diff --git a/root/package/firmware/nss/nss-ifb/Makefile b/root/package/firmware/nss/nss-ifb/Makefile new file mode 100644 index 00000000..6b7f0b48 --- /dev/null +++ b/root/package/firmware/nss/nss-ifb/Makefile @@ -0,0 +1,49 @@ +# +# Copyright (C) 2008-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=nss-ifb +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/nss-ifb + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=NSS IFB Interface + DEPENDS:=+kmod-qca-nss-drv @LINUX_5_4 + FILES:=$(PKG_BUILD_DIR)/nss-ifb.ko + KCONFIG:= +endef + +define KernelPackage/nss-ifb/description + Kernel module to register a NSS aware IFB interface. +endef + +EXTRA_KCONFIG:= \ + CONFIG_NET_CLS=y + +EXTRA_CFLAGS:= \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv + +MAKE_OPTS:= \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + $(EXTRA_KCONFIG) + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" \ + $(MAKE_OPTS) \ + modules +endef + +$(eval $(call KernelPackage,nss-ifb)) + diff --git a/root/package/firmware/nss/nss-ifb/README.md b/root/package/firmware/nss/nss-ifb/README.md new file mode 100644 index 00000000..a0af7a5e --- /dev/null +++ b/root/package/firmware/nss/nss-ifb/README.md @@ -0,0 +1,45 @@ +NSS Physical Interface Ingress Driver +===================================== + +This driver redirect NSS physical interface (namely GMACs) ingress traffic to itself +and sends it back to the Linux network stack (as the source GMACs packets) as it's +egress traffic. + +This allows the NSS QDISC drivers to manage the egress traffic of this driver's +NSS virtual interface. + +This driver will create a single network interface named 'nssifb'. The default +source interface is defined as 'eth0'. It can be changed using the following module +parameter path: + +/sys/module/nss-ifb/parameter/nss_src_dev + +To change the source NSS physical interface to 'eth1', use the following command: + +printf eth1 > /sys/module/nss-ifb/parameter/nss_src_dev + +You need to change the source interface first before bringing up the 'nssifb' +interface. Changing it after the interface is up will have no effect. You need +to bring down the interface and bring it back up to have the changes take effect. + +CPU load imposed on the Krait CPUs appears negligible with this driver intercepting +the physical interface's ingress traffic. Full line speed of the GMAC interface +could still be achieved. + +The commands below shows an example to shape ingress traffic to 500 Mbps and egress +to 200 Mbps for the 'eth0' interface. + +# Load the module if it's not loaded +modprobe nss-ifb + +# Bring up the nssifb interface to active ingress redirect +ip link set up nssifb + +# Shape ingress traffic to 500 Mbit with chained NSSFQ_CODEL +tc qdisc add dev nssifb root handle 1: nsstbl rate 500Mbit burst 1Mb +tc qdisc add dev nssifb parent 1: handle 10: nssfq_codel limit 10240 flows 1024 quantum 1514 target 5ms interval 100ms set_default + +# Shape egress traffic to 200 Mbit with chained NSSFQ_CODEL +tc qdisc add dev eth0 root handle 1: nsstbl rate 200Mbit burst 1Mb +tc qdisc add dev eth0 parent 1: handle 10: nssfq_codel limit 10240 flows 1024 quantum 1514 target 5ms interval 100ms set_default + diff --git a/root/package/firmware/nss/nss-ifb/src/Makefile b/root/package/firmware/nss/nss-ifb/src/Makefile new file mode 100644 index 00000000..332b9b4e --- /dev/null +++ b/root/package/firmware/nss/nss-ifb/src/Makefile @@ -0,0 +1,3 @@ +obj-m += nss-ifb.o + +nss-ifb-objs := nss_ifb.o diff --git a/root/package/firmware/nss/nss-ifb/src/nss_ifb.c b/root/package/firmware/nss/nss-ifb/src/nss_ifb.c new file mode 100644 index 00000000..18c017fe --- /dev/null +++ b/root/package/firmware/nss/nss-ifb/src/nss_ifb.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* + * This driver is adapted from the Linux /drivers/net/ifb.c file. + * + * Redirect QCA NSS physical interface ingress traffic to this driver's + * virtual interface. This will allow ingress traffic shaping using the + * QCA NSS shaper. + */ + +#include + +#define TX_Q_LIMIT 32 + +struct nss_ifb_dev_private { + struct nss_virt_if_handle *nssctx; + struct net_device *nss_src_dev; + uint32_t nss_src_if_num; + char nss_src_dev_name[32]; +}; + +char nss_dev_name_array[32] = "eth0"; +char *nss_dev_name = nss_dev_name_array; +module_param(nss_dev_name, charp, 0644); +MODULE_PARM_DESC(nss_dev_name, "NSS physical interface source device name"); + +/* + * Virtual interface egress packet callback. + * + * We send it back to the Linux network stack. + */ +static void nss_ifb_data_cb(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi) +{ + struct nss_ifb_dev_private *dp = netdev_priv(netdev); + + skb->protocol = eth_type_trans(skb, dp->nss_src_dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; + + napi_gro_receive(napi, skb); +} + +/* + * Virtual interface ingress packet callback. + * + * We just send it back to the NSS firmware to let the shaper work on it. + */ +static void nss_ifb_xmit_cb(struct net_device *netdev, struct sk_buff *skb) +{ + struct nss_ifb_dev_private *dp = netdev_priv(netdev); + int ret; + + ret = nss_virt_if_tx_buf(dp->nssctx, skb); + if (unlikely(ret)) { + pr_warn("Failed [%d] to send skb [len: %d, protocol: 0x%X] to NSS!\n", + ret, skb->len, ntohs(skb->protocol)); + } +} + +static void nss_ifb_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + +} + +static int nss_ifb_dev_init(struct net_device *dev) +{ + struct nss_ifb_dev_private *dp = netdev_priv(dev); + + dp->nssctx = nss_virt_if_create_sync_nexthop(dev, NSS_ETH_RX_INTERFACE, NSS_ETH_RX_INTERFACE); + if (!dp->nssctx) { + dp->nssctx = NULL; + pr_warn("Could not create a NSS virtual interface for dev [%s]\n", + dev->name); + + return -ENODEV; + } + pr_info("Created a NSS virtual interface for dev [%s]\n", dev->name); + + nss_virt_if_register(dp->nssctx, nss_ifb_data_cb, dev); + pr_info("NSS IFB data callback registered\n"); + + nss_virt_if_xmit_callback_register(dp->nssctx, nss_ifb_xmit_cb); + pr_info("NSS IFB transmit callback registered\n"); + + return 0; +} + +static void nss_ifb_dev_uninit(struct net_device *dev) +{ + struct nss_ifb_dev_private *dp = netdev_priv(dev); + int ret; + + nss_virt_if_xmit_callback_unregister(dp->nssctx); + pr_info("NSS IFB transmit callback unregistered\n"); + + ret = nss_virt_if_destroy_sync(dp->nssctx); + if (ret == NSS_TX_SUCCESS) { + pr_info("NSS virtual interface destroyed for dev [%s]\n", dev->name); + } + else { + pr_warn("Unable to destroy NSS virtual interface for dev [%s], error[%d]\n", + dev->name, ret); + } + dp->nssctx = NULL; +} + +static netdev_tx_t nss_ifb_xmit(struct sk_buff *skb, struct net_device *dev) +{ + return NETDEV_TX_OK; +} + +static int nss_ifb_close(struct net_device *dev) +{ + struct nss_ifb_dev_private *dp = netdev_priv(dev); + struct nss_ctx_instance *nss_ctx; + struct net_device *src_dev; + uint32_t src_if_num; + int ret; + + nss_ctx = dp->nssctx->nss_ctx; + src_dev = dp->nss_src_dev; + src_if_num = dp->nss_src_if_num; + + ret = nss_phys_if_set_nexthop(nss_ctx, src_if_num, NSS_ETH_RX_INTERFACE); + if (ret != NSS_TX_SUCCESS) { + pr_warn("%p: Failed to reset next hop for net device [%s].\n", + nss_ctx, src_dev->name); + } + else { + pr_info("%p: Reset nexthop successful for net device [%s].\n", + nss_ctx, src_dev->name); + } + + dev_put(src_dev); + dp->nss_src_dev = NULL; + dp->nss_src_if_num = -1; + + return 0; +} + +static int nss_ifb_open(struct net_device *dev) +{ + struct nss_ifb_dev_private *dp = netdev_priv(dev); + struct net_device *src_dev; + uint32_t src_if_num; + uint32_t nh_if_num; + nss_tx_status_t nss_tx_status; + struct nss_ctx_instance *nss_ctx; + + nss_ctx = dp->nssctx->nss_ctx; + nh_if_num = dp->nssctx->if_num_n2h; + + strcpy(dp->nss_src_dev_name, nss_dev_name); + + src_dev = dev_get_by_name(&init_net, dp->nss_src_dev_name); + if (!src_dev) { + pr_warn("%p: Cannot find the net device [%s]\n", + nss_ctx, dp->nss_src_dev_name); + + return -ENODEV; + } + pr_info("%p: Found net device [%s]\n", nss_ctx, dp->nss_src_dev_name); + + src_if_num = nss_cmn_get_interface_number_by_dev(src_dev); + if (src_if_num < 0) { + pr_warn("%p: Invalid interface number:%d\n", nss_ctx, src_if_num); + dev_put(src_dev); + + return -ENODEV; + } + pr_info("%p: Net device [%s] has NSS intf_num [%d]\n", + nss_ctx, dp->nss_src_dev_name, src_if_num); + + nss_tx_status = nss_phys_if_set_nexthop(nss_ctx, src_if_num, nh_if_num); + if (nss_tx_status != NSS_TX_SUCCESS) { + pr_warn("%p: Sending message failed, cannot change nexthop for [%s]\n", + nss_ctx, dp->nss_src_dev_name); + } + else { + pr_info("Nexthop successfully set for [%s] to [%s]\n", + dp->nss_src_dev_name, dev->name); + } + + dp->nss_src_dev = src_dev; + dp->nss_src_if_num = src_if_num; + + return 0; +} + +static const struct net_device_ops nss_ifb_netdev_ops = { + .ndo_open = nss_ifb_open, + .ndo_stop = nss_ifb_close, + .ndo_get_stats64 = nss_ifb_stats64, + .ndo_start_xmit = nss_ifb_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_init = nss_ifb_dev_init, + .ndo_uninit = nss_ifb_dev_uninit, +}; + +#define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \ + NETIF_F_TSO_ECN | NETIF_F_TSO | NETIF_F_TSO6 | \ + NETIF_F_GSO_ENCAP_ALL | \ + NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | \ + NETIF_F_HW_VLAN_STAG_TX) + +static void nss_ifb_dev_free(struct net_device *dev) +{ + +} + +static void nss_ifb_setup(struct net_device *dev) +{ + /* Initialize the device structure. */ + dev->netdev_ops = &nss_ifb_netdev_ops; + + /* Fill in device structure with ethernet-generic values. */ + ether_setup(dev); + dev->tx_queue_len = TX_Q_LIMIT; + + dev->features |= IFB_FEATURES; + dev->hw_features |= dev->features; + dev->hw_enc_features |= dev->features; + dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX); + + dev->flags |= IFF_NOARP; + dev->flags &= ~IFF_MULTICAST; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + netif_keep_dst(dev); + eth_hw_addr_random(dev); + dev->needs_free_netdev = true; + dev->priv_destructor = nss_ifb_dev_free; + + dev->min_mtu = 0; + dev->max_mtu = 0; +} + +static int nss_ifb_validate(struct nlattr *tb[], struct nlattr *data[], + struct netlink_ext_ack *extack) +{ + if (tb[IFLA_ADDRESS]) { + if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) + return -EINVAL; + if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) + return -EADDRNOTAVAIL; + } + return 0; +} + +static struct rtnl_link_ops nss_ifb_link_ops __read_mostly = { + .kind = "nss_ifb", + .priv_size = sizeof(struct nss_ifb_dev_private), + .setup = nss_ifb_setup, + .validate = nss_ifb_validate, +}; + +static int __init nss_ifb_init_module(void) +{ + struct net_device *dev; + int err; + + down_write(&pernet_ops_rwsem); + rtnl_lock(); + err = __rtnl_link_register(&nss_ifb_link_ops); + if (err < 0) + goto out; + + dev = alloc_netdev(sizeof(struct nss_ifb_dev_private), "nssifb", + NET_NAME_UNKNOWN, nss_ifb_setup); + + if (dev) { + dev->rtnl_link_ops = &nss_ifb_link_ops; + err = register_netdevice(dev); + } + else { + err = -ENOMEM; + } + + if (err) + __rtnl_link_unregister(&nss_ifb_link_ops); + +out: + rtnl_unlock(); + up_write(&pernet_ops_rwsem); + + if (!err) + pr_info("NSS IFB module loaded.\n"); + else + pr_warn("Failed to load NSS IFB module.\n"); + + return err; +} + +static void __exit nss_ifb_cleanup_module(void) +{ + rtnl_link_unregister(&nss_ifb_link_ops); + + pr_info("NSS IFB module unloaded.\n"); +} + +module_init(nss_ifb_init_module); +module_exit(nss_ifb_cleanup_module); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_RTNL_LINK("nss_ifb"); diff --git a/root/package/firmware/nss/qca-nss-cfi/Makefile b/root/package/firmware/nss/qca-nss-cfi/Makefile new file mode 100644 index 00000000..570b45cf --- /dev/null +++ b/root/package/firmware/nss/qca-nss-cfi/Makefile @@ -0,0 +1,99 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-nss-cfi +PKG_RELEASE:=2 + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-cfi +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=8035a8ddefdcc8a2f06c96b2a82618ca6ce6406d +PKG_MIRROR_HASH:=23316395d1346994d069eb41ef73a5505853687f8beab14f83545b3a05e52429 + +include $(INCLUDE_DIR)/package.mk + +ifeq ($(CONFIG_TARGET_ipq),y) +subtarget:=$(SUBTARGET) +else +subtarget:=$(CONFIG_TARGET_BOARD) +endif + +# v1.0 is for Akronite +# v2.0 is for Hawkeye/Cypress/Maple +ifneq (, $(findstring $(subtarget), "ipq807x" "ipq807x_64" "ipq60xx" "ipq60xx_64")) + CFI_OCF_DIR:=ocf/v2.0 + CFI_CRYPTOAPI_DIR:=cryptoapi/v2.0 +else + CFI_CRYPTOAPI_DIR:=cryptoapi/v1.1 + CFI_OCF_DIR:=ocf/v1.0 + CFI_IPSEC_DIR:=ipsec/v1.0 +endif + +define KernelPackage/qca-nss-cfi-cryptoapi + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq806x||TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64 \ + +kmod-qca-nss-crypto +kmod-crypto-authenc @LINUX_5_4 + TITLE:=Kernel driver for NSS cfi + FILES:=$(PKG_BUILD_DIR)/$(CFI_CRYPTOAPI_DIR)/qca-nss-cfi-cryptoapi.ko + AUTOLOAD:=$(call AutoLoad,59,qca-nss-cfi-cryptoapi) +endef + +# OCF should be dropped +# define KernelPackage/qca-nss-cfi-ocf +# SECTION:=kernel +# CATEGORY:=Kernel modules +# SUBMENU:=Network Devices +# DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq806x||TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64 \ +# +kmod-qca-nss-crypto +PACKAGE_kmod-crypto-ocf:kmod-crypto-ocf @!LINUX_3_18 +# TITLE:=Kernel driver for NSS cfi +# FILES:=$(PKG_BUILD_DIR)/$(CFI_OCF_DIR)/qca-nss-cfi-ocf.ko + +# ifdef CFI_IPSEC_DIR +# FILES+=$(PKG_BUILD_DIR)/$(CFI_IPSEC_DIR)/qca-nss-ipsec.ko +# AUTOLOAD:=$(call AutoLoad,61,qca-nss-cfi-ocf qca-nss-ipsec) +# else +# AUTOLOAD:=$(call AutoLoad,61,qca-nss-cfi-ocf) +# endif +# endef + +define Build/InstallDev/qca-nss-cfi + $(INSTALL_DIR) $(1)/usr/include/qca-nss-cfi + $(CP) $(PKG_BUILD_DIR)/$(CFI_CRYPTOAPI_DIR)/../exports/* $(1)/usr/include/qca-nss-cfi + $(CP) $(PKG_BUILD_DIR)/include/* $(1)/usr/include/qca-nss-cfi +endef + +define Build/InstallDev + $(call Build/InstallDev/qca-nss-cfi,$(1)) +endef + +define KernelPackage/qca-nss-cfi/Description +This package contains a NSS cfi driver for QCA chipset +endef + +EXTRA_CFLAGS+= \ + -DCONFIG_NSS_DEBUG_LEVEL=4 \ + -I$(LINUX_DIR)/crypto/ocf \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv + +ifneq (, $(findstring $(subtarget), "ipq807x" "ipq807x_64" "ipq60xx" "ipq60xx_64")) +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-clients +endif + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + CFI_CRYPTOAPI_DIR=$(CFI_CRYPTOAPI_DIR) \ + CFI_OCF_DIR=$(CFI_OCF_DIR) \ + CFI_IPSEC_DIR=$(CFI_IPSEC_DIR) \ + SoC=$(subtarget) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-cfi-cryptoapi)) +#$(eval $(call KernelPackage,qca-nss-cfi-ocf)) diff --git a/root/package/firmware/nss/qca-nss-cfi/patches/0001-compile-only-cryptoapi.patch b/root/package/firmware/nss/qca-nss-cfi/patches/0001-compile-only-cryptoapi.patch new file mode 100644 index 00000000..00968f5f --- /dev/null +++ b/root/package/firmware/nss/qca-nss-cfi/patches/0001-compile-only-cryptoapi.patch @@ -0,0 +1,30 @@ +From a8a573c5ce83bdddca9a60c62161638a5fd906d4 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 13 Jun 2020 12:57:14 +0200 +Subject: [PATCH 1/3] compile only cryptoapi + +--- + Makefile | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile b/Makefile +index c42adca..36a9d3f 100644 +--- a/Makefile ++++ b/Makefile +@@ -4,9 +4,9 @@ + + export BUILD_ID = \"Build Id: $(shell date +'%m/%d/%y, %H:%M:%S')\" + +-obj-m += $(CFI_OCF_DIR)/ ++# obj-m += $(CFI_OCF_DIR)/ + obj-m += $(CFI_CRYPTOAPI_DIR)/ + +-ifeq ($(SoC),$(filter $(SoC),ipq806x)) +-obj-m += $(CFI_IPSEC_DIR)/ +-endif ++# ifeq ($(SoC),$(filter $(SoC),ipq806x)) ++# obj-m += $(CFI_IPSEC_DIR)/ ++# endif +-- +2.27.0.rc0 + diff --git a/root/package/firmware/nss/qca-nss-cfi/patches/0002-wip-support-5.4.patch b/root/package/firmware/nss/qca-nss-cfi/patches/0002-wip-support-5.4.patch new file mode 100644 index 00000000..d68fc939 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-cfi/patches/0002-wip-support-5.4.patch @@ -0,0 +1,78 @@ +From 202f57bae49947a04301ac8ac9bdc00f28f09355 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 13 Jun 2020 12:58:26 +0200 +Subject: [PATCH 2/3] wip: support 5.4 + +--- + cryptoapi/v1.1/nss_cryptoapi.c | 1 - + cryptoapi/v1.1/nss_cryptoapi_ablk.c | 12 ++++++------ + cryptoapi/v1.1/nss_cryptoapi_aead.c | 2 +- + 3 files changed, 7 insertions(+), 8 deletions(-) + +diff --git a/cryptoapi/v1.1/nss_cryptoapi.c b/cryptoapi/v1.1/nss_cryptoapi.c +index d1a7313..a10590e 100644 +--- a/cryptoapi/v1.1/nss_cryptoapi.c ++++ b/cryptoapi/v1.1/nss_cryptoapi.c +@@ -231,7 +231,6 @@ static struct crypto_alg cryptoapi_ablkcipher_algs[] = { + .cra_u = { + .ablkcipher = { + .ivsize = CTR_RFC3686_IV_SIZE, +- .geniv = "seqiv", + .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, + .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, + .setkey = nss_cryptoapi_ablk_aes_setkey, +diff --git a/cryptoapi/v1.1/nss_cryptoapi_ablk.c b/cryptoapi/v1.1/nss_cryptoapi_ablk.c +index 223591c..9b6c65e 100644 +--- a/cryptoapi/v1.1/nss_cryptoapi_ablk.c ++++ b/cryptoapi/v1.1/nss_cryptoapi_ablk.c +@@ -108,7 +108,7 @@ EXPORT_SYMBOL(nss_cryptoapi_skcipher_ctx2session); + int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm) + { + struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); +- struct crypto_ablkcipher *sw_tfm; ++ struct crypto_cipher *sw_tfm; + + nss_cfi_assert(ctx); + +@@ -122,20 +122,20 @@ int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm) + + nss_cryptoapi_set_magic(ctx); + +- if (!(crypto_tfm_alg_flags(tfm) & CRYPTO_ALG_NEED_FALLBACK)) ++ if (!(crypto_tfm_alg_type(tfm) & CRYPTO_ALG_NEED_FALLBACK)) + return 0; + + /* Alloc fallback transform for future use */ +- sw_tfm = crypto_alloc_ablkcipher(crypto_tfm_alg_name(tfm), 0, CRYPTO_ALG_ASYNC | +- CRYPTO_ALG_NEED_FALLBACK); ++ sw_tfm = crypto_alloc_cipher(crypto_tfm_alg_name(tfm), 0, CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(sw_tfm)) { + nss_cfi_err("unable to alloc software crypto for %s\n", crypto_tfm_alg_name(tfm)); + return -EINVAL; + } + + /* set this tfm reqsize same to fallback tfm */ +- tfm->crt_ablkcipher.reqsize = crypto_ablkcipher_reqsize(sw_tfm); +- ctx->sw_tfm = crypto_ablkcipher_tfm(sw_tfm); ++ tfm->crt_ablkcipher.reqsize = sizeof(struct nss_cryptoapi_ctx); ++ ctx->sw_tfm = crypto_cipher_tfm(sw_tfm); + + return 0; + } +diff --git a/cryptoapi/v1.1/nss_cryptoapi_aead.c b/cryptoapi/v1.1/nss_cryptoapi_aead.c +index 527936b..53e4bed 100644 +--- a/cryptoapi/v1.1/nss_cryptoapi_aead.c ++++ b/cryptoapi/v1.1/nss_cryptoapi_aead.c +@@ -103,7 +103,7 @@ int nss_cryptoapi_aead_init(struct crypto_aead *aead) + + nss_cryptoapi_set_magic(ctx); + +- if (!(crypto_tfm_alg_flags(tfm) & CRYPTO_ALG_NEED_FALLBACK)) ++ if (!(crypto_tfm_alg_type(tfm) & CRYPTO_ALG_NEED_FALLBACK)) + return 0; + + /* Alloc fallback transform for future use */ +-- +2.27.0.rc0 + diff --git a/root/package/firmware/nss/qca-nss-cfi/patches/0003-Convert-ablkcipher-to-skcipher.patch b/root/package/firmware/nss/qca-nss-cfi/patches/0003-Convert-ablkcipher-to-skcipher.patch new file mode 100644 index 00000000..b4520a3d --- /dev/null +++ b/root/package/firmware/nss/qca-nss-cfi/patches/0003-Convert-ablkcipher-to-skcipher.patch @@ -0,0 +1,707 @@ +From e3a53a6d11b2c1770545a2820a58c117799bcb70 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Tue, 16 Jun 2020 18:12:34 +0200 +Subject: [PATCH 3/3] Convert ablkcipher to skcipher + +--- + cryptoapi/v1.1/nss_cryptoapi.c | 149 +++++++++++-------------- + cryptoapi/v1.1/nss_cryptoapi_ablk.c | 136 +++++++++++----------- + cryptoapi/v1.1/nss_cryptoapi_debugfs.c | 1 + + cryptoapi/v1.1/nss_cryptoapi_private.h | 16 +-- + 4 files changed, 145 insertions(+), 157 deletions(-) + +diff --git a/cryptoapi/v1.1/nss_cryptoapi.c b/cryptoapi/v1.1/nss_cryptoapi.c +index a10590e..3a835dc 100644 +--- a/cryptoapi/v1.1/nss_cryptoapi.c ++++ b/cryptoapi/v1.1/nss_cryptoapi.c +@@ -66,7 +66,7 @@ struct aead_alg cryptoapi_aead_algs[] = { + .cra_name = "echainiv(authenc(hmac(sha1),cbc(aes)))", + .cra_driver_name = "nss-hmac-sha1-cbc-aes", + .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_NEED_FALLBACK, ++ .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_KERN_DRIVER_ONLY, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, +@@ -87,7 +87,7 @@ struct aead_alg cryptoapi_aead_algs[] = { + .cra_name = "seqiv(authenc(hmac(sha1),rfc3686(ctr(aes))))", + .cra_driver_name = "nss-hmac-sha1-rfc3686-ctr-aes", + .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_NEED_FALLBACK, ++ .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_KERN_DRIVER_ONLY, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, +@@ -108,7 +108,7 @@ struct aead_alg cryptoapi_aead_algs[] = { + .cra_name = "echainiv(authenc(hmac(sha1),cbc(des3_ede)))", + .cra_driver_name = "nss-hmac-sha1-cbc-3des", + .cra_priority = 300, +- .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG, ++ .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_KERN_DRIVER_ONLY, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, +@@ -129,7 +129,7 @@ struct aead_alg cryptoapi_aead_algs[] = { + .cra_name = "echainiv(authenc(hmac(sha256),cbc(aes)))", + .cra_driver_name = "nss-hmac-sha256-cbc-aes", + .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_NEED_FALLBACK, ++ .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_KERN_DRIVER_ONLY, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, +@@ -150,7 +150,7 @@ struct aead_alg cryptoapi_aead_algs[] = { + .cra_name = "seqiv(authenc(hmac(sha256),rfc3686(ctr(aes))))", + .cra_driver_name = "nss-hmac-sha256-rfc3686-ctr-aes", + .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_NEED_FALLBACK, ++ .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_KERN_DRIVER_ONLY, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, +@@ -171,7 +171,7 @@ struct aead_alg cryptoapi_aead_algs[] = { + .cra_name = "echainiv(authenc(hmac(sha256),cbc(des3_ede)))", + .cra_driver_name = "nss-hmac-sha256-cbc-3des", + .cra_priority = 300, +- .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG, ++ .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_KERN_DRIVER_ONLY, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), + .cra_alignmask = 0, +@@ -192,75 +192,66 @@ struct aead_alg cryptoapi_aead_algs[] = { + /* + * ABLK cipher algorithms + */ +-static struct crypto_alg cryptoapi_ablkcipher_algs[] = { ++static struct skcipher_alg cryptoapi_skcipher_algs[] = { + { +- .cra_name = "cbc(aes)", +- .cra_driver_name = "nss-cbc-aes", +- .cra_priority = 10000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = AES_BLOCK_SIZE, +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = nss_cryptoapi_ablk_aes_setkey, +- .encrypt = nss_cryptoapi_ablk_aes_encrypt, +- .decrypt = nss_cryptoapi_ablk_aes_decrypt, +- }, ++ .base = { ++ .cra_name = "cbc(aes)", ++ .cra_driver_name = "nss-cbc-aes", ++ .cra_priority = 10000, ++ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .cra_alignmask = 0, ++ .cra_module = THIS_MODULE, + }, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = AES_BLOCK_SIZE, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .setkey = nss_cryptoapi_ablk_aes_setkey, ++ .encrypt = nss_cryptoapi_ablk_aes_encrypt, ++ .decrypt = nss_cryptoapi_ablk_aes_decrypt, + }, + { +- .cra_name = "rfc3686(ctr(aes))", +- .cra_driver_name = "nss-rfc3686-ctr-aes", +- .cra_priority = 30000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = CTR_RFC3686_IV_SIZE, +- .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, +- .setkey = nss_cryptoapi_ablk_aes_setkey, +- .encrypt = nss_cryptoapi_ablk_aes_encrypt, +- .decrypt = nss_cryptoapi_ablk_aes_decrypt, +- }, ++ .base = { ++ .cra_name = "rfc3686(ctr(aes))", ++ .cra_driver_name = "nss-rfc3686-ctr-aes", ++ .cra_priority = 30000, ++ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .cra_alignmask = 0, ++ .cra_module = THIS_MODULE, + }, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .setkey = nss_cryptoapi_ablk_aes_setkey, ++ .encrypt = nss_cryptoapi_ablk_aes_encrypt, ++ .decrypt = nss_cryptoapi_ablk_aes_decrypt, + }, + { +- .cra_name = "cbc(des3_ede)", +- .cra_driver_name = "nss-cbc-3des", +- .cra_priority = 1000, +- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_ASYNC, +- .cra_blocksize = DES3_EDE_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), +- .cra_alignmask = 0, +- .cra_type = &crypto_ablkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_init = nss_cryptoapi_ablkcipher_init, +- .cra_exit = nss_cryptoapi_ablkcipher_exit, +- .cra_u = { +- .ablkcipher = { +- .ivsize = DES3_EDE_BLOCK_SIZE, +- .min_keysize = DES3_EDE_KEY_SIZE, +- .max_keysize = DES3_EDE_KEY_SIZE, +- .setkey = nss_cryptoapi_3des_cbc_setkey, +- .encrypt = nss_cryptoapi_3des_cbc_encrypt, +- .decrypt = nss_cryptoapi_3des_cbc_decrypt, +- }, ++ .base = { ++ .cra_name = "cbc(des3_ede)", ++ .cra_driver_name = "nss-cbc-3des", ++ .cra_priority = 1000, ++ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_NOSUPP_SG | CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct nss_cryptoapi_ctx), ++ .cra_alignmask = 0, ++ .cra_module = THIS_MODULE, + }, ++ .init = nss_cryptoapi_skcipher_init, ++ .exit = nss_cryptoapi_skcipher_exit, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .min_keysize = DES3_EDE_KEY_SIZE, ++ .max_keysize = DES3_EDE_KEY_SIZE, ++ .setkey = nss_cryptoapi_3des_cbc_setkey, ++ .encrypt = nss_cryptoapi_3des_cbc_encrypt, ++ .decrypt = nss_cryptoapi_3des_cbc_decrypt, + }, + }; + +@@ -277,14 +268,14 @@ static nss_crypto_user_ctx_t nss_cryptoapi_register(nss_crypto_handle_t crypto) + + sc->crypto = crypto; + +- for (i = 0; i < ARRAY_SIZE(cryptoapi_ablkcipher_algs); i++) { +- rc = crypto_register_alg(&cryptoapi_ablkcipher_algs[i]); ++ for (i = 0; i < ARRAY_SIZE(cryptoapi_skcipher_algs); i++) { ++ rc = crypto_register_skcipher(&cryptoapi_skcipher_algs[i]); + if (rc) { +- nss_cfi_trace("Ablk registration failed, algo: %s\n", cryptoapi_ablkcipher_algs[i].cra_name); +- cryptoapi_ablkcipher_algs[i].cra_flags = 0; ++ nss_cfi_trace("Ablk registration failed, algo: %s\n", cryptoapi_skcipher_algs[i].base.cra_name); ++ cryptoapi_skcipher_algs[i].base.cra_flags = 0; + continue; + } +- nss_cfi_info("Ablk registration succeeded, algo: %s\n", cryptoapi_ablkcipher_algs[i].cra_name); ++ nss_cfi_info("Ablk registration succeeded, algo: %s\n", cryptoapi_skcipher_algs[i].base.cra_name); + } + + for (i = 0; i < ARRAY_SIZE(cryptoapi_aead_algs); i++) { +@@ -317,7 +308,7 @@ static nss_crypto_user_ctx_t nss_cryptoapi_register(nss_crypto_handle_t crypto) + static void nss_cryptoapi_unregister(nss_crypto_user_ctx_t cfi) + { + struct nss_cryptoapi *sc = &gbl_ctx; +- int i, ret = 0; ++ int i; + + nss_cfi_info("unregister nss_cryptoapi\n"); + +@@ -326,16 +317,12 @@ static void nss_cryptoapi_unregister(nss_crypto_user_ctx_t cfi) + */ + atomic_set(&gbl_ctx.registered, 0); + +- for (i = 0; i < ARRAY_SIZE(cryptoapi_ablkcipher_algs); i++) { +- if (!cryptoapi_ablkcipher_algs[i].cra_flags) { +- continue; +- } +- ret = crypto_unregister_alg(&cryptoapi_ablkcipher_algs[i]); +- if (ret) { +- nss_cfi_err("Ablk unregister failed, algo: %s\n", cryptoapi_ablkcipher_algs[i].cra_name); ++ for (i = 0; i < ARRAY_SIZE(cryptoapi_skcipher_algs); i++) { ++ if (!cryptoapi_skcipher_algs[i].base.cra_flags) { + continue; + } +- nss_cfi_info("Ablk unregister succeeded, algo: %s\n", cryptoapi_ablkcipher_algs[i].cra_name); ++ crypto_unregister_skcipher(&cryptoapi_skcipher_algs[i]); ++ nss_cfi_info("Ablk unregister succeeded, algo: %s\n", cryptoapi_skcipher_algs[i].base.cra_name); + } + + for (i = 0; i < ARRAY_SIZE(cryptoapi_aead_algs); i++) { +diff --git a/cryptoapi/v1.1/nss_cryptoapi_ablk.c b/cryptoapi/v1.1/nss_cryptoapi_ablk.c +index 9b6c65e..913e9cc 100644 +--- a/cryptoapi/v1.1/nss_cryptoapi_ablk.c ++++ b/cryptoapi/v1.1/nss_cryptoapi_ablk.c +@@ -102,12 +102,12 @@ int nss_cryptoapi_skcipher_ctx2session(struct crypto_skcipher *sk, uint32_t *sid + EXPORT_SYMBOL(nss_cryptoapi_skcipher_ctx2session); + + /* +- * nss_cryptoapi_ablkcipher_init() +- * Cryptoapi ablkcipher init function. ++ * nss_cryptoapi_skcipher_init() ++ * Cryptoapi skcipher init function. + */ +-int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm) ++int nss_cryptoapi_skcipher_init(struct crypto_skcipher *tfm) + { +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm); + struct crypto_cipher *sw_tfm; + + nss_cfi_assert(ctx); +@@ -122,31 +122,31 @@ int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm) + + nss_cryptoapi_set_magic(ctx); + +- if (!(crypto_tfm_alg_type(tfm) & CRYPTO_ALG_NEED_FALLBACK)) ++ if (!(crypto_tfm_alg_type(&tfm->base) & CRYPTO_ALG_NEED_FALLBACK)) + return 0; + + /* Alloc fallback transform for future use */ +- sw_tfm = crypto_alloc_cipher(crypto_tfm_alg_name(tfm), 0, CRYPTO_ALG_ASYNC | ++ sw_tfm = crypto_alloc_cipher(crypto_tfm_alg_name(&tfm->base), 0, CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(sw_tfm)) { +- nss_cfi_err("unable to alloc software crypto for %s\n", crypto_tfm_alg_name(tfm)); ++ nss_cfi_err("unable to alloc software crypto for %s\n", crypto_tfm_alg_name(&tfm->base)); + return -EINVAL; + } + + /* set this tfm reqsize same to fallback tfm */ +- tfm->crt_ablkcipher.reqsize = sizeof(struct nss_cryptoapi_ctx); ++ crypto_skcipher_set_reqsize(tfm, sizeof(struct nss_cryptoapi_ctx)); + ctx->sw_tfm = crypto_cipher_tfm(sw_tfm); + + return 0; + } + + /* +- * nss_cryptoapi_ablkcipher_exit() +- * Cryptoapi ablkcipher exit function. ++ * nss_cryptoapi_skcipher_exit() ++ * Cryptoapi skcipher exit function. + */ +-void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm) ++void nss_cryptoapi_skcipher_exit(struct crypto_skcipher *tfm) + { +- struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(tfm); + struct nss_cryptoapi *sc = &gbl_ctx; + nss_crypto_status_t status; + +@@ -158,7 +158,7 @@ void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm) + } + + if (ctx->sw_tfm) { +- crypto_free_ablkcipher(__crypto_ablkcipher_cast(ctx->sw_tfm)); ++ crypto_free_skcipher(__crypto_skcipher_cast(ctx->sw_tfm)); + ctx->sw_tfm = NULL; + } + +@@ -183,9 +183,9 @@ void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm) + * nss_cryptoapi_ablk_aes_setkey() + * Cryptoapi setkey routine for aes. + */ +-int nss_cryptoapi_ablk_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int keylen) ++int nss_cryptoapi_ablk_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int keylen) + { +- struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); + struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); + struct nss_cryptoapi *sc = &gbl_ctx; + struct nss_crypto_key cip; +@@ -255,10 +255,10 @@ int nss_cryptoapi_ablk_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *ke + + /* set flag to fallback tfm */ + crypto_tfm_clear_flags(ctx->sw_tfm, CRYPTO_TFM_REQ_MASK); +- crypto_tfm_set_flags(ctx->sw_tfm, crypto_ablkcipher_get_flags(cipher) & CRYPTO_TFM_REQ_MASK); ++ crypto_tfm_set_flags(ctx->sw_tfm, crypto_skcipher_get_flags(cipher) & CRYPTO_TFM_REQ_MASK); + + /* Set key to the fallback tfm */ +- ret = crypto_ablkcipher_setkey(__crypto_ablkcipher_cast(ctx->sw_tfm), key, keylen); ++ ret = crypto_skcipher_setkey(__crypto_skcipher_cast(ctx->sw_tfm), key, keylen); + if (ret) { + nss_cfi_err("Failed to set key to the sw crypto"); + +@@ -266,7 +266,7 @@ int nss_cryptoapi_ablk_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *ke + * Set back the fallback tfm flag to the original flag one after + * doing setkey + */ +- crypto_ablkcipher_set_flags(cipher, crypto_tfm_get_flags(ctx->sw_tfm)); ++ crypto_skcipher_set_flags(cipher, crypto_tfm_get_flags(ctx->sw_tfm)); + } + return ret; + default: +@@ -289,23 +289,23 @@ int nss_cryptoapi_ablk_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *ke + return 0; + + fail: +- crypto_ablkcipher_set_flags(cipher, flag); ++ crypto_skcipher_set_flags(cipher, flag); + return -EINVAL; + } + + /* +- * nss_cryptoapi_ablkcipher_done() ++ * nss_cryptoapi_skcipher_done() + * Cipher operation completion callback function + */ +-void nss_cryptoapi_ablkcipher_done(struct nss_crypto_buf *buf) ++void nss_cryptoapi_skcipher_done(struct nss_crypto_buf *buf) + { + struct nss_cryptoapi_ctx *ctx; +- struct ablkcipher_request *req; ++ struct skcipher_request *req; + int err = 0; + + nss_cfi_assert(buf); + +- req = (struct ablkcipher_request *)nss_crypto_get_cb_ctx(buf); ++ req = (struct skcipher_request *)nss_crypto_get_cb_ctx(buf); + + /* + * check cryptoapi context magic number. +@@ -319,7 +319,7 @@ void nss_cryptoapi_ablkcipher_done(struct nss_crypto_buf *buf) + nss_crypto_buf_free(gbl_ctx.crypto, buf); + + nss_cfi_dbg("after transformation\n"); +- nss_cfi_dbg_data(sg_virt(req->dst), req->nbytes, ' '); ++ nss_cfi_dbg_data(sg_virt(req->dst), req->cryptlen, ' '); + + /* + * Passing always pass in case of encrypt. +@@ -337,7 +337,7 @@ void nss_cryptoapi_ablkcipher_done(struct nss_crypto_buf *buf) + * Cryptoapi: obtain sg to virtual address mapping. + * Check for multiple sg in src and dst + */ +-int nss_cryptoapi_ablk_checkaddr(struct ablkcipher_request *req) ++int nss_cryptoapi_ablk_checkaddr(struct skcipher_request *req) + { + /* + * Currently only single sg is supported +@@ -356,7 +356,7 @@ int nss_cryptoapi_ablk_checkaddr(struct ablkcipher_request *req) + /* + * If the size of data is more than 65K reject transformation + */ +- if (req->nbytes > NSS_CRYPTOAPI_MAX_DATA_LEN) { ++ if (req->cryptlen > NSS_CRYPTOAPI_MAX_DATA_LEN) { + nss_cfi_err("Buffer length exceeded limit\n"); + return -EINVAL; + } +@@ -368,10 +368,10 @@ int nss_cryptoapi_ablk_checkaddr(struct ablkcipher_request *req) + * nss_cryptoapi_ablk_transform() + * Crytoapi common routine for encryption and decryption operations. + */ +-struct nss_crypto_buf *nss_cryptoapi_ablk_transform(struct ablkcipher_request *req, struct nss_cryptoapi_ablk_info *info) ++struct nss_crypto_buf *nss_cryptoapi_ablk_transform(struct skcipher_request *req, struct nss_cryptoapi_ablk_info *info) + { +- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); +- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); ++ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); + struct nss_crypto_buf *buf; + struct nss_cryptoapi *sc = &gbl_ctx; + nss_crypto_status_t status; +@@ -382,7 +382,7 @@ struct nss_crypto_buf *nss_cryptoapi_ablk_transform(struct ablkcipher_request *r + nss_cfi_assert(ctx); + + nss_cfi_dbg("src_vaddr: 0x%p, dst_vaddr: 0x%p, iv: 0x%p\n", +- sg_virt(req->src), sg_virt(req->dst), req->info); ++ sg_virt(req->src), sg_virt(req->dst), req->iv); + + info->params->cipher_skip = 0; + info->params->auth_skip = 0; +@@ -419,19 +419,19 @@ struct nss_crypto_buf *nss_cryptoapi_ablk_transform(struct ablkcipher_request *r + /* + * Get IV location and memcpy the IV + */ +- iv_size = crypto_ablkcipher_ivsize(cipher); ++ iv_size = crypto_skcipher_ivsize(cipher); + iv_addr = nss_crypto_get_ivaddr(buf); + + switch (ctx->cip_alg) { + case NSS_CRYPTO_CIPHER_AES_CBC: + case NSS_CRYPTO_CIPHER_DES: +- memcpy(iv_addr, req->info, iv_size); ++ memcpy(iv_addr, req->iv, iv_size); + break; + + case NSS_CRYPTO_CIPHER_AES_CTR: + ((uint32_t *)iv_addr)[0] = ctx->ctx_iv[0]; +- ((uint32_t *)iv_addr)[1] = ((uint32_t *)req->info)[0]; +- ((uint32_t *)iv_addr)[2] = ((uint32_t *)req->info)[1]; ++ ((uint32_t *)iv_addr)[1] = ((uint32_t *)req->iv)[0]; ++ ((uint32_t *)iv_addr)[2] = ((uint32_t *)req->iv)[1]; + ((uint32_t *)iv_addr)[3] = ctx->ctx_iv[3]; + break; + +@@ -446,7 +446,7 @@ struct nss_crypto_buf *nss_cryptoapi_ablk_transform(struct ablkcipher_request *r + /* + * Fill Cipher and Auth len + */ +- cipher_len = req->nbytes; ++ cipher_len = req->cryptlen; + auth_len = 0; + + nss_crypto_set_data(buf, sg_virt(req->src), sg_virt(req->dst), cipher_len); +@@ -463,12 +463,12 @@ struct nss_crypto_buf *nss_cryptoapi_ablk_transform(struct ablkcipher_request *r + } + + /* +- * nss_cryptoapi_ablkcipher_fallback() +- * Cryptoapi fallback for ablkcipher algorithm. ++ * nss_cryptoapi_skcipher_fallback() ++ * Cryptoapi fallback for skcipher algorithm. + */ +-int nss_cryptoapi_ablkcipher_fallback(struct nss_cryptoapi_ctx *ctx, struct ablkcipher_request *req, int type) ++int nss_cryptoapi_skcipher_fallback(struct nss_cryptoapi_ctx *ctx, struct skcipher_request *req, int type) + { +- struct crypto_ablkcipher *orig_tfm = crypto_ablkcipher_reqtfm(req); ++ struct crypto_skcipher *orig_tfm = crypto_skcipher_reqtfm(req); + int err; + + if (!ctx->sw_tfm) { +@@ -476,16 +476,16 @@ int nss_cryptoapi_ablkcipher_fallback(struct nss_cryptoapi_ctx *ctx, struct ablk + } + + /* Set new fallback tfm to the request */ +- ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(ctx->sw_tfm)); ++ skcipher_request_set_tfm(req, __crypto_skcipher_cast(ctx->sw_tfm)); + + ctx->queued++; + + switch (type) { + case NSS_CRYPTOAPI_ENCRYPT: +- err = crypto_ablkcipher_encrypt(req); ++ err = crypto_skcipher_encrypt(req); + break; + case NSS_CRYPTOAPI_DECRYPT: +- err = crypto_ablkcipher_decrypt(req); ++ err = crypto_skcipher_decrypt(req); + break; + default: + err = -EINVAL; +@@ -495,7 +495,7 @@ int nss_cryptoapi_ablkcipher_fallback(struct nss_cryptoapi_ctx *ctx, struct ablk + ctx->completed++; + + /* Set original tfm to the request */ +- ablkcipher_request_set_tfm(req, orig_tfm); ++ skcipher_request_set_tfm(req, orig_tfm); + + return err; + } +@@ -504,13 +504,13 @@ int nss_cryptoapi_ablkcipher_fallback(struct nss_cryptoapi_ctx *ctx, struct ablk + * nss_cryptoapi_ablk_aes_encrypt() + * Crytoapi encrypt for aes(aes-cbc/rfc3686-aes-ctr) algorithms. + */ +-int nss_cryptoapi_ablk_aes_encrypt(struct ablkcipher_request *req) ++int nss_cryptoapi_ablk_aes_encrypt(struct skcipher_request *req) + { + struct nss_crypto_params params = { .req_type = NSS_CRYPTO_REQ_TYPE_ENCRYPT }; +- struct nss_cryptoapi_ablk_info info = {.cb_fn = nss_cryptoapi_ablkcipher_done, ++ struct nss_cryptoapi_ablk_info info = {.cb_fn = nss_cryptoapi_skcipher_done, + .params = ¶ms}; +- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); +- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); ++ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); + struct nss_cryptoapi *sc = &gbl_ctx; + struct nss_crypto_buf *buf; + +@@ -520,7 +520,7 @@ int nss_cryptoapi_ablk_aes_encrypt(struct ablkcipher_request *req) + nss_cryptoapi_verify_magic(ctx); + + if (ctx->fallback_req) +- return nss_cryptoapi_ablkcipher_fallback(ctx, req, NSS_CRYPTOAPI_ENCRYPT); ++ return nss_cryptoapi_skcipher_fallback(ctx, req, NSS_CRYPTOAPI_ENCRYPT); + + /* + * Check if previous call to setkey couldn't allocate session with core crypto. +@@ -539,9 +539,9 @@ int nss_cryptoapi_ablk_aes_encrypt(struct ablkcipher_request *req) + * According to RFC3686, AES-CTR algo need not be padded if the + * plaintext or ciphertext is unaligned to block size boundary. + */ +- if (nss_cryptoapi_check_unalign(req->nbytes, AES_BLOCK_SIZE) && (ctx->cip_alg != NSS_CRYPTO_CIPHER_AES_CTR)) { ++ if (nss_cryptoapi_check_unalign(req->cryptlen, AES_BLOCK_SIZE) && (ctx->cip_alg != NSS_CRYPTO_CIPHER_AES_CTR)) { + nss_cfi_err("Invalid cipher len - Not aligned to algo blocksize\n"); +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); ++ crypto_skcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); + return -EINVAL; + } + +@@ -571,13 +571,13 @@ int nss_cryptoapi_ablk_aes_encrypt(struct ablkcipher_request *req) + * nss_cryptoapi_ablk_aes_decrypt() + * Crytoapi decrypt for aes(aes-cbc/rfc3686-aes-ctr) algorithms. + */ +-int nss_cryptoapi_ablk_aes_decrypt(struct ablkcipher_request *req) ++int nss_cryptoapi_ablk_aes_decrypt(struct skcipher_request *req) + { + struct nss_crypto_params params = { .req_type = NSS_CRYPTO_REQ_TYPE_DECRYPT }; +- struct nss_cryptoapi_ablk_info info = {.cb_fn = nss_cryptoapi_ablkcipher_done, ++ struct nss_cryptoapi_ablk_info info = {.cb_fn = nss_cryptoapi_skcipher_done, + .params = ¶ms}; +- struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); +- struct nss_cryptoapi_ctx *ctx = crypto_ablkcipher_ctx(cipher); ++ struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); ++ struct nss_cryptoapi_ctx *ctx = crypto_skcipher_ctx(cipher); + struct nss_cryptoapi *sc = &gbl_ctx; + struct nss_crypto_buf *buf; + +@@ -587,7 +587,7 @@ int nss_cryptoapi_ablk_aes_decrypt(struct ablkcipher_request *req) + nss_cryptoapi_verify_magic(ctx); + + if (ctx->fallback_req) +- return nss_cryptoapi_ablkcipher_fallback(ctx, req, NSS_CRYPTOAPI_DECRYPT); ++ return nss_cryptoapi_skcipher_fallback(ctx, req, NSS_CRYPTOAPI_DECRYPT); + + /* + * Check if previous call to setkey couldn't allocate session with core crypto. +@@ -606,9 +606,9 @@ int nss_cryptoapi_ablk_aes_decrypt(struct ablkcipher_request *req) + * According to RFC3686, AES-CTR algo need not be padded if the + * plaintext or ciphertext is unaligned to block size boundary. + */ +- if (nss_cryptoapi_check_unalign(req->nbytes, AES_BLOCK_SIZE) && (ctx->cip_alg != NSS_CRYPTO_CIPHER_AES_CTR)) { ++ if (nss_cryptoapi_check_unalign(req->cryptlen, AES_BLOCK_SIZE) && (ctx->cip_alg != NSS_CRYPTO_CIPHER_AES_CTR)) { + nss_cfi_err("Invalid cipher len - Not aligned to algo blocksize\n"); +- crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); ++ crypto_skcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_BLOCK_LEN); + return -EINVAL; + } + +@@ -638,9 +638,9 @@ int nss_cryptoapi_ablk_aes_decrypt(struct ablkcipher_request *req) + * nss_cryptoapi_3des_cbc_setkey() + * Cryptoapi DES3 CBC setkey function. + */ +-int nss_cryptoapi_3des_cbc_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int keylen) ++int nss_cryptoapi_3des_cbc_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int keylen) + { +- struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); + struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(tfm); + struct nss_cryptoapi *sc = &gbl_ctx; + struct nss_crypto_key cip = { .algo = NSS_CRYPTO_CIPHER_DES }; +@@ -693,7 +693,7 @@ int nss_cryptoapi_3des_cbc_setkey(struct crypto_ablkcipher *cipher, const u8 *ke + return 0; + + fail: +- crypto_ablkcipher_set_flags(cipher, flag); ++ crypto_skcipher_set_flags(cipher, flag); + return -EINVAL; + } + +@@ -701,7 +701,7 @@ fail: + * nss_cryptoapi_3des_cbc_encrypt() + * Cryptoapi DES3 CBC encrypt function. + */ +-int nss_cryptoapi_3des_cbc_encrypt(struct ablkcipher_request *req) ++int nss_cryptoapi_3des_cbc_encrypt(struct skcipher_request *req) + { + struct nss_cryptoapi *sc = &gbl_ctx; + struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(req->base.tfm); +@@ -727,14 +727,14 @@ int nss_cryptoapi_3des_cbc_encrypt(struct ablkcipher_request *req) + return -EINVAL; + } + +- if (nss_cryptoapi_check_unalign(req->nbytes, DES3_EDE_BLOCK_SIZE)) { ++ if (nss_cryptoapi_check_unalign(req->cryptlen, DES3_EDE_BLOCK_SIZE)) { + nss_cfi_err("Invalid cipher len - Not aligned to algo blocksize\n"); +- crypto_ablkcipher_set_flags(crypto_ablkcipher_reqtfm(req), CRYPTO_TFM_RES_BAD_BLOCK_LEN); ++ crypto_skcipher_set_flags(crypto_skcipher_reqtfm(req), CRYPTO_TFM_RES_BAD_BLOCK_LEN); + return -EINVAL; + } + + info.params = ¶ms; +- info.cb_fn = nss_cryptoapi_ablkcipher_done; ++ info.cb_fn = nss_cryptoapi_skcipher_done; + + buf = nss_cryptoapi_ablk_transform(req, &info); + if (!buf) { +@@ -762,7 +762,7 @@ int nss_cryptoapi_3des_cbc_encrypt(struct ablkcipher_request *req) + * nss_cryptoapi_3des_cbc_decrypt() + * Cryptoapi DES3 CBC decrypt function. + */ +-int nss_cryptoapi_3des_cbc_decrypt(struct ablkcipher_request *req) ++int nss_cryptoapi_3des_cbc_decrypt(struct skcipher_request *req) + { + struct nss_cryptoapi *sc = &gbl_ctx; + struct nss_cryptoapi_ctx *ctx = crypto_tfm_ctx(req->base.tfm); +@@ -788,14 +788,14 @@ int nss_cryptoapi_3des_cbc_decrypt(struct ablkcipher_request *req) + return -EINVAL; + } + +- if (nss_cryptoapi_check_unalign(req->nbytes, DES3_EDE_BLOCK_SIZE)) { ++ if (nss_cryptoapi_check_unalign(req->cryptlen, DES3_EDE_BLOCK_SIZE)) { + nss_cfi_err("Invalid cipher len - Not aligned to algo blocksize\n"); +- crypto_ablkcipher_set_flags(crypto_ablkcipher_reqtfm(req), CRYPTO_TFM_RES_BAD_BLOCK_LEN); ++ crypto_skcipher_set_flags(crypto_skcipher_reqtfm(req), CRYPTO_TFM_RES_BAD_BLOCK_LEN); + return -EINVAL; + } + + info.params = ¶ms; +- info.cb_fn = nss_cryptoapi_ablkcipher_done; ++ info.cb_fn = nss_cryptoapi_skcipher_done; + + buf = nss_cryptoapi_ablk_transform(req, &info); + if (!buf) { +diff --git a/cryptoapi/v1.1/nss_cryptoapi_debugfs.c b/cryptoapi/v1.1/nss_cryptoapi_debugfs.c +index dff774c..cf4bc70 100644 +--- a/cryptoapi/v1.1/nss_cryptoapi_debugfs.c ++++ b/cryptoapi/v1.1/nss_cryptoapi_debugfs.c +@@ -55,6 +55,7 @@ + */ + void nss_cryptoapi_debugfs_add_stats(struct dentry *parent, struct nss_cryptoapi_ctx *session_ctx) + { ++ pr_info("add stats"); + debugfs_create_u64("queued", S_IRUGO, parent, &session_ctx->queued); + debugfs_create_u64("completed", S_IRUGO, parent, &session_ctx->completed); + debugfs_create_u64("queue_failed", S_IRUGO, parent, &session_ctx->queue_failed); +diff --git a/cryptoapi/v1.1/nss_cryptoapi_private.h b/cryptoapi/v1.1/nss_cryptoapi_private.h +index 5feb9e3..70c6714 100644 +--- a/cryptoapi/v1.1/nss_cryptoapi_private.h ++++ b/cryptoapi/v1.1/nss_cryptoapi_private.h +@@ -141,16 +141,16 @@ int nss_cryptoapi_sha256_3des_encrypt(struct aead_request *req); + int nss_cryptoapi_sha256_3des_decrypt(struct aead_request *req); + + /* ABLKCIPHER */ +-int nss_cryptoapi_ablkcipher_init(struct crypto_tfm *tfm); +-void nss_cryptoapi_ablkcipher_exit(struct crypto_tfm *tfm); +-int nss_cryptoapi_ablk_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int len); +-int nss_cryptoapi_3des_cbc_setkey(struct crypto_ablkcipher *cipher, const u8 *key, unsigned int len); ++int nss_cryptoapi_skcipher_init(struct crypto_skcipher *tfm); ++void nss_cryptoapi_skcipher_exit(struct crypto_skcipher *tfm); ++int nss_cryptoapi_ablk_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int len); ++int nss_cryptoapi_3des_cbc_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int len); + +-int nss_cryptoapi_ablk_aes_encrypt(struct ablkcipher_request *req); +-int nss_cryptoapi_ablk_aes_decrypt(struct ablkcipher_request *req); ++int nss_cryptoapi_ablk_aes_encrypt(struct skcipher_request *req); ++int nss_cryptoapi_ablk_aes_decrypt(struct skcipher_request *req); + +-int nss_cryptoapi_3des_cbc_encrypt(struct ablkcipher_request *req); +-int nss_cryptoapi_3des_cbc_decrypt(struct ablkcipher_request *req); ++int nss_cryptoapi_3des_cbc_encrypt(struct skcipher_request *req); ++int nss_cryptoapi_3des_cbc_decrypt(struct skcipher_request *req); + + #endif /* __NSS_CRYPTOAPI_PRIVATE_H */ + +-- +2.27.0.rc0 + diff --git a/root/package/firmware/nss/qca-nss-clients-64/Makefile b/root/package/firmware/nss/qca-nss-clients-64/Makefile new file mode 100644 index 00000000..11abb99a --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients-64/Makefile @@ -0,0 +1,59 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-clients-64 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/cc-qrdk/oss/lklm/nss-clients +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-04-29 +PKG_SOURCE_VERSION:=b93c72c1b72c591c2ddc2f0b24f0e2b457720118 +PKG_MIRROR_HASH:=fbfba64a364b095ea7c9a24cd7af96b63ab0bc29c179e1628c675aa223c0d063 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-nss-drv-pppoe-64 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - PPPoE + DEPENDS:=@TARGET_ipq807x +kmod-qca-nss-drv-64 +kmod-ppp +kmod-pppoe + FILES:=$(PKG_BUILD_DIR)/pppoe/qca-nss-pppoe.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-pppoe) +endef + +define KernelPackage/qca-nss-drv-pppoe-64/Description +Kernel modules for NSS connection manager - Support for PPPoE +endef + +EXTRA_CFLAGS+= \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-cfi \ + -I$(STAGING_DIR)/usr/include/qca-nss-gmac \ + -I$(STAGING_DIR)/usr/include/qca-ssdk \ + -I$(STAGING_DIR)/usr/include/qca-ssdk/fal \ + -I$(STAGING_DIR)/usr/include/nat46 + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pppoe-64),) +NSS_CLIENTS_MAKE_OPTS+=pppoe=y +endif + +ifeq ($(CONFIG_TARGET_BOARD), "ipq807x") + SOC="ipq807x_64" +else ifeq ($(CONFIG_TARGET_BOARD), "ipq60xx") + SOC="ipq60xx_64" +endif + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" $(strip $(NSS_CLIENTS_MAKE_OPTS)) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + SoC=$(SOC) \ + $(KERNEL_MAKE_FLAGS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-drv-pppoe-64)) diff --git a/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-ipsec b/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-ipsec new file mode 100755 index 00000000..5f682c8e --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-ipsec @@ -0,0 +1,214 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2018-2019, 2021 The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +NSS_IPSEC_LOG_FILE=/tmp/.nss_ipsec_log +NSS_IPSEC_LOG_STR_ECM="ECM_Loaded" +NSS_IPSEC_OL_FILE=/tmp/qca_nss_ipsec_ol + +ecm_load () { + if [ ! -d /sys/module/ecm ]; then + /etc/init.d/qca-nss-ecm start + if [ -d /sys/module/ecm ]; then + echo ${NSS_IPSEC_LOG_STR_ECM} >> ${NSS_IPSEC_LOG_FILE} + fi + fi +} + +ecm_unload () { + if [ -f /tmp/.nss_ipsec_log ]; then + str=`grep ${NSS_IPSEC_LOG_STR_ECM} ${NSS_IPSEC_LOG_FILE}` + if [[ $str == ${NSS_IPSEC_LOG_STR_ECM} ]]; then + /etc/init.d/qca-nss-ecm stop + `sed 's/${NSS_IPSEC_LOG_STR_ECM}/ /g' $NSS_IPSEC_LOG_FILE > $NSS_IPSEC_LOG_FILE` + fi + fi +} + +ecm_disable() { + + if [ ! -d /sys/module/ecm ]; then + return; + fi + + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 2 +} + +ecm_enable() { + if [ ! -d /sys/module/ecm ]; then + return; + fi + + echo 0 > /sys/kernel/debug/ecm/ecm_db/defunct_all + echo 0 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 0 > /sys/kernel/debug/ecm/front_end_ipv6_stop +} + +kernel_version_check_5_4() { + major_ver=$(uname -r | awk -F '.' '{print $1}') + minor_ver=$(uname -r | awk -F '.' '{print $2}') + if [ $major_ver -lt 5 ] || ([ $major_ver -eq 5 ] && [ $minor_ver -lt 4 ] ) ; then + return 1 + else + return 0 + fi +} + +start_klips() { + if kernel_version_check_5_4 + then + echo "Kernel 5.4 doesn't support klips stack." + return $? + fi + + touch $NSS_IPSEC_OL_FILE + ecm_load + + local kernel_version=$(uname -r) + + insmod /lib/modules/${kernel_version}/qca-nss-ipsec-klips.ko + if [ "$?" -gt 0 ]; then + echo "Failed to load plugin. Please start ecm if not done already" + ecm_enable + rm $NSS_IPSEC_OL_FILE + return + fi + + /etc/init.d/ipsec start + sleep 2 + ipsec eroute + + ecm_enable +} + +stop_klips() { + if kernel_version_check_5_4 + then + echo "Kernel 5.4 doesn't support klips stack." + return $? + fi + + ecm_disable + + /etc/init.d/ipsec stop + rmmod qca-nss-ipsec-klips + rm $NSS_IPSEC_OL_FILE + + ecm_unload +} + +start_xfrm() { + touch $NSS_IPSEC_OL_FILE + ecm_load + + local kernel_version=$(uname -r) + + # load all NETKEY modules first. + for mod in xfrm_ipcomp ipcomp xfrm6_tunnel ipcomp6 xfrm6_mode_tunnel xfrm6_mode_beet xfrm6_mode_ro \ + xfrm6_mode_transport xfrm4_mode_transport xfrm4_mode_tunnel \ + xfrm4_tunnel xfrm4_mode_beet esp4 esp6 ah4 ah6 af_key + do + insmod $mod 2> /dev/null + done + + # Now load the xfrm plugin + insmod /lib/modules/${kernel_version}/qca-nss-ipsec-xfrm.ko + if [ "$?" -gt 0 ]; then + echo "Failed to load plugin. Please start ecm if not done already" + ecm_enable + rm $NSS_IPSEC_OL_FILE + return + fi + + /etc/init.d/ipsec start + sleep 2 + + ecm_enable +} + +stop_xfrm() { + ecm_disable + + #Shutdown Pluto first. Then only plugin can be removed. + plutopid=/var/run/pluto/pluto.pid + if [ -f $plutopid ]; then + pid=`cat $plutopid` + if [ ! -z "$pid" ]; then + ipsec whack --shutdown | grep -v "002"; + if [ -s $plutopid ]; then + echo "Attempt to shut Pluto down failed! Trying kill:" + kill $pid; + sleep 5; + fi + fi + rm -rf $plutopid + fi + ip xfrm state flush; + ip xfrm policy flush; + sleep 2 + + #Now we can remove the plugin + retries=5 + while [ -d /sys/module/qca_nss_ipsec_xfrm ] + do + rmmod qca-nss-ipsec-xfrm + if [ "$?" -eq 0 ]; then + rm $NSS_IPSEC_OL_FILE + break + fi + + if [ ${retries} -eq 0 ]; then + echo "Failed to unload qca-nss-ipsec-xfrm plugin!" + exit + fi + + echo "XFRM plugin unload failed; retrying ${retries} times" + sleep 1 + retries=`expr ${retries} - 1` + done + + /etc/init.d/ipsec stop + ecm_unload +} + +start() { + local protostack=`uci -q get ipsec.setup.protostack` + if [ "$protostack" = "klips" ]; then + start_klips + return $? + fi + + start_xfrm + return $? +} + +stop() { + local protostack=`uci -q get ipsec.setup.protostack` + if [ "$protostack" = "klips" ]; then + stop_klips + return $? + fi + + stop_xfrm + return $? +} + +restart() { + stop + start +} diff --git a/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-mirred.init b/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-mirred.init new file mode 100644 index 00000000..1f931f09 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-mirred.init @@ -0,0 +1,28 @@ +#!/bin/sh /etc/rc.common + +########################################################################### +# Copyright (c) 2019, The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +########################################################################### + +restart() { + rmmod act_nssmirred.ko + insmod act_nssmirred.ko +} + +start() { + insmod act_nssmirred.ko +} + +stop() { + rmmod act_nssmirred.ko +} diff --git a/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-ovpn.init b/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-ovpn.init new file mode 100644 index 00000000..622e295e --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients-64/files/qca-nss-ovpn.init @@ -0,0 +1,69 @@ +#!/bin/sh /etc/rc.common + +########################################################################### +# Copyright (c) 2019, The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +########################################################################### + +ecm_disable() { + if [ ! -d /sys/module/ecm ]; then + return + fi + + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 2 +} + +ecm_enable() { + if [ ! -d /sys/module/ecm ]; then + return + fi + + echo 0 > /sys/kernel/debug/ecm/ecm_db/defunct_all + echo 0 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 0 > /sys/kernel/debug/ecm/front_end_ipv6_stop +} + +restart() { + ecm_disable + + /etc/init.d/openvpn stop + rmmod qca-nss-ovpn-link + rmmod qca-nss-ovpn-mgr + + insmod qca-nss-ovpn-mgr + insmod qca-nss-ovpn-link + + if [ "$?" -gt 0 ]; then + echo "Failed to load plugin. Please start ecm if not done already" + ecm_enable + return + fi + + ecm_enable +} + +start() { + restart +} + +stop() { + ecm_disable + + /etc/init.d/openvpn stop + rmmod qca-nss-ovpn-link + rmmod qca-nss-ovpn-mgr + + ecm_enable +} diff --git a/root/package/firmware/nss/qca-nss-clients/Makefile b/root/package/firmware/nss/qca-nss-clients/Makefile new file mode 100644 index 00000000..e782cf81 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/Makefile @@ -0,0 +1,469 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-nss-clients +PKG_RELEASE:=2 + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-clients +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=740d0102c518cd49f30c5580982b218b480006b1 +PKG_MIRROR_HASH:=2f427d01dba69b1b89d3a081daf08b36fb345d55b9c9462eb358e5b071e2a171 + +include $(INCLUDE_DIR)/package.mk + +# Keep default as ipq806x for branches that does not have subtarget framework +ifeq ($(CONFIG_TARGET_ipq),y) +subtarget:=$(SUBTARGET) +else +subtarget:=$(CONFIG_TARGET_BOARD) +endif + +ifneq (, $(findstring $(subtarget), "ipq807x" "ipq807x_64" "ipq60xx" "ipq60xx_64")) +# DTLS Manager v2.0 for Hawkeye/Cypress + DTLSMGR_DIR:=v2.0 +# IPsec Manager v2.0 for Hawkeye/Cypress + IPSECMGR_DIR:=v2.0 +# KLIPS plugin + IPSECMGR_KLIPS:= $(PKG_BUILD_DIR)/ipsecmgr/$(IPSECMGR_DIR)/plugins/klips/qca-nss-ipsec-klips.ko +else +# DTLS Manager v1.0 for Akronite. + DTLSMGR_DIR:=v1.0 +# IPsec Manager v1.0 for Akronite. + IPSECMGR_DIR:=v1.0 +# KLIPS plugin not needed + IPSECMGR_KLIPS:= +endif + +define KernelPackage/qca-nss-drv-tun6rd + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - tun6rd + DEPENDS:=+kmod-qca-nss-drv +kmod-sit +6rd @!LINUX_3_18 + FILES:=$(PKG_BUILD_DIR)/qca-nss-tun6rd.ko + AUTOLOAD:=$(call AutoLoad,60,qca-nss-tun6rd) +endef + +define KernelPackage/qca-nss-drv-tun6rd/Description +Kernel modules for NSS connection manager - Support for 6rd tunnel +endef + +define KernelPackage/qca-nss-drv-dtlsmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - dtlsmgr + DEPENDS:=+kmod-qca-nss-drv +kmod-qca-nss-cfi-cryptoapi @!LINUX_3_18 + FILES:=$(PKG_BUILD_DIR)/dtls/$(DTLSMGR_DIR)/qca-nss-dtlsmgr.ko +endef + +define KernelPackage/qca-nss-drv-dtls/Description +Kernel modules for NSS connection manager - Support for DTLS sessions +endef + +define KernelPackage/qca-nss-drv-l2tpv2 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - l2tp + DEPENDS:=+kmod-qca-nss-drv +kmod-ppp +kmod-l2tp @!LINUX_3_18 + FILES:=$(PKG_BUILD_DIR)/l2tp/l2tpv2/qca-nss-l2tpv2.ko + KCONFIG:=CONFIG_L2TP=y + AUTOLOAD:=$(call AutoLoad,51,qca-nss-l2tpv2) +endef + +define KernelPackage/qca-nss-drv-l2tpv2/Description +Kernel modules for NSS connection manager - Support for l2tp tunnel +endef + +define KernelPackage/qca-nss-drv-pptp + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - PPTP + DEPENDS:=+kmod-qca-nss-drv +kmod-pptp @!LINUX_3_18 + FILES:=$(PKG_BUILD_DIR)/pptp/qca-nss-pptp.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-pptp) +endef + +define KernelPackage/qca-nss-drv-pptp/Description +Kernel modules for NSS connection manager - Support for PPTP tunnel +endef + +define KernelPackage/qca-nss-drv-pppoe + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - PPPoE + DEPENDS:=+kmod-qca-nss-drv +kmod-pppoe @!LINUX_3_18 \ + +!(TARGET_ipq_ipq807x_QSDK_256||TARGET_ipq_ipq60xx_QSDK_256):kmod-bonding + FILES:=$(PKG_BUILD_DIR)/pppoe/qca-nss-pppoe.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-pppoe) +endef + +define KernelPackage/qca-nss-drv-pppoe/Description +Kernel modules for NSS connection manager - Support for PPPoE +endef + +define KernelPackage/qca-nss-drv-map-t + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - MAP-T + DEPENDS:=+kmod-qca-nss-drv +kmod-nat46 @!LINUX_3_18 + FILES:=$(PKG_BUILD_DIR)/map/map-t/qca-nss-map-t.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-map-t) +endef + +define KernelPackage/qca-nss-drv-map-t/Description +Kernel modules for NSS connection manager - Support for MAP-T +endef + +define KernelPackage/qca-nss-drv-gre + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - GRE + DEPENDS:=@TARGET_ipq_ipq806x||TARGET_ipq806x||TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64 \ + +kmod-qca-nss-drv @!LINUX_3_18 +kmod-gre6 + FILES:=$(PKG_BUILD_DIR)/gre/qca-nss-gre.ko $(PKG_BUILD_DIR)/gre/test/qca-nss-gre-test.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-gre) +endef + +define KernelPackage/qca-nss-drv-gre/Description +Kernel modules for NSS connection manager - Support for GRE +endef + +define KernelPackage/qca-nss-drv-tunipip6 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (connection manager) - DS-lite and ipip6 Tunnel + DEPENDS:=+kmod-qca-nss-drv +kmod-iptunnel6 +kmod-ip6-tunnel @!LINUX_3_18 + FILES:=$(PKG_BUILD_DIR)/qca-nss-tunipip6.ko + AUTOLOAD:=$(call AutoLoad,60,qca-nss-tunipip6) +endef + +define KernelPackage/qca-nss-drv-tunipip6/Description +Kernel modules for NSS connection manager +Add support for DS-lite and ipip6 tunnel +endef + +define KernelPackage/qca-nss-drv-profile + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=+kmod-qca-nss-drv @!LINUX_3_18 + TITLE:=Profiler for QCA NSS driver (IPQ806x) + FILES:=$(PKG_BUILD_DIR)/profiler/qca-nss-profile-drv.ko +endef + +define KernelPackage/qca-nss-drv-profile/Description +This package contains a NSS driver profiler for QCA chipset +endef + +define KernelPackage/qca-nss-drv-ipsecmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS (ipsec manager) - ipsecmgr + DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq806x||TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64 \ + +kmod-qca-nss-drv +kmod-qca-nss-ecm-standard +kmod-qca-nss-cfi-cryptoapi @!LINUX_3_18 +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-l2tpv2),) + DEPENDS+=+kmod-qca-nss-drv-l2tpv2 +endif + FILES:=$(PKG_BUILD_DIR)/ipsecmgr/$(IPSECMGR_DIR)/qca-nss-ipsecmgr.ko $(IPSECMGR_KLIPS) + AUTOLOAD:=$(call AutoLoad,60,qca-nss-ipsecmgr) +endef + +define KernelPackage/qca-nss-drv-ipsecmgr/Description +Kernel module for NSS IPsec offload manager +endef + +define KernelPackage/qca-nss-drv-capwapmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=+kmod-qca-nss-drv +kmod-qca-nss-drv-dtlsmgr @!LINUX_3_18 + TITLE:=NSS CAPWAP Manager for QCA NSS driver (IPQ806x) + FILES:=$(PKG_BUILD_DIR)/capwapmgr/qca-nss-capwapmgr.ko +endef + +define KernelPackage/qca-nss-drv-capwapmgr/Description +This package contains a NSS CAPWAP Manager +endef + +define KernelPackage/qca-nss-drv-bridge-mgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS bridge manager + DEPENDS:=@TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64 \ + +TARGET_ipq_ipq807x:kmod-qca-nss-drv-vlan-mgr \ + +TARGET_ipq_ipq807x_64:kmod-qca-nss-drv-vlan-mgr \ + +TARGET_ipq807x:kmod-qca-nss-drv-vlan-mgr \ + +TARGET_ipq807x_64:kmod-qca-nss-drv-vlan-mgr \ + +TARGET_ipq_ipq60xx:kmod-qca-nss-drv-vlan-mgr \ + +TARGET_ipq_ipq60xx_64:kmod-qca-nss-drv-vlan-mgr @!LINUX_3_18 \ + +!(TARGET_ipq_ipq807x_QSDK_256||TARGET_ipq_ipq60xx_QSDK_256):kmod-bonding + FILES:=$(PKG_BUILD_DIR)/bridge/qca-nss-bridge-mgr.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-bridge-mgr) +endef + +define KernelPackage/qca-nss-drv-bridge-mgr/Description +Kernel modules for NSS bridge manager +endef + +define KernelPackage/qca-nss-drv-vlan-mgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS vlan manager + DEPENDS:=@TARGET_ipq806x||TARGET_ipq807x +kmod-qca-nss-drv @!LINUX_3_18 \ + +!(TARGET_ipq_ipq807x_QSDK_256||TARGET_ipq_ipq60xx_QSDK_256):kmod-bonding + FILES:=$(PKG_BUILD_DIR)/vlan/qca-nss-vlan.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-vlan) +endef + +define KernelPackage/qca-nss-drv-vlan-mgr/Description +Kernel modules for NSS vlan manager +endef + +define KernelPackage/qca-nss-drv-qdisc + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + TITLE:=Qdisc for configuring shapers in NSS + DEPENDS:=+kmod-qca-nss-drv @!LINUX_3_18 + FILES:=$(PKG_BUILD_DIR)/nss_qdisc/qca-nss-qdisc.ko + KCONFIG:=CONFIG_NET_CLS_ACT=y + AUTOLOAD:=$(call AutoLoad,58,qca-nss-qdisc) +endef + +define KernelPackage/qca-nss-drv-qdisc/Description +Linux qdisc that aids in configuring shapers in the NSS +endef + +define KernelPackage/qca-nss-drv-lag-mgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS LAG manager + DEPENDS:=+kmod-qca-nss-drv @!LINUX_3_18 \ + +TARGET_ipq_ipq807x:kmod-qca-nss-drv-vlan-mgr \ + +TARGET_ipq_ipq807x_64:kmod-qca-nss-drv-vlan-mgr @!LINUX_3_18 \ + +TARGET_ipq807x:kmod-qca-nss-drv-vlan-mgr \ + +TARGET_ipq807x_64:kmod-qca-nss-drv-vlan-mgr @!LINUX_3_18 \ + +TARGET_ipq_ipq60xx:kmod-qca-nss-drv-vlan-mgr @!LINUX_3_18 \ + +TARGET_ipq_ipq60xx_64:kmod-qca-nss-drv-vlan-mgr @!LINUX_3_18 \ + +kmod-bonding + FILES:=$(PKG_BUILD_DIR)/lag/qca-nss-lag-mgr.ko + AUTOLOAD:=$(call AutoLoad,51,qca-nss-lag-mgr) +endef + +define KernelPackage/qca-nss-drv-lag-mgr/Description +Kernel modules for NSS LAG manager +endef + +define KernelPackage/qca-nss-drv-netlink + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_ipq807x||TARGET_ipq_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64 \ + +kmod-qca-nss-drv @!LINUX_3_18 \ + +PACKAGE_kmod-qca-nss-drv-ipsecmgr:kmod-qca-nss-drv-ipsecmgr \ + +PACKAGE_kmod-qca-nss-drv-dtlsmgr:kmod-qca-nss-drv-dtlsmgr \ + +PACKAGE_kmod-qca-nss-drv-capwapmgr:kmod-qca-nss-drv-capwapmgr @!LINUX_3_18 + TITLE:=NSS NETLINK Manager for QCA NSS driver + FILES:=$(PKG_BUILD_DIR)/netlink/qca-nss-netlink.ko +endef + +define KernelPackage/qca-nss-drv-netlink/Description +Kernel module for NSS netlink manager +endef + +define KernelPackage/qca-nss-drv-ovpn-mgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for NSS OpenVPN manager + DEPENDS:=+kmod-qca-nss-drv +kmod-qca-nss-cfi-cryptoapi +kmod-tun +kmod-ipt-conntrack @!LINUX_3_18 \ + @TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64 + FILES:=$(PKG_BUILD_DIR)/openvpn/src/qca-nss-ovpn-mgr.ko +endef + +define KernelPackage/qca-nss-drv-ovpn-mgr/Description +Kernel module for NSS OpenVPN manager +endef + +define KernelPackage/qca-nss-drv-ovpn-link + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for interfacing NSS OpenVPN manager with ECM + DEPENDS:=+kmod-qca-nss-drv-ovpn-mgr +@PACKAGE_kmod-qca-nss-ecm-premium @!LINUX_3_18 \ + @TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64 + FILES:=$(PKG_BUILD_DIR)/openvpn/plugins/qca-nss-ovpn-link.ko +endef + +define KernelPackage/qca-nss-drv-ovpn-link/Description +This module registers with ECM and communicates with NSS OpenVPN manager for supporting OpenVPN offload. +endef + +define KernelPackage/qca-nss-drv-pvxlanmgr + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=+kmod-qca-nss-drv @!LINUX_3_18 + TITLE:=NSS PVXLAN Manager for QCA NSS driver + FILES:=$(PKG_BUILD_DIR)/pvxlanmgr/qca-nss-pvxlanmgr.ko +endef + +define KernelPackage/qca-nss-drv-pvxlanmgr/Description +Kernel module for managing NSS PVxLAN +endef + +define Build/InstallDev/qca-nss-clients + $(INSTALL_DIR) $(1)/usr/include/qca-nss-clients + $(CP) $(PKG_BUILD_DIR)/netlink/include/* $(1)/usr/include/qca-nss-clients/ + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-clients/ +endef + +define Build/InstallDev + $(call Build/InstallDev/qca-nss-clients,$(1)) +endef + +define KernelPackage/qca-nss-drv-ovpn-mgr/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-nss-ovpn.init $(1)/etc/init.d/qca-nss-ovpn +endef + +define KernelPackage/qca-nss-drv-ipsecmgr/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-nss-ipsec $(1)/etc/init.d/qca-nss-ipsec +endef + + +EXTRA_CFLAGS+= \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-cfi \ + -I$(STAGING_DIR)/usr/include/qca-nss-gmac \ + -I$(STAGING_DIR)/usr/include/qca-nss-ecm \ + -I$(STAGING_DIR)/usr/include/qca-ssdk \ + -I$(STAGING_DIR)/usr/include/qca-ssdk/fal \ + -I$(STAGING_DIR)/usr/include/nat46 + +# Build individual packages if selected +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-profile),) +MAKE_OPTS+=profile=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-capwapmgr),) +MAKE_OPTS+=capwapmgr=y +EXTRA_CFLAGS += -DNSS_CAPWAPMGR_ONE_NETDEV +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-tun6rd),) +MAKE_OPTS+=tun6rd=m +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-dtlsmgr),) +MAKE_OPTS+=dtlsmgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-l2tpv2),) +MAKE_OPTS+=l2tpv2=y +EXTRA_CFLAGS += -DNSS_L2TPV2_ENABLED +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pptp),) +MAKE_OPTS+=pptp=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-map-t),) +MAKE_OPTS+=map-t=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-tunipip6),) +MAKE_OPTS+=tunipip6=m +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-qdisc),) +MAKE_OPTS+=qdisc=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ipsecmgr),) +EXTRA_CFLAGS+= -I$(PKG_BUILD_DIR)/exports \ + -I$(STAGING_DIR)/usr/include/qca-nss-ecm +MAKE_OPTS+=ipsecmgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-bridge-mgr),) +MAKE_OPTS+=bridge-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vlan-mgr),) +MAKE_OPTS+=vlan-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-lag-mgr),) +MAKE_OPTS+=lag-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-gre),) +EXTRA_CFLAGS+= -I$(PKG_BUILD_DIR)/exports +MAKE_OPTS+=gre=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pppoe),) +MAKE_OPTS+=pppoe=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-netlink),) +MAKE_OPTS+=netlink=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ovpn-mgr),) +MAKE_OPTS+=ovpn-mgr=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ovpn-link),) +MAKE_OPTS+=ovpn-link=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-pvxlanmgr),) +MAKE_OPTS+=pvxlanmgr=y +endif + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(MAKE_OPTS)) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + SoC="$(subtarget)" \ + DTLSMGR_DIR="$(DTLSMGR_DIR)" \ + IPSECMGR_DIR="$(IPSECMGR_DIR)" \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-drv-profile)) +$(eval $(call KernelPackage,qca-nss-drv-capwapmgr)) +$(eval $(call KernelPackage,qca-nss-drv-tun6rd)) +$(eval $(call KernelPackage,qca-nss-drv-dtlsmgr)) +$(eval $(call KernelPackage,qca-nss-drv-l2tpv2)) +$(eval $(call KernelPackage,qca-nss-drv-pptp)) +$(eval $(call KernelPackage,qca-nss-drv-pppoe)) +$(eval $(call KernelPackage,qca-nss-drv-map-t)) +$(eval $(call KernelPackage,qca-nss-drv-tunipip6)) +$(eval $(call KernelPackage,qca-nss-drv-qdisc)) +$(eval $(call KernelPackage,qca-nss-drv-netlink)) +$(eval $(call KernelPackage,qca-nss-drv-ipsecmgr)) +$(eval $(call KernelPackage,qca-nss-drv-bridge-mgr)) +$(eval $(call KernelPackage,qca-nss-drv-vlan-mgr)) +$(eval $(call KernelPackage,qca-nss-drv-lag-mgr)) +$(eval $(call KernelPackage,qca-nss-drv-gre)) +$(eval $(call KernelPackage,qca-nss-drv-ovpn-mgr)) +$(eval $(call KernelPackage,qca-nss-drv-ovpn-link)) +$(eval $(call KernelPackage,qca-nss-drv-pvxlanmgr)) diff --git a/root/package/firmware/nss/qca-nss-clients/files/qca-nss-ipsec b/root/package/firmware/nss/qca-nss-clients/files/qca-nss-ipsec new file mode 100644 index 00000000..bb202e8e --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/files/qca-nss-ipsec @@ -0,0 +1,92 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +NSS_IPSEC_LOG_FILE=/tmp/.nss_ipsec_log +NSS_IPSEC_LOG_STR_ECM="ECM_Loaded" + +ecm_load () { + if [ ! -d /sys/module/ecm ]; then + /etc/init.d/qca-nss-ecm start + if [ -d /sys/module/ecm ]; then + echo ${NSS_IPSEC_LOG_STR_ECM} >> ${NSS_IPSEC_LOG_FILE} + fi + fi +} + +ecm_unload () { + if [ -f /tmp/.nss_ipsec_log ]; then + str=`grep ${NSS_IPSEC_LOG_STR_ECM} ${NSS_IPSEC_LOG_FILE}` + if [[ $str == ${NSS_IPSEC_LOG_STR_ECM} ]]; then + /etc/init.d/qca-nss-ecm stop + `sed 's/${NSS_IPSEC_LOG_STR_ECM}/ /g' $NSS_IPSEC_LOG_FILE > $NSS_IPSEC_LOG_FILE` + fi + fi +} + +ecm_disable() { + + if [ ! -d /sys/module/ecm ]; then + return; + fi + + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 2 +} + +ecm_enable() { + if [ ! -d /sys/module/ecm ]; then + return; + fi + + echo 0 > /sys/kernel/debug/ecm/ecm_db/defunct_all + echo 0 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 0 > /sys/kernel/debug/ecm/front_end_ipv6_stop +} + +start() { + ecm_load + + local kernel_version=$(uname -r) + + insmod /lib/modules/${kernel_version}/qca-nss-ipsec-klips.ko + if [ "$?" -gt 0 ]; then + echo "Failed to load plugin. Please start ecm if not done already" + ecm_enable + return + fi + + /etc/init.d/ipsec start + sleep 2 + ipsec eroute + + ecm_enable +} + +stop() { + ecm_disable + + /etc/init.d/ipsec stop + rmmod qca-nss-ipsec-klips + + ecm_unload +} + +restart() { + stop + start +} diff --git a/root/package/firmware/nss/qca-nss-clients/files/qca-nss-mirred.init b/root/package/firmware/nss/qca-nss-clients/files/qca-nss-mirred.init new file mode 100644 index 00000000..1f931f09 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/files/qca-nss-mirred.init @@ -0,0 +1,28 @@ +#!/bin/sh /etc/rc.common + +########################################################################### +# Copyright (c) 2019, The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +########################################################################### + +restart() { + rmmod act_nssmirred.ko + insmod act_nssmirred.ko +} + +start() { + insmod act_nssmirred.ko +} + +stop() { + rmmod act_nssmirred.ko +} diff --git a/root/package/firmware/nss/qca-nss-clients/files/qca-nss-ovpn.init b/root/package/firmware/nss/qca-nss-clients/files/qca-nss-ovpn.init new file mode 100644 index 00000000..622e295e --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/files/qca-nss-ovpn.init @@ -0,0 +1,69 @@ +#!/bin/sh /etc/rc.common + +########################################################################### +# Copyright (c) 2019, The Linux Foundation. All rights reserved. +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all copies. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +########################################################################### + +ecm_disable() { + if [ ! -d /sys/module/ecm ]; then + return + fi + + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 2 +} + +ecm_enable() { + if [ ! -d /sys/module/ecm ]; then + return + fi + + echo 0 > /sys/kernel/debug/ecm/ecm_db/defunct_all + echo 0 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 0 > /sys/kernel/debug/ecm/front_end_ipv6_stop +} + +restart() { + ecm_disable + + /etc/init.d/openvpn stop + rmmod qca-nss-ovpn-link + rmmod qca-nss-ovpn-mgr + + insmod qca-nss-ovpn-mgr + insmod qca-nss-ovpn-link + + if [ "$?" -gt 0 ]; then + echo "Failed to load plugin. Please start ecm if not done already" + ecm_enable + return + fi + + ecm_enable +} + +start() { + restart +} + +stop() { + ecm_disable + + /etc/init.d/openvpn stop + rmmod qca-nss-ovpn-link + rmmod qca-nss-ovpn-mgr + + ecm_enable +} diff --git a/root/package/firmware/nss/qca-nss-clients/patches/100-kernel-5.4-support-qdisc.patch b/root/package/firmware/nss/qca-nss-clients/patches/100-kernel-5.4-support-qdisc.patch new file mode 100644 index 00000000..0ec8d766 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/patches/100-kernel-5.4-support-qdisc.patch @@ -0,0 +1,1145 @@ +--- a/nss_qdisc/nss_qdisc.h ++++ b/nss_qdisc/nss_qdisc.h +@@ -338,7 +340,7 @@ extern void nss_qdisc_destroy(struct nss + * Initializes a shaper in NSS, based on the position of this qdisc (child or root) + * and if its a normal interface or a bridge interface. + */ +-extern int nss_qdisc_init(struct Qdisc *sch, struct nss_qdisc *nq, nss_shaper_node_type_t type, uint32_t classid, uint32_t accel_mode); ++extern int nss_qdisc_init(struct Qdisc *sch, struct netlink_ext_ack *extack, struct nss_qdisc *nq, nss_shaper_node_type_t type, uint32_t classid, uint32_t accel_mode); + + /* + * nss_qdisc_start_basic_stats_polling() +--- a/nss_qdisc/nss_bf.c ++++ b/nss_qdisc/nss_bf.c +@@ -69,7 +69,7 @@ static inline struct nss_bf_class_data * + * Configures a new class. + */ + static int nss_bf_change_class(struct Qdisc *sch, u32 classid, u32 parentid, +- struct nlattr **tca, unsigned long *arg) ++ struct nlattr **tca, unsigned long *arg, struct netlink_ext_ack *extack) + { + struct nss_bf_sched_data *q = qdisc_priv(sch); + struct nss_bf_class_data *cl = (struct nss_bf_class_data *)*arg; +@@ -121,7 +121,7 @@ static int nss_bf_change_class(struct Qd + * that is registered to Linux. Therefore we initialize the NSSBF_GROUP shaper + * here. + */ +- if (nss_qdisc_init(sch, &cl->nq, NSS_SHAPER_NODE_TYPE_BF_GROUP, classid, accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, &cl->nq, NSS_SHAPER_NODE_TYPE_BF_GROUP, classid, accel_mode) < 0) { + nss_qdisc_error("Nss init for class %u failed\n", classid); + kfree(cl); + return -EINVAL; +@@ -260,7 +260,7 @@ static void nss_bf_destroy_class(struct + /* + * And now we destroy the child. + */ +- qdisc_destroy(cl->qdisc); ++ qdisc_put(cl->qdisc); + + /* + * Stop the stats polling timer and free class +@@ -325,7 +325,7 @@ static int nss_bf_delete_class(struct Qd + * Replaces the qdisc attached to the provided class. + */ + static int nss_bf_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, +- struct Qdisc **old) ++ struct Qdisc **old, struct netlink_ext_ack *extack) + { + struct nss_bf_sched_data *q = qdisc_priv(sch); + struct nss_bf_class_data *cl = (struct nss_bf_class_data *)arg; +@@ -432,24 +432,6 @@ static unsigned long nss_bf_get_class(st + } + + /* +- * nss_bf_put_class() +- * Reduces reference count for this class. +- */ +-static void nss_bf_put_class(struct Qdisc *sch, unsigned long arg) +-{ +- struct nss_bf_class_data *cl = (struct nss_bf_class_data *)arg; +- nss_qdisc_info("bf put class for %p\n", cl); +- +- /* +- * We are safe to destroy the qdisc if the reference count +- * goes down to 0. +- */ +- if (atomic_sub_return(1, &cl->nq.refcnt) == 0) { +- nss_bf_destroy_class(sch, cl); +- } +-} +- +-/* + * nss_bf_dump_class() + * Dumps all configurable parameters pertaining to this class. + */ +@@ -538,7 +520,7 @@ static void nss_bf_walk(struct Qdisc *sc + * nss_bf_change_qdisc() + * Can be used to configure a nssbf qdisc. + */ +-static int nss_bf_change_qdisc(struct Qdisc *sch, struct nlattr *opt) ++static int nss_bf_change_qdisc(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_bf_sched_data *q = qdisc_priv(sch); + struct tc_nssbf_qopt *qopt; +@@ -684,7 +666,7 @@ static void nss_bf_destroy_qdisc(struct + * nss_bf_init_qdisc() + * Initializes the nssbf qdisc. + */ +-static int nss_bf_init_qdisc(struct Qdisc *sch, struct nlattr *opt) ++static int nss_bf_init_qdisc(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_bf_sched_data *q = qdisc_priv(sch); + struct tc_nssbf_qopt *qopt; +@@ -720,7 +702,7 @@ static int nss_bf_init_qdisc(struct Qdis + /* + * Initialize the NSSBF shaper in NSS + */ +- if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_BF, 0, accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, &q->nq, NSS_SHAPER_NODE_TYPE_BF, 0, accel_mode) < 0) { + return -EINVAL; + } + +@@ -729,7 +711,7 @@ static int nss_bf_init_qdisc(struct Qdis + /* + * Tune nss_bf parameters. + */ +- if (nss_bf_change_qdisc(sch, opt) < 0) { ++ if (nss_bf_change_qdisc(sch, opt, NULL) < 0) { + nss_qdisc_destroy(&q->nq); + return -EINVAL; + } +@@ -772,7 +754,7 @@ nla_put_failure: + * nss_bf_enqueue() + * Enqueues a skb to nssbf qdisc. + */ +-static int nss_bf_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_bf_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -787,18 +769,6 @@ static struct sk_buff *nss_bf_dequeue(st + } + + /* +- * nss_bf_drop() +- * Drops a single skb from linux queue, if not empty. +- * +- * Does not drop packets that are queued in the NSS. +- */ +-static unsigned int nss_bf_drop(struct Qdisc *sch) +-{ +- printk("In bf drop\n"); +- return nss_qdisc_drop(sch); +-} +- +-/* + * Registration structure for nssbf class + */ + const struct Qdisc_class_ops nss_bf_class_ops = { +@@ -807,9 +777,8 @@ const struct Qdisc_class_ops nss_bf_clas + .graft = nss_bf_graft_class, + .leaf = nss_bf_leaf_class, + .qlen_notify = nss_bf_qlen_notify, +- .get = nss_bf_get_class, +- .put = nss_bf_put_class, ++ .find = nss_bf_get_class, + .dump = nss_bf_dump_class, + .dump_stats = nss_bf_dump_class_stats, + .walk = nss_bf_walk + }; +@@ -830,7 +798,6 @@ struct Qdisc_ops nss_bf_qdisc_ops __read + .enqueue = nss_bf_enqueue, + .dequeue = nss_bf_dequeue, + .peek = qdisc_peek_dequeued, +- .drop = nss_bf_drop, + .cl_ops = &nss_bf_class_ops, + .priv_size = sizeof(struct nss_bf_sched_data), + .owner = THIS_MODULE +--- a/nss_qdisc/nss_blackhole.c ++++ b/nss_qdisc/nss_blackhole.c +@@ -35,7 +35,7 @@ static struct nla_policy nss_blackhole_p + * nss_blackhole_enqueue() + * Enqueue API for nss blackhole qdisc. + */ +-static int nss_blackhole_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_blackhole_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -50,18 +50,6 @@ static struct sk_buff *nss_blackhole_deq + } + + /* +- * nss_blackhole_drop() +- * The following function drops a packet from HLOS queue. +- * +- * Note, this does not drop packets from queues in the NSS. We do not support that. +- */ +-static unsigned int nss_blackhole_drop(struct Qdisc *sch) +-{ +- nss_qdisc_info("qdisc %x dropping\n", sch->handle); +- return nss_qdisc_drop(sch); +-} +- +-/* + * nss_blackhole_reset() + * Resets the nss blackhole qdisc. + */ +@@ -92,7 +80,7 @@ static void nss_blackhole_destroy(struct + * nss_blackhole_change() + * Function call used to configure the parameters of the nss blackhole qdisc. + */ +-static int nss_blackhole_change(struct Qdisc *sch, struct nlattr *opt) ++static int nss_blackhole_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_blackhole_sched_data *q; + struct tc_nssblackhole_qopt *qopt; +@@ -154,7 +142,7 @@ static int nss_blackhole_change(struct Q + * nss_blackhole_init() + * Initializes a nss blackhole qdisc. + */ +-static int nss_blackhole_init(struct Qdisc *sch, struct nlattr *opt) ++static int nss_blackhole_init(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_qdisc *nq = qdisc_priv(sch); + struct tc_nssblackhole_qopt *qopt; +@@ -176,12 +164,12 @@ static int nss_blackhole_init(struct Qdi + nss_qdisc_info("qdisc %x initializing\n", sch->handle); + nss_blackhole_reset(sch); + +- if (nss_qdisc_init(sch, nq, NSS_SHAPER_NODE_TYPE_FIFO, 0, accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, nq, NSS_SHAPER_NODE_TYPE_FIFO, 0, accel_mode) < 0) { + return -EINVAL; + } + + nss_qdisc_info("qdisc %x initialized with parent %x\n", sch->handle, sch->parent); +- if (nss_blackhole_change(sch, opt) < 0) { ++ if (nss_blackhole_change(sch, opt, NULL) < 0) { + nss_qdisc_destroy(nq); + return -EINVAL; + } +@@ -251,7 +239,6 @@ struct Qdisc_ops nss_blackhole_qdisc_ops + .enqueue = nss_blackhole_enqueue, + .dequeue = nss_blackhole_dequeue, + .peek = nss_blackhole_peek, +- .drop = nss_blackhole_drop, + .init = nss_blackhole_init, + .reset = nss_blackhole_reset, + .destroy = nss_blackhole_destroy, +--- a/nss_qdisc/nss_codel.c ++++ b/nss_qdisc/nss_codel.c +@@ -76,7 +76,7 @@ static struct nla_policy nss_codel_polic + * nss_codel_enqueue() + * Enqueue a packet into nss_codel queue in NSS firmware (bounce). + */ +-static int nss_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -91,17 +91,6 @@ static struct sk_buff *nss_codel_dequeue + } + + /* +- * nss_codel_drop() +- * Drops a packet from the bounce complete queue. +- * +- * Note: this does not drop packets from the NSS queues. +- */ +-static unsigned int nss_codel_drop(struct Qdisc *sch) +-{ +- return nss_qdisc_drop(sch); +-} +- +-/* + * nss_codel_reset() + * Resets nss_codel qdisc. + */ +@@ -234,7 +223,7 @@ static int nss_codel_mem_sz_get(struct Q + * nss_codel_change() + * Used to configure the nss_codel queue in NSS firmware. + */ +-static int nss_codel_change(struct Qdisc *sch, struct nlattr *opt) ++static int nss_codel_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_codel_sched_data *q = qdisc_priv(sch); + struct tc_nsscodel_qopt *qopt; +@@ -381,7 +370,7 @@ fail: + * nss_codel_init() + * Initializes the nss_codel qdisc. + */ +-static int nss_codel_init(struct Qdisc *sch, struct nlattr *opt) ++static int nss_codel_init(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_qdisc *nq = qdisc_priv(sch); + struct tc_nsscodel_qopt *qopt; +@@ -404,7 +393,7 @@ static int nss_codel_init(struct Qdisc * + nss_qdisc_register_configure_callback(nq, nss_codel_configure_callback); + nss_qdisc_register_stats_callback(nq, nss_codel_stats_callback); + +- if (nss_qdisc_init(sch, nq, NSS_SHAPER_NODE_TYPE_CODEL, 0, qopt->accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, nq, NSS_SHAPER_NODE_TYPE_CODEL, 0, qopt->accel_mode) < 0) { + return -EINVAL; + } + +@@ -412,7 +401,7 @@ static int nss_codel_init(struct Qdisc * + return -EINVAL; + } + +- if (nss_codel_change(sch, opt) < 0) { ++ if (nss_codel_change(sch, opt, NULL) < 0) { + nss_qdisc_destroy(nq); + return -EINVAL; + } +@@ -511,7 +500,6 @@ struct Qdisc_ops nss_codel_qdisc_ops __r + .enqueue = nss_codel_enqueue, + .dequeue = nss_codel_dequeue, + .peek = nss_codel_peek, +- .drop = nss_codel_drop, + .init = nss_codel_init, + .reset = nss_codel_reset, + .destroy = nss_codel_destroy, +@@ -530,7 +518,6 @@ struct Qdisc_ops nss_fq_codel_qdisc_ops + .enqueue = nss_codel_enqueue, + .dequeue = nss_codel_dequeue, + .peek = nss_codel_peek, +- .drop = nss_codel_drop, + .init = nss_codel_init, + .reset = nss_codel_reset, + .destroy = nss_codel_destroy, +--- a/nss_qdisc/nss_fifo.c ++++ b/nss_qdisc/nss_fifo.c +@@ -29,7 +29,7 @@ static struct nla_policy nss_fifo_policy + [TCA_NSSFIFO_PARMS] = { .len = sizeof(struct tc_nssfifo_qopt) }, + }; + +-static int nss_fifo_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_fifo_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -39,12 +39,6 @@ static struct sk_buff *nss_fifo_dequeue( + return nss_qdisc_dequeue(sch); + } + +-static unsigned int nss_fifo_drop(struct Qdisc *sch) +-{ +- nss_qdisc_info("nss_fifo dropping"); +- return nss_qdisc_drop(sch); +-} +- + static void nss_fifo_reset(struct Qdisc *sch) + { + nss_qdisc_info("nss_fifo resetting!"); +@@ -158,7 +152,7 @@ fail: + } + #endif + +-static int nss_fifo_change(struct Qdisc *sch, struct nlattr *opt) ++static int nss_fifo_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_fifo_sched_data *q = qdisc_priv(sch); + struct nss_qdisc *nq = &q->nq; +@@ -208,7 +202,7 @@ static int nss_fifo_change(struct Qdisc + return 0; + } + +-static int nss_fifo_init(struct Qdisc *sch, struct nlattr *opt) ++static int nss_fifo_init(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_qdisc *nq = qdisc_priv(sch); + struct tc_nssfifo_qopt *qopt; +@@ -226,13 +220,13 @@ static int nss_fifo_init(struct Qdisc *s + return -EINVAL; + } + +- if (nss_qdisc_init(sch, nq, NSS_SHAPER_NODE_TYPE_FIFO, 0, qopt->accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, nq, NSS_SHAPER_NODE_TYPE_FIFO, 0, qopt->accel_mode) < 0) { + nss_qdisc_warning("Fifo %x init failed", sch->handle); + return -EINVAL; + } + + nss_qdisc_info("NSS fifo initialized - handle %x parent %x\n", sch->handle, sch->parent); +- if (nss_fifo_change(sch, opt) < 0) { ++ if (nss_fifo_change(sch, opt, NULL) < 0) { + nss_qdisc_destroy(nq); + return -EINVAL; + } +@@ -290,7 +284,6 @@ struct Qdisc_ops nss_pfifo_qdisc_ops __r + .enqueue = nss_fifo_enqueue, + .dequeue = nss_fifo_dequeue, + .peek = nss_fifo_peek, +- .drop = nss_fifo_drop, + .init = nss_fifo_init, + .reset = nss_fifo_reset, + .destroy = nss_fifo_destroy, +@@ -305,7 +298,6 @@ struct Qdisc_ops nss_bfifo_qdisc_ops __r + .enqueue = nss_fifo_enqueue, + .dequeue = nss_fifo_dequeue, + .peek = nss_fifo_peek, +- .drop = nss_fifo_drop, + .init = nss_fifo_init, + .reset = nss_fifo_reset, + .destroy = nss_fifo_destroy, +--- a/nss_qdisc/nss_htb.c ++++ b/nss_qdisc/nss_htb.c +@@ -267,7 +267,7 @@ static int nss_htb_ppe_change_class(stru + * Configures a new class. + */ + static int nss_htb_change_class(struct Qdisc *sch, u32 classid, u32 parentid, +- struct nlattr **tca, unsigned long *arg) ++ struct nlattr **tca, unsigned long *arg, struct netlink_ext_ack *extack) + { + struct nss_htb_sched_data *q = qdisc_priv(sch); + struct nss_htb_class_data *cl = (struct nss_htb_class_data *)*arg; +@@ -332,7 +332,7 @@ static int nss_htb_change_class(struct Q + * here. + */ + cl->nq.parent = nq_parent; +- if (nss_qdisc_init(sch, &cl->nq, NSS_SHAPER_NODE_TYPE_HTB_GROUP, classid, accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, &cl->nq, NSS_SHAPER_NODE_TYPE_HTB_GROUP, classid, accel_mode) < 0) { + nss_qdisc_error("nss_init for htb class %x failed\n", classid); + goto failure; + } +@@ -478,7 +478,7 @@ static void nss_htb_destroy_class(struct + /* + * And now we destroy the child. + */ +- qdisc_destroy(cl->qdisc); ++ qdisc_put(cl->qdisc); + + /* + * Stop the stats polling timer and free class +@@ -577,7 +577,8 @@ static int nss_htb_delete_class(struct Q + * nss_htb_graft_class() + * Replaces the qdisc attached to the provided class. + */ +-static int nss_htb_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) ++static int nss_htb_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old, ++ struct netlink_ext_ack *extack) + { + struct nss_htb_class_data *cl = (struct nss_htb_class_data *)arg; + struct nss_if_msg nim_detach; +@@ -682,25 +683,6 @@ static unsigned long nss_htb_get_class(s + } + + /* +- * nss_htb_put_class() +- * Reduces reference count for this class. +- */ +-static void nss_htb_put_class(struct Qdisc *sch, unsigned long arg) +-{ +- struct nss_htb_class_data *cl = (struct nss_htb_class_data *)arg; +- nss_qdisc_trace("executing put on htb class %x in qdisc %x\n", +- cl->nq.qos_tag, sch->handle); +- +- /* +- * We are safe to destroy the qdisc if the reference count +- * goes down to 0. +- */ +- if (atomic_sub_return(1, &cl->nq.refcnt) == 0) { +- nss_htb_destroy_class(sch, cl); +- } +-} +- +-/* + * nss_htb_dump_class() + * Dumps all configurable parameters pertaining to this class. + */ +@@ -795,7 +777,7 @@ static void nss_htb_walk(struct Qdisc *s + * nss_htb_change_qdisc() + * Can be used to configure a htb qdisc. + */ +-static int nss_htb_change_qdisc(struct Qdisc *sch, struct nlattr *opt) ++static int nss_htb_change_qdisc(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_htb_sched_data *q = qdisc_priv(sch); + struct tc_nsshtb_qopt *qopt; +@@ -945,7 +927,7 @@ static void nss_htb_destroy_qdisc(struct + * nss_htb_init_qdisc() + * Initializes the htb qdisc. + */ +-static int nss_htb_init_qdisc(struct Qdisc *sch, struct nlattr *opt) ++static int nss_htb_init_qdisc(struct Qdisc *sch, struct nlattr *opt,struct netlink_ext_ack *extack) + { + struct nss_htb_sched_data *q = qdisc_priv(sch); + struct tc_nsshtb_qopt *qopt; +@@ -977,7 +959,7 @@ static int nss_htb_init_qdisc(struct Qdi + /* + * Initialize the NSSHTB shaper in NSS + */ +- if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_HTB, 0, accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, &q->nq, NSS_SHAPER_NODE_TYPE_HTB, 0, accel_mode) < 0) { + nss_qdisc_error("failed to initialize htb qdisc %x in nss", sch->handle); + return -EINVAL; + } +@@ -987,7 +969,7 @@ static int nss_htb_init_qdisc(struct Qdi + /* + * Tune HTB parameters + */ +- if (nss_htb_change_qdisc(sch, opt) < 0) { ++ if (nss_htb_change_qdisc(sch, opt, NULL) < 0) { + nss_qdisc_destroy(&q->nq); + return -EINVAL; + } +@@ -1032,7 +1014,7 @@ static int nss_htb_dump_qdisc(struct Qdi + * nss_htb_enqueue() + * Enqueues a skb to htb qdisc. + */ +-static int nss_htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_htb_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -1047,18 +1029,6 @@ static struct sk_buff *nss_htb_dequeue(s + } + + /* +- * nss_htb_drop() +- * Drops a single skb from linux queue, if not empty. +- * +- * Does not drop packets that are queued in the NSS. +- */ +-static unsigned int nss_htb_drop(struct Qdisc *sch) +-{ +- nss_qdisc_trace("drop called on htb qdisc %x\n", sch->handle); +- return nss_qdisc_drop(sch); +-} +- +-/* + * Registration structure for htb class + */ + const struct Qdisc_class_ops nss_htb_class_ops = { +@@ -1067,9 +1037,8 @@ const struct Qdisc_class_ops nss_htb_cla + .graft = nss_htb_graft_class, + .leaf = nss_htb_leaf_class, + .qlen_notify = nss_htb_qlen_notify, +- .get = nss_htb_get_class, +- .put = nss_htb_put_class, ++ .find = nss_htb_get_class, + .dump = nss_htb_dump_class, + .dump_stats = nss_htb_dump_class_stats, + .walk = nss_htb_walk + }; +@@ -1090,7 +1058,6 @@ struct Qdisc_ops nss_htb_qdisc_ops __rea + .enqueue = nss_htb_enqueue, + .dequeue = nss_htb_dequeue, + .peek = qdisc_peek_dequeued, +- .drop = nss_htb_drop, + .cl_ops = &nss_htb_class_ops, + .priv_size = sizeof(struct nss_htb_sched_data), + .owner = THIS_MODULE +--- a/nss_qdisc/nss_prio.c ++++ b/nss_qdisc/nss_prio.c +@@ -37,7 +37,7 @@ static struct nla_policy nss_prio_policy + * nss_prio_enqueue() + * Enqueues a skb to nssprio qdisc. + */ +-static int nss_prio_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_prio_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -52,17 +52,6 @@ static struct sk_buff *nss_prio_dequeue( + } + + /* +- * nss_prio_drop() +- * Drops a single skb from linux queue, if not empty. +- * +- * Does not drop packets that are queued in the NSS. +- */ +-static unsigned int nss_prio_drop(struct Qdisc *sch) +-{ +- return nss_qdisc_drop(sch); +-} +- +-/* + * nss_prio_peek() + * Peeks the first packet in queue for this qdisc. + */ +@@ -117,7 +106,7 @@ static void nss_prio_destroy(struct Qdis + /* + * We can now destroy it + */ +- qdisc_destroy(q->queues[i]); ++ qdisc_put(q->queues[i]); + } + + /* +@@ -157,7 +146,7 @@ static int nss_prio_get_max_bands(struct + * nss_prio_change() + * Function call to configure the nssprio parameters + */ +-static int nss_prio_change(struct Qdisc *sch, struct nlattr *opt) ++static int nss_prio_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_prio_sched_data *q; + struct tc_nssprio_qopt *qopt; +@@ -209,7 +198,7 @@ static int nss_prio_change(struct Qdisc + * nss_prio_init() + * Initializes the nssprio qdisc + */ +-static int nss_prio_init(struct Qdisc *sch, struct nlattr *opt) ++static int nss_prio_init(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_prio_sched_data *q = qdisc_priv(sch); + struct tc_nssprio_qopt *qopt; +@@ -230,14 +219,14 @@ static int nss_prio_init(struct Qdisc *s + accel_mode = qopt->accel_mode; + } + +- if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_PRIO, 0, accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, &q->nq, NSS_SHAPER_NODE_TYPE_PRIO, 0, accel_mode) < 0) { + return -EINVAL; + } + + nss_qdisc_info("Nssprio initialized - handle %x parent %x\n", + sch->handle, sch->parent); + +- if (nss_prio_change(sch, opt) < 0) { ++ if (nss_prio_change(sch, opt, NULL) < 0) { + nss_qdisc_destroy(&q->nq); + return -EINVAL; + } +@@ -280,7 +269,7 @@ nla_put_failure: + * Replaces existing child qdisc with the new qdisc that is passed. + */ + static int nss_prio_graft(struct Qdisc *sch, unsigned long arg, +- struct Qdisc *new, struct Qdisc **old) ++ struct Qdisc *new, struct Qdisc **old, struct netlink_ext_ack *extack) + { + struct nss_prio_sched_data *q = qdisc_priv(sch); + struct nss_qdisc *nq_new = qdisc_priv(new); +@@ -383,15 +372,6 @@ static unsigned long nss_prio_get(struct + } + + /* +- * nss_prio_put() +- * Unused API. +- */ +-static void nss_prio_put(struct Qdisc *sch, unsigned long arg) +-{ +- nss_qdisc_info("Inside prio put\n"); +-} +- +-/* + * nss_prio_walk() + * Walks the priority band. + */ +@@ -460,9 +440,8 @@ static int nss_prio_dump_class_stats(str + const struct Qdisc_class_ops nss_prio_class_ops = { + .graft = nss_prio_graft, + .leaf = nss_prio_leaf, +- .get = nss_prio_get, +- .put = nss_prio_put, ++ .find = nss_prio_get, + .walk = nss_prio_walk, + .dump = nss_prio_dump_class, + .dump_stats = nss_prio_dump_class_stats, + }; +@@ -481,7 +459,6 @@ struct Qdisc_ops nss_prio_qdisc_ops __re + .enqueue = nss_prio_enqueue, + .dequeue = nss_prio_dequeue, + .peek = nss_prio_peek, +- .drop = nss_prio_drop, + .init = nss_prio_init, + .reset = nss_prio_reset, + .destroy = nss_prio_destroy, +--- a/nss_qdisc/nss_qdisc.c ++++ b/nss_qdisc/nss_qdisc.c +@@ -929,7 +929,7 @@ static inline void nss_qdisc_add_to_tail + * We do not use the qdisc_enqueue_tail() API here in order + * to prevent stats from getting updated by the API. + */ +- __skb_queue_tail(&sch->q, skb); ++ __qdisc_enqueue_tail(skb, &sch->q); + + spin_unlock_bh(&nq->bounce_protection_lock); + }; +@@ -944,7 +944,7 @@ static inline void nss_qdisc_add_to_tail + * We do not use the qdisc_enqueue_tail() API here in order + * to prevent stats from getting updated by the API. + */ +- __skb_queue_tail(&sch->q, skb); ++ __qdisc_enqueue_tail(skb, &sch->q); + }; + + /* +@@ -966,7 +966,7 @@ static inline struct sk_buff *nss_qdisc_ + * We use __skb_dequeue() to ensure that + * stats don't get updated twice. + */ +- skb = __skb_dequeue(&sch->q); ++ skb = __qdisc_dequeue_head(&sch->q); + + spin_unlock_bh(&nq->bounce_protection_lock); + +@@ -983,7 +983,7 @@ static inline struct sk_buff *nss_qdisc_ + * We use __skb_dequeue() to ensure that + * stats don't get updated twice. + */ +- return __skb_dequeue(&sch->q); ++ return __qdisc_dequeue_head(&sch->q); + }; + + /* +@@ -1064,14 +1064,19 @@ struct Qdisc *nss_qdisc_replace(struct Q + void *nss_qdisc_qopt_get(struct nlattr *opt, struct nla_policy *policy, + uint32_t tca_max, uint32_t tca_params) + { +- struct nlattr *na[tca_max + 1]; ++ struct nlattr *na[8]; + int err; + ++ if (tca_max > 8) { ++ pr_warn("nss_qdisc_qopt_get(): Too many options!\n"); ++ return NULL; ++ } ++ + if (!opt) { + return NULL; + } + +- err = nla_parse_nested(na, tca_max, opt, policy); ++ err = nla_parse_nested_deprecated(na, tca_max, opt, policy, NULL); + if (err < 0) + return NULL; + +@@ -1104,10 +1109,10 @@ struct sk_buff *nss_qdisc_peek(struct Qd + struct sk_buff *skb; + + if (!nq->is_virtual) { +- skb = skb_peek(&sch->q); ++ skb = qdisc_peek_head(sch); + } else { + spin_lock_bh(&nq->bounce_protection_lock); +- skb = skb_peek(&sch->q); ++ skb = qdisc_peek_head(sch); + spin_unlock_bh(&nq->bounce_protection_lock); + } + +@@ -1122,15 +1127,16 @@ unsigned int nss_qdisc_drop(struct Qdisc + { + struct nss_qdisc *nq = qdisc_priv(sch); + unsigned int ret; ++ struct sk_buff *to_free = qdisc_peek_head(sch); + + if (!nq->is_virtual) { +- ret = __qdisc_queue_drop_head(sch, &sch->q); ++ ret = __qdisc_queue_drop_head(sch, &sch->q, &to_free); + } else { + spin_lock_bh(&nq->bounce_protection_lock); + /* + * This function is safe to call within locks + */ +- ret = __qdisc_queue_drop_head(sch, &sch->q); ++ ret = __qdisc_queue_drop_head(sch, &sch->q, &to_free); + spin_unlock_bh(&nq->bounce_protection_lock); + } + +@@ -1958,7 +1964,7 @@ void nss_qdisc_destroy(struct nss_qdisc + * Initializes a shaper in NSS, based on the position of this qdisc (child or root) + * and if its a normal interface or a bridge interface. + */ +-int nss_qdisc_init(struct Qdisc *sch, struct nss_qdisc *nq, nss_shaper_node_type_t type, uint32_t classid, uint32_t accel_mode) ++int nss_qdisc_init(struct Qdisc *sch, struct netlink_ext_ack *extack, struct nss_qdisc *nq, nss_shaper_node_type_t type, uint32_t classid, uint32_t accel_mode) + { + struct Qdisc *root; + u32 parent; +@@ -2471,6 +2481,8 @@ static void nss_qdisc_basic_stats_callba + struct gnet_stats_queue *qstats; + struct nss_shaper_node_stats_response *response; + atomic_t *refcnt; ++ refcount_t *refcnt_new; ++ bool is_refcnt_zero = false; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_qdisc_warning("Qdisc %p (type %d): Receive stats FAILED - " +@@ -2494,7 +2506,7 @@ static void nss_qdisc_basic_stats_callba + } else { + bstats = &qdisc->bstats; + qstats = &qdisc->qstats; +- refcnt = &qdisc->refcnt; ++ refcnt_new = &qdisc->refcnt; + qdisc->q.qlen = response->sn_stats.qlen_packets; + } + +@@ -2533,11 +2545,20 @@ static void nss_qdisc_basic_stats_callba + * All access to nq fields below do not need lock protection. They + * do not get manipulated on different thread contexts. + */ +- if (atomic_read(refcnt) == 0) { ++ if (nq->is_class) { ++ if (atomic_read(refcnt) == 0) ++ is_refcnt_zero = true; ++ } ++ else { ++ if (refcount_read(refcnt_new) == 0) ++ is_refcnt_zero = true; ++ } ++ if (is_refcnt_zero) { + atomic_sub(1, &nq->pending_stat_requests); + wake_up(&nq->wait_queue); + return; + } ++ + + /* + * Requests for stats again, after 1 sec. +@@ -2555,9 +2576,9 @@ static void nss_qdisc_basic_stats_callba + * nss_qdisc_get_stats_timer_callback() + * Invoked periodically to get updated stats + */ +-static void nss_qdisc_get_stats_timer_callback(unsigned long int data) ++static void nss_qdisc_get_stats_timer_callback(struct timer_list *arg) + { +- struct nss_qdisc *nq = (struct nss_qdisc *)data; ++ struct nss_qdisc *nq = (struct nss_qdisc *)arg->cust_data; + nss_tx_status_t rc; + struct nss_if_msg nim; + int msg_type; +@@ -2604,9 +2625,8 @@ void nss_qdisc_start_basic_stats_polling + return; + } + +- init_timer(&nq->stats_get_timer); +- nq->stats_get_timer.function = nss_qdisc_get_stats_timer_callback; +- nq->stats_get_timer.data = (unsigned long)nq; ++ timer_setup(&nq->stats_get_timer, nss_qdisc_get_stats_timer_callback, 0); ++ nq->stats_get_timer.cust_data = (unsigned long)nq; + nq->stats_get_timer.expires = jiffies + HZ; + atomic_set(&nq->pending_stat_requests, 1); + add_timer(&nq->stats_get_timer); +@@ -2650,7 +2670,7 @@ int nss_qdisc_gnet_stats_copy_basic(stru + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 18, 0)) + return gnet_stats_copy_basic(d, b); + #else +- return gnet_stats_copy_basic(d, NULL, b); ++ return gnet_stats_copy_basic(NULL, d, NULL, b); + #endif + } + +--- a/nss_qdisc/nss_tbl.c ++++ b/nss_qdisc/nss_tbl.c +@@ -29,7 +29,7 @@ static struct nla_policy nss_tbl_policy[ + [TCA_NSSTBL_PARMS] = { .len = sizeof(struct tc_nsstbl_qopt) }, + }; + +-static int nss_tbl_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_tbl_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -39,11 +39,6 @@ static struct sk_buff *nss_tbl_dequeue(s + return nss_qdisc_dequeue(sch); + } + +-static unsigned int nss_tbl_drop(struct Qdisc *sch) +-{ +- return nss_qdisc_drop(sch); +-} +- + static struct sk_buff *nss_tbl_peek(struct Qdisc *sch) + { + return nss_qdisc_peek(sch); +@@ -77,7 +72,7 @@ static void nss_tbl_destroy(struct Qdisc + /* + * Now we can destroy our child qdisc + */ +- qdisc_destroy(q->qdisc); ++ qdisc_put(q->qdisc); + + /* + * Stop the polling of basic stats and destroy qdisc. +@@ -132,7 +127,7 @@ fail: + } + #endif + +-static int nss_tbl_change(struct Qdisc *sch, struct nlattr *opt) ++static int nss_tbl_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_tbl_sched_data *q = qdisc_priv(sch); + struct tc_nsstbl_qopt *qopt; +@@ -216,7 +211,7 @@ static int nss_tbl_change(struct Qdisc * + return 0; + } + +-static int nss_tbl_init(struct Qdisc *sch, struct nlattr *opt) ++static int nss_tbl_init(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_tbl_sched_data *q = qdisc_priv(sch); + struct tc_nsstbl_qopt *qopt; +@@ -232,10 +227,10 @@ static int nss_tbl_init(struct Qdisc *sc + return -EINVAL; + } + +- if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_TBL, 0, qopt->accel_mode) < 0) ++ if (nss_qdisc_init(sch, extack, &q->nq, NSS_SHAPER_NODE_TYPE_TBL, 0, qopt->accel_mode) < 0) + return -EINVAL; + +- if (nss_tbl_change(sch, opt) < 0) { ++ if (nss_tbl_change(sch, opt, NULL) < 0) { + nss_qdisc_info("Failed to configure tbl\n"); + nss_qdisc_destroy(&q->nq); + return -EINVAL; +@@ -287,7 +282,7 @@ static int nss_tbl_dump_class(struct Qdi + } + + static int nss_tbl_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, +- struct Qdisc **old) ++ struct Qdisc **old, struct netlink_ext_ack *extack) + { + struct nss_tbl_sched_data *q = qdisc_priv(sch); + struct nss_qdisc *nq_new = (struct nss_qdisc *)qdisc_priv(new); +@@ -344,10 +339,6 @@ static unsigned long nss_tbl_get(struct + return 1; + } + +-static void nss_tbl_put(struct Qdisc *sch, unsigned long arg) +-{ +-} +- + static void nss_tbl_walk(struct Qdisc *sch, struct qdisc_walker *walker) + { + nss_qdisc_info("Nsstbl walk called"); +@@ -364,9 +355,8 @@ static void nss_tbl_walk(struct Qdisc *s + const struct Qdisc_class_ops nss_tbl_class_ops = { + .graft = nss_tbl_graft, + .leaf = nss_tbl_leaf, +- .get = nss_tbl_get, +- .put = nss_tbl_put, ++ .find = nss_tbl_get, + .walk = nss_tbl_walk, + .dump = nss_tbl_dump_class, + }; + +@@ -381,7 +370,6 @@ struct Qdisc_ops nss_tbl_qdisc_ops __rea + .enqueue = nss_tbl_enqueue, + .dequeue = nss_tbl_dequeue, + .peek = nss_tbl_peek, +- .drop = nss_tbl_drop, + .init = nss_tbl_init, + .reset = nss_tbl_reset, + .destroy = nss_tbl_destroy, +--- a/nss_qdisc/nss_wred.c ++++ b/nss_qdisc/nss_wred.c +@@ -55,7 +55,7 @@ static struct nla_policy nss_wred_policy + * nss_wred_enqueue() + * Enqueue API for nsswred qdisc + */ +-static int nss_wred_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_wred_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -70,16 +70,6 @@ static struct sk_buff *nss_wred_dequeue( + } + + /* +- * nss_wred_drop() +- * Drops a packet from HLOS queue. +- */ +-static unsigned int nss_wred_drop(struct Qdisc *sch) +-{ +- nss_qdisc_info("nsswred dropping"); +- return nss_qdisc_drop(sch); +-} +- +-/* + * nss_wred_reset() + * Reset the nsswred qdisc + */ +@@ -171,7 +161,7 @@ fail: + * nss_wred_change() + * Function call to configure the nsswred parameters + */ +-static int nss_wred_change(struct Qdisc *sch, struct nlattr *opt) ++static int nss_wred_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_wred_sched_data *q = qdisc_priv(sch); + struct tc_nsswred_qopt *qopt; +@@ -298,7 +288,7 @@ static int nss_wred_change(struct Qdisc + * nss_wred_init() + * Init the nsswred qdisc + */ +-static int nss_wred_init(struct Qdisc *sch, struct nlattr *opt) ++static int nss_wred_init(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_qdisc *nq = qdisc_priv(sch); + struct tc_nsswred_qopt *qopt; +@@ -315,11 +305,11 @@ static int nss_wred_init(struct Qdisc *s + nss_qdisc_info("Initializing Wred - type %d\n", NSS_SHAPER_NODE_TYPE_WRED); + nss_wred_reset(sch); + +- if (nss_qdisc_init(sch, nq, NSS_SHAPER_NODE_TYPE_WRED, 0, qopt->accel_mode) < 0) ++ if (nss_qdisc_init(sch, extack, nq, NSS_SHAPER_NODE_TYPE_WRED, 0, qopt->accel_mode) < 0) + return -EINVAL; + + nss_qdisc_info("NSS wred initialized - handle %x parent %x\n", sch->handle, sch->parent); +- if (nss_wred_change(sch, opt) < 0) { ++ if (nss_wred_change(sch, opt, NULL) < 0) { + nss_qdisc_destroy(nq); + return -EINVAL; + } +@@ -405,7 +395,6 @@ struct Qdisc_ops nss_red_qdisc_ops __rea + .enqueue = nss_wred_enqueue, + .dequeue = nss_wred_dequeue, + .peek = nss_wred_peek, +- .drop = nss_wred_drop, + .init = nss_wred_init, + .reset = nss_wred_reset, + .destroy = nss_wred_destroy, +@@ -423,7 +412,6 @@ struct Qdisc_ops nss_wred_qdisc_ops __re + .enqueue = nss_wred_enqueue, + .dequeue = nss_wred_dequeue, + .peek = nss_wred_peek, +- .drop = nss_wred_drop, + .init = nss_wred_init, + .reset = nss_wred_reset, + .destroy = nss_wred_destroy, +--- a/nss_qdisc/nss_wrr.c ++++ b/nss_qdisc/nss_wrr.c +@@ -84,7 +84,7 @@ static void nss_wrr_destroy_class(struct + /* + * And now we destroy the child. + */ +- qdisc_destroy(cl->qdisc); ++ qdisc_put(cl->qdisc); + + /* + * Stop the stats polling timer and free class +@@ -219,7 +219,7 @@ static int nss_wrr_ppe_change_class(stru + #endif + + static int nss_wrr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, +- struct nlattr **tca, unsigned long *arg) ++ struct nlattr **tca, unsigned long *arg, struct netlink_ext_ack *extack) + { + struct nss_wrr_sched_data *q = qdisc_priv(sch); + struct nss_wrr_class_data *cl = (struct nss_wrr_class_data *)*arg; +@@ -286,7 +286,7 @@ static int nss_wrr_change_class(struct Q + * here. + */ + cl->nq.parent = &q->nq; +- if (nss_qdisc_init(sch, &cl->nq, NSS_SHAPER_NODE_TYPE_WRR_GROUP, classid, accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, &cl->nq, NSS_SHAPER_NODE_TYPE_WRR_GROUP, classid, accel_mode) < 0) { + nss_qdisc_error("Nss init for class %u failed\n", classid); + return -EINVAL; + } +@@ -422,7 +422,7 @@ static int nss_wrr_delete_class(struct Q + } + + static int nss_wrr_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, +- struct Qdisc **old) ++ struct Qdisc **old, struct netlink_ext_ack *extack) + { + struct nss_wrr_sched_data *q = qdisc_priv(sch); + struct nss_wrr_class_data *cl = (struct nss_wrr_class_data *)arg; +@@ -517,20 +517,6 @@ static unsigned long nss_wrr_get_class(s + return (unsigned long)cl; + } + +-static void nss_wrr_put_class(struct Qdisc *sch, unsigned long arg) +-{ +- struct nss_wrr_class_data *cl = (struct nss_wrr_class_data *)arg; +- nss_qdisc_info("nss_wrr put class for %p\n", cl); +- +- /* +- * We are safe to destroy the qdisc if the reference count +- * goes down to 0. +- */ +- if (atomic_sub_return(1, &cl->nq.refcnt) == 0) { +- nss_wrr_destroy_class(sch, cl); +- } +-} +- + static int nss_wrr_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, + struct tcmsg *tcm) + { +@@ -600,7 +586,7 @@ static void nss_wrr_walk(struct Qdisc *s + } + } + +-static int nss_wrr_init_qdisc(struct Qdisc *sch, struct nlattr *opt) ++static int nss_wrr_init_qdisc(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_wrr_sched_data *q = qdisc_priv(sch); + int err; +@@ -629,7 +615,7 @@ static int nss_wrr_init_qdisc(struct Qdi + /* + * Initialize the NSSWRR shaper in NSS + */ +- if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_WRR, 0, qopt->accel_mode) < 0) { ++ if (nss_qdisc_init(sch, extack, &q->nq, NSS_SHAPER_NODE_TYPE_WRR, 0, qopt->accel_mode) < 0) { + nss_qdisc_warning("Failed init nss_wrr qdisc"); + return -EINVAL; + } +@@ -669,7 +655,7 @@ static int nss_wrr_init_qdisc(struct Qdi + return 0; + } + +-static int nss_wrr_change_qdisc(struct Qdisc *sch, struct nlattr *opt) ++static int nss_wrr_change_qdisc(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) + { + struct nss_wrr_sched_data *q; + struct tc_nsswrr_qopt *qopt; +@@ -809,7 +795,7 @@ nla_put_failure: + return -EMSGSIZE; + } + +-static int nss_wrr_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++static int nss_wrr_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + { + return nss_qdisc_enqueue(skb, sch); + } +@@ -819,21 +805,14 @@ static struct sk_buff *nss_wrr_dequeue(s + return nss_qdisc_dequeue(sch); + } + +-static unsigned int nss_wrr_drop(struct Qdisc *sch) +-{ +- nss_qdisc_info("Nsswrr drop\n"); +- return nss_qdisc_drop(sch); +-} +- + const struct Qdisc_class_ops nss_wrr_class_ops = { + .change = nss_wrr_change_class, + .delete = nss_wrr_delete_class, + .graft = nss_wrr_graft_class, + .leaf = nss_wrr_leaf_class, + .qlen_notify = nss_wrr_qlen_notify, +- .get = nss_wrr_get_class, +- .put = nss_wrr_put_class, ++ .find = nss_wrr_get_class, + .dump = nss_wrr_dump_class, + .dump_stats = nss_wrr_dump_class_stats, + .walk = nss_bf_walk + }; +@@ -851,7 +829,6 @@ struct Qdisc_ops nss_wrr_qdisc_ops __rea + .enqueue = nss_wrr_enqueue, + .dequeue = nss_wrr_dequeue, + .peek = qdisc_peek_dequeued, +- .drop = nss_wrr_drop, + .cl_ops = &nss_wrr_class_ops, + .priv_size = sizeof(struct nss_wrr_sched_data), + .owner = THIS_MODULE +@@ -863,9 +840,8 @@ const struct Qdisc_class_ops nss_wfq_cla + .graft = nss_wrr_graft_class, + .leaf = nss_wrr_leaf_class, + .qlen_notify = nss_wrr_qlen_notify, +- .get = nss_wrr_get_class, +- .put = nss_wrr_put_class, ++ .find = nss_wrr_get_class, + .dump = nss_wrr_dump_class, + .dump_stats = nss_wrr_dump_class_stats, + .walk = nss_wrr_walk + }; +@@ -883,7 +858,6 @@ struct Qdisc_ops nss_wfq_qdisc_ops __rea + .enqueue = nss_wrr_enqueue, + .dequeue = nss_wrr_dequeue, + .peek = qdisc_peek_dequeued, +- .drop = nss_wrr_drop, + .cl_ops = &nss_wrr_class_ops, + .priv_size = sizeof(struct nss_wrr_sched_data), + .owner = THIS_MODULE diff --git a/root/package/firmware/nss/qca-nss-clients/patches/101-kernel-5.4-support-gre.patch b/root/package/firmware/nss/qca-nss-clients/patches/101-kernel-5.4-support-gre.patch new file mode 100644 index 00000000..705ceabe --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/patches/101-kernel-5.4-support-gre.patch @@ -0,0 +1,106 @@ +From 7c89187ab2d165ccffed627742e7cb72cce375ef Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 12 Jul 2020 22:49:30 +0200 +Subject: [PATCH] kernel-5.4-support-gre + +--- + gre/nss_connmgr_gre.c | 16 +++++++--------- + gre/nss_connmgr_gre_v6.c | 4 ++-- + 2 files changed, 9 insertions(+), 11 deletions(-) + +diff --git a/gre/nss_connmgr_gre.c b/gre/nss_connmgr_gre.c +index 52203b1..6de8f6e 100644 +--- a/gre/nss_connmgr_gre.c ++++ b/gre/nss_connmgr_gre.c +@@ -88,7 +88,7 @@ static int nss_connmgr_gre_dev_init(struct net_device *dev) + u64_stats_init(&stats->syncp); + } + +- if ((dev->priv_flags & IFF_GRE_V4_TAP) || (dev->type == ARPHRD_IPGRE)) { ++ if ((dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V4_TAP) || (dev->type == ARPHRD_IPGRE)) { + dev->needed_headroom = sizeof(struct iphdr) + sizeof(struct ethhdr) + MAX_WIFI_HEADROOM + append; + dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - append; + dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA; +@@ -169,7 +169,7 @@ fail: + * nss_connmgr_gre_dev_stats64() + * Netdev ops function to retrieve stats. + */ +-struct rtnl_link_stats64 *nss_connmgr_gre_dev_stats64(struct net_device *dev, ++void nss_connmgr_gre_dev_stats64(struct net_device *dev, + struct rtnl_link_stats64 *tot) + { + uint64_t rx_packets, rx_bytes, tx_packets, tx_bytes; +@@ -202,8 +202,6 @@ struct rtnl_link_stats64 *nss_connmgr_gre_dev_stats64(struct net_device *dev, + tot->rx_dropped = dev->stats.rx_dropped; + tot->tx_dropped = dev->stats.tx_dropped; + } +- +- return tot; + } + + /* +@@ -390,7 +388,7 @@ static int32_t nss_connmgr_gre_prepare_config_cmd(struct net_device *dev, + { + struct nss_gre_config_msg *cmsg = &req->msg.cmsg; + +- if ((dev->type == ARPHRD_ETHER) && (dev->priv_flags & IFF_GRE_V4_TAP)) { ++ if ((dev->type == ARPHRD_ETHER) && (dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V4_TAP)) { + cmsg->mode = NSS_GRE_MODE_TAP; + cmsg->ip_type = NSS_GRE_IP_IPV4; + if (enable_unalign) { +@@ -399,7 +397,7 @@ static int32_t nss_connmgr_gre_prepare_config_cmd(struct net_device *dev, + return nss_connmgr_gre_v4_get_config(dev, req, next_dev, hold); + } + +- if ((dev->type == ARPHRD_ETHER) && (dev->priv_flags & IFF_GRE_V6_TAP)) { ++ if ((dev->type == ARPHRD_ETHER) && (dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V6_TAP)) { + cmsg->mode = NSS_GRE_MODE_TAP; + cmsg->ip_type = NSS_GRE_IP_IPV6; + if (enable_unalign) { +@@ -605,7 +603,7 @@ static bool nss_connmgr_gre_is_gre(struct net_device *dev) + { + if ((dev->type == ARPHRD_IPGRE) || + (dev->type == ARPHRD_IP6GRE) || ((dev->type == ARPHRD_ETHER) && +- (dev->priv_flags & (IFF_GRE_V4_TAP | IFF_GRE_V6_TAP)))) { ++ (dev->priv_flags_qca_ecm & (IFF_QCA_ECM_GRE_V4_TAP | IFF_QCA_ECM_GRE_V6_TAP)))) { + return true; + } + +@@ -692,10 +690,10 @@ static struct net_device *__nss_connmgr_gre_create_interface(struct nss_connmgr_ + nss_connmgr_gre_tap_setup(dev); + + if (cfg->is_ipv6) { +- dev->priv_flags |= IFF_GRE_V6_TAP; ++ dev->priv_flags_qca_ecm |= IFF_QCA_ECM_GRE_V6_TAP; + ret = nss_connmgr_gre_v6_set_config(dev, cfg); + } else { +- dev->priv_flags |= IFF_GRE_V4_TAP; ++ dev->priv_flags_qca_ecm |= IFF_QCA_ECM_GRE_V4_TAP; + ret = nss_connmgr_gre_v4_set_config(dev, cfg); + } + break; +diff --git a/gre/nss_connmgr_gre_v6.c b/gre/nss_connmgr_gre_v6.c +index f9a8e58..e93c7e4 100644 +--- a/gre/nss_connmgr_gre_v6.c ++++ b/gre/nss_connmgr_gre_v6.c +@@ -46,7 +46,7 @@ static struct net_device *nss_connmgr_gre_v6_get_tx_dev(uint8_t *dest_ip) + struct net_device *dev; + + memcpy(ipv6_addr.s6_addr, dest_ip, 16); +- rt = rt6_lookup(&init_net, &ipv6_addr, NULL, 0, 0); ++ rt = rt6_lookup(&init_net, &ipv6_addr, NULL, 0, NULL, 0); + if (!rt) { + return NULL; + } +@@ -92,7 +92,7 @@ static int nss_connmgr_gre_v6_get_mac_address(uint8_t *src_ip, uint8_t *dest_ip, + * Find dest MAC address + */ + memcpy(ipv6_addr.s6_addr, dest_ip, 16); +- rt = rt6_lookup(&init_net, &ipv6_addr, NULL, 0, 0); ++ rt = rt6_lookup(&init_net, &ipv6_addr, NULL, 0, NULL, 0); + if (!rt) { + return GRE_ERR_NEIGH_LOOKUP; + } +-- +2.27.0 + diff --git a/root/package/firmware/nss/qca-nss-clients/patches/102-kernel-5.4-support-ipsec.patch b/root/package/firmware/nss/qca-nss-clients/patches/102-kernel-5.4-support-ipsec.patch new file mode 100644 index 00000000..de43b4d0 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/patches/102-kernel-5.4-support-ipsec.patch @@ -0,0 +1,29 @@ +--- a/ipsecmgr/v1.0/nss_ipsecmgr.c ++++ b/ipsecmgr/v1.0/nss_ipsecmgr.c +@@ -377,7 +377,7 @@ free: + * nss_ipsecmgr_tunnel_stats() + * get tunnel statistics + */ +-static struct rtnl_link_stats64 *nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) ++void nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + { + struct nss_ipsecmgr_priv *priv = netdev_priv(dev); + +@@ -389,8 +389,6 @@ static struct rtnl_link_stats64 *nss_ips + read_lock_bh(&ipsecmgr_ctx->lock); + memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64)); + read_unlock_bh(&ipsecmgr_ctx->lock); +- +- return stats; + } + + /* +@@ -442,7 +440,7 @@ static void nss_ipsecmgr_tunnel_setup(st + dev->header_ops = NULL; + dev->netdev_ops = &nss_ipsecmgr_tunnel_ops; + +- dev->destructor = nss_ipsecmgr_tunnel_free; ++ dev->priv_destructor = nss_ipsecmgr_tunnel_free; + + /* + * get the MAC address from the ethernet device diff --git a/root/package/firmware/nss/qca-nss-clients/patches/103-kernel-5.4-support-dtls.patch b/root/package/firmware/nss/qca-nss-clients/patches/103-kernel-5.4-support-dtls.patch new file mode 100644 index 00000000..ae9c9147 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/patches/103-kernel-5.4-support-dtls.patch @@ -0,0 +1,11 @@ +--- a/dtls/v1.0/nss_connmgr_dtls_netdev.c ++++ b/dtls/v1.0/nss_connmgr_dtls_netdev.c +@@ -160,7 +160,7 @@ static void nss_dtlsmgr_dev_setup(struct + dev->ethtool_ops = NULL; + dev->header_ops = NULL; + dev->netdev_ops = &nss_dtlsmgr_session_ops; +- dev->destructor = NULL; ++ dev->priv_destructor = NULL; + + memcpy(dev->dev_addr, "\xaa\xbb\xcc\xdd\xee\xff", dev->addr_len); + memset(dev->broadcast, 0xff, dev->addr_len); diff --git a/root/package/firmware/nss/qca-nss-clients/patches/104-kernel-5.4-support-l2tp.patch b/root/package/firmware/nss/qca-nss-clients/patches/104-kernel-5.4-support-l2tp.patch new file mode 100644 index 00000000..c637235c --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/patches/104-kernel-5.4-support-l2tp.patch @@ -0,0 +1,64 @@ +--- a/l2tp/l2tpv2/nss_connmgr_l2tpv2.h ++++ b/l2tp/l2tpv2/nss_connmgr_l2tpv2.h +@@ -30,10 +30,10 @@ + + #define L2TP_V_2 2 + +-#define tunnel_hold(tunnel) atomic_inc(&tunnel->ref_count) +-#define tunnel_put(tunnel) atomic_dec(&tunnel->ref_count) +-#define session_hold(session) atomic_inc(&session->ref_count) +-#define session_put(session) atomic_dec(&session->ref_count) ++#define tunnel_hold(tunnel) refcount_inc(&tunnel->ref_count) ++#define tunnel_put(tunnel) refcount_dec(&tunnel->ref_count) ++#define session_hold(session) refcount_inc(&session->ref_count) ++#define session_put(session) refcount_dec(&session->ref_count) + + /* + * ---------------------------------------------------------------------------------- +--- a/l2tp/l2tpv2/nss_connmgr_l2tpv2.c ++++ b/l2tp/l2tpv2/nss_connmgr_l2tpv2.c +@@ -244,7 +244,7 @@ static struct nss_connmgr_l2tpv2_session + */ + data->l2tpv2.session.session_id = session->session_id; + data->l2tpv2.session.peer_session_id = session->peer_session_id; +- data->l2tpv2.session.offset = session->offset; ++ data->l2tpv2.session.offset = 0; + data->l2tpv2.session.hdr_len = session->hdr_len; + data->l2tpv2.session.reorder_timeout = session->reorder_timeout; + data->l2tpv2.session.recv_seq = session->recv_seq; +@@ -253,7 +253,7 @@ static struct nss_connmgr_l2tpv2_session + nss_connmgr_l2tpv2_info("sess %u, peer=%u nr=%u ns=%u off=%u hdr_len=%u timeout=%x" + " recv_seq=%x send_seq=%x\n", + session->session_id, session->peer_session_id, session->nr, +- session->ns, session->offset, session->hdr_len, ++ session->ns, 0, session->hdr_len, + session->reorder_timeout, session->recv_seq, + session->send_seq); + +--- a/l2tp/l2tpv2/nss_l2tpv2_stats.c ++++ b/l2tp/l2tpv2/nss_l2tpv2_stats.c +@@ -21,6 +21,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -103,14 +104,14 @@ void nss_l2tpv2_update_dev_stats(struct + /* + * Update tunnel & session stats + */ +- tunnel = l2tp_tunnel_find(dev_net(dev), data.l2tpv2.tunnel.tunnel_id); ++ tunnel = l2tp_tunnel_get(dev_net(dev), data.l2tpv2.tunnel.tunnel_id); + if (!tunnel) { + dev_put(dev); + return; + } + tunnel_hold(tunnel); + +- session = l2tp_session_find(dev_net(dev), tunnel, data.l2tpv2.session.session_id); ++ session = l2tp_session_get(dev_net(dev), data.l2tpv2.session.session_id); + if (!session) { + tunnel_put(tunnel); + dev_put(dev); diff --git a/root/package/firmware/nss/qca-nss-clients/patches/200-qdisc-fix-compile-error.patch b/root/package/firmware/nss/qca-nss-clients/patches/200-qdisc-fix-compile-error.patch new file mode 100644 index 00000000..4e147489 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/patches/200-qdisc-fix-compile-error.patch @@ -0,0 +1,14 @@ +--- a/nss_qdisc/nss_qdisc.c ++++ b/nss_qdisc/nss_qdisc.c +@@ -2708,9 +2708,11 @@ static int nss_qdisc_if_event_cb(struct + case NETDEV_BR_JOIN: + nss_qdisc_info("Reveived NETDEV_BR_JOIN on interface %s\n", + dev->name); ++ goto fall_through; + case NETDEV_BR_LEAVE: + nss_qdisc_info("Reveived NETDEV_BR_LEAVE on interface %s\n", + dev->name); ++fall_through: + br = nss_qdisc_get_dev_master(dev); + if_num = nss_cmn_get_interface_number(nss_qdisc_ctx, dev); + diff --git a/root/package/firmware/nss/qca-nss-clients/patches/202-vlanmgr-fix-compile-error.patch b/root/package/firmware/nss/qca-nss-clients/patches/202-vlanmgr-fix-compile-error.patch new file mode 100644 index 00000000..53af3192 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-clients/patches/202-vlanmgr-fix-compile-error.patch @@ -0,0 +1,48 @@ +--- a/vlan/nss_vlan_mgr.c ++++ b/vlan/nss_vlan_mgr.c +@@ -820,8 +820,10 @@ static struct nss_vlan_pvt *nss_vlan_mgr + */ + static void nss_vlan_mgr_instance_free(struct nss_vlan_pvt *v) + { ++#ifdef NSS_VLAN_MGR_PPE_SUPPORT + int32_t i; + int ret = 0; ++#endif + + spin_lock(&vlan_mgr_ctx.lock); + BUG_ON(--v->refs); +@@ -979,8 +981,11 @@ static int nss_vlan_mgr_register_event(s + int ret; + #endif + uint32_t vlan_tag; ++#ifdef NSS_VLAN_MGR_PPE_SUPPORT + struct net_device *slave; +- int32_t port, port_if; ++ int32_t port; ++#endif ++ int32_t port_if; + struct vlan_dev_priv *vlan; + struct net_device *real_dev; + bool is_bond_master = false; +@@ -1354,8 +1359,10 @@ return_with_error: + int nss_vlan_mgr_join_bridge(struct net_device *dev, uint32_t bridge_vsi) + { + struct nss_vlan_pvt *v = nss_vlan_mgr_instance_find_and_ref(dev); ++#ifdef NSS_VLAN_MGR_PPE_SUPPORT + struct net_device *real_dev; + int ret; ++#endif + + if (!v) + return 0; +@@ -1415,8 +1422,10 @@ EXPORT_SYMBOL(nss_vlan_mgr_join_bridge); + int nss_vlan_mgr_leave_bridge(struct net_device *dev, uint32_t bridge_vsi) + { + struct nss_vlan_pvt *v = nss_vlan_mgr_instance_find_and_ref(dev); ++#ifdef NSS_VLAN_MGR_PPE_SUPPORT + struct net_device *real_dev; + int ret; ++#endif + + if (!v) + return 0; diff --git a/root/package/firmware/nss/qca-nss-crypto/Makefile b/root/package/firmware/nss/qca-nss-crypto/Makefile new file mode 100644 index 00000000..213e2447 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-crypto/Makefile @@ -0,0 +1,74 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-nss-crypto +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-crypto +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=e7651c2986d30b5e8ca5ad6b9a72c47febdf3cca +PKG_MIRROR_HASH:=381ba448ccd9e0ff69fa52b3e10687b72260b7d0bf865cac10be7f159573b6c8 + +include $(INCLUDE_DIR)/package.mk + +ifeq ($(CONFIG_TARGET_ipq),y) +subtarget:=$(SUBTARGET) +else +subtarget:=$(CONFIG_TARGET_BOARD) +endif + +# v1.0 is for Akronite +# v2.0 is for Hawkeye/Cypress/Maple +ifneq (, $(findstring $(subtarget), "ipq807x" "ipq807x_64" "ipq60xx" "ipq60xx_64" "ipq50xx" "ipq50xx_64")) +NSS_CRYPTO_DIR:=v2.0 +else +NSS_CRYPTO_DIR:=v1.0 +endif + +define KernelPackage/qca-nss-crypto/Default + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@(TARGET_ipq806x||TARGET_ipq807x||TARGET_ipq50xx||TARGET_ipq60xx) +kmod-qca-nss-drv +endef + +define KernelPackage/qca-nss-crypto + $(call KernelPackage/qca-nss-crypto/Default) + TITLE:=Kernel driver for NSS crypto driver + FILES:=$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/src/qca-nss-crypto.ko \ + $(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/tool/qca-nss-crypto-tool.ko + AUTOLOAD:=$(call AutoLoad,52,qca-nss-crypto) +endef + +define KernelPackage/qca-nss-crypto/Description +This package contains a NSS crypto driver for QCA chipset +endef + +define Build/InstallDev/qca-nss-crypto + $(INSTALL_DIR) $(1)/usr/include/qca-nss-crypto + $(CP) $(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/include/* $(1)/usr/include/qca-nss-crypto +endef + +define Build/InstallDev + $(call Build/InstallDev/qca-nss-crypto,$(1)) +endef + +EXTRA_CFLAGS+= \ + -DCONFIG_NSS_DEBUG_LEVEL=4 \ + -I$(STAGING_DIR)/usr/include/qca-nss-crypto \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv \ + -I$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/include \ + -I$(PKG_BUILD_DIR)/$(NSS_CRYPTO_DIR)/src + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + NSS_CRYPTO_DIR=$(NSS_CRYPTO_DIR) \ + SoC="$(subtarget)" \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-crypto)) diff --git a/root/package/firmware/nss/qca-nss-crypto/patches/100-kernel-5.4-support.patch b/root/package/firmware/nss/qca-nss-crypto/patches/100-kernel-5.4-support.patch new file mode 100644 index 00000000..b9ef6191 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-crypto/patches/100-kernel-5.4-support.patch @@ -0,0 +1,42 @@ +--- a/v1.0/tool/nss_crypto_bench.c ++++ b/v1.0/tool/nss_crypto_bench.c +@@ -75,8 +75,8 @@ static DECLARE_WAIT_QUEUE_HEAD(tx_comp); + static DECLARE_WAIT_QUEUE_HEAD(tx_start); + static struct task_struct *tx_thread = NULL; + +-static struct timeval init_time; +-static struct timeval comp_time; ++static struct timespec64 init_time; ++static struct timespec64 comp_time; + static spinlock_t op_lock; + static nss_crypto_handle_t crypto_hdl; + +@@ -782,7 +782,7 @@ static int crypto_bench_tx(void *arg) + crypto_bench_debug("#"); + + /* get start time */ +- do_gettimeofday(&init_time); ++ ktime_get_real_ts64(&init_time); + + /** + * Request submission +@@ -812,8 +812,8 @@ static int crypto_bench_tx(void *arg) + * Calculate time and output the Mbps + */ + +- init_usecs = (init_time.tv_sec * 1000 * 1000) + init_time.tv_usec; +- comp_usecs = (comp_time.tv_sec * 1000 * 1000) + comp_time.tv_usec; ++ init_usecs = (init_time.tv_sec * 1000 * 1000) + (init_time.tv_nsec / NSEC_PER_USEC); ++ comp_usecs = (comp_time.tv_sec * 1000 * 1000) + (comp_time.tv_nsec / NSEC_PER_USEC); + delta_usecs = comp_usecs - init_usecs; + + reqs_completed = param.num_reqs - atomic_read(&tx_reqs); +@@ -870,7 +870,7 @@ static void crypto_bench_done(struct nss + nss_crypto_buf_free(crypto_hdl, buf); + + if (atomic_dec_and_test(&tx_reqs)) { +- do_gettimeofday(&comp_time); ++ ktime_get_real_ts64(&comp_time); + + wake_up_interruptible(&tx_comp); + param.num_loops--; diff --git a/root/package/firmware/nss/qca-nss-crypto/patches/200-fix-NULL-pointer-exception.patch b/root/package/firmware/nss/qca-nss-crypto/patches/200-fix-NULL-pointer-exception.patch new file mode 100644 index 00000000..6bd95109 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-crypto/patches/200-fix-NULL-pointer-exception.patch @@ -0,0 +1,57 @@ +--- a/v1.0/src/nss_crypto_if.c ++++ b/v1.0/src/nss_crypto_if.c +@@ -370,15 +370,16 @@ void nss_crypto_transform_done(struct ne + struct nss_crypto_buf *buf = (struct nss_crypto_buf *)skb->data; + struct nss_crypto_buf_node *entry; + void *addr; ++ struct device *cdev = gbl_crypto_ctrl.eng[0].dev; + + if (likely(buf->data_in == buf->data_out)) { +- dma_unmap_single(NULL, buf->data_in, buf->data_len, DMA_BIDIRECTIONAL); ++ dma_unmap_single(cdev, buf->data_in, buf->data_len, DMA_BIDIRECTIONAL); + } else { +- dma_unmap_single(NULL, buf->data_in, buf->data_len, DMA_TO_DEVICE); +- dma_unmap_single(NULL, buf->data_out, buf->data_len, DMA_FROM_DEVICE); ++ dma_unmap_single(cdev, buf->data_in, buf->data_len, DMA_TO_DEVICE); ++ dma_unmap_single(cdev, buf->data_out, buf->data_len, DMA_FROM_DEVICE); + } + +- dma_unmap_single(NULL, buf->iv_addr, L1_CACHE_BYTES, DMA_BIDIRECTIONAL); ++ dma_unmap_single(cdev, buf->iv_addr, L1_CACHE_BYTES, DMA_BIDIRECTIONAL); + + addr = phys_to_virt(buf->iv_addr); + entry = container_of(addr, struct nss_crypto_buf_node, results); +@@ -531,6 +532,7 @@ nss_crypto_status_t nss_crypto_transform + uint32_t paddr; + void *vaddr; + size_t len; ++ struct device *cdev = gbl_crypto_ctrl.eng[0].dev; + + if (!buf->cb_fn) { + nss_crypto_warn("%p:no buffer(%p) callback present\n", crypto, buf); +@@ -544,7 +546,7 @@ nss_crypto_status_t nss_crypto_transform + */ + vaddr = (void *)buf->data_in; + len = buf->data_len; +- paddr = dma_map_single(NULL, vaddr, len, DMA_TO_DEVICE); ++ paddr = dma_map_single(cdev, vaddr, len, DMA_TO_DEVICE); + buf->data_in = paddr; + + if (vaddr == (void *)buf->data_out) { +@@ -555,14 +557,14 @@ nss_crypto_status_t nss_crypto_transform + */ + vaddr = (void *)buf->data_out; + len = buf->data_len; +- paddr = dma_map_single(NULL, vaddr, len, DMA_FROM_DEVICE); ++ paddr = dma_map_single(cdev, vaddr, len, DMA_FROM_DEVICE); + buf->data_out = paddr; + } + + /* + * We need to map the results into IV + */ +- paddr = dma_map_single(NULL, entry->results, L1_CACHE_BYTES, DMA_BIDIRECTIONAL); ++ paddr = dma_map_single(cdev, entry->results, L1_CACHE_BYTES, DMA_BIDIRECTIONAL); + buf->hash_addr = paddr; + buf->iv_addr = paddr; + diff --git a/root/package/firmware/nss/qca-nss-dp/Makefile b/root/package/firmware/nss/qca-nss-dp/Makefile new file mode 100644 index 00000000..8da7d314 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-dp/Makefile @@ -0,0 +1,62 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-dp +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/cc-qrdk/oss/lklm/nss-dp +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-03-26 +PKG_SOURCE_VERSION:=e0c89348d5ad99559ce2fbe15d37b3b5bc66aa03 +PKG_MIRROR_HASH:=f369f0c3b33b5f4ad6d0a6ad6ac5495f63c9ecaf94e4e7fa345169f3e44fcf45 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-nss-dp + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@(TARGET_ipq807x||TARGET_ipq60xx) +kmod-qca-ssdk-nohnat + TITLE:=Kernel driver for NSS data plane + FILES:=$(PKG_BUILD_DIR)/qca-nss-dp.ko + AUTOLOAD:=$(call AutoLoad,31,qca-nss-dp) +endef + +define KernelPackage/qca-nss-dp/Description +This package contains a NSS data plane driver for QCA chipset +endef + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-dp + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-dp/ +endef + +EXTRA_CFLAGS+= \ + -I$(STAGING_DIR)/usr/include/qca-ssdk + +NSS_DP_HAL_DIR:=$(PKG_BUILD_DIR)/hal +define Build/Configure + $(LN) $(NSS_DP_HAL_DIR)/arch/$(CONFIG_TARGET_BOARD)/nss_$(CONFIG_TARGET_BOARD).h \ + $(PKG_BUILD_DIR)/exports/nss_dp_arch.h +endef + +ifeq ($(CONFIG_TARGET_BOARD), "ipq807x") + SOC="ipq807x_64" +else ifeq ($(CONFIG_TARGET_BOARD), "ipq60xx") + SOC="ipq60xx_64" +endif + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(SOC)" \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-dp)) diff --git a/root/package/firmware/nss/qca-nss-dp/patches/0001-edma_tx_rx-support-newer-kernels-time-stamping-API.patch b/root/package/firmware/nss/qca-nss-dp/patches/0001-edma_tx_rx-support-newer-kernels-time-stamping-API.patch new file mode 100644 index 00000000..c16a714f --- /dev/null +++ b/root/package/firmware/nss/qca-nss-dp/patches/0001-edma_tx_rx-support-newer-kernels-time-stamping-API.patch @@ -0,0 +1,44 @@ +From 40979666b4371012405715ffa61ab5760fcdc6b3 Mon Sep 17 00:00:00 2001 +Message-Id: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il> +From: Baruch Siach +Date: Mon, 3 May 2021 20:07:36 +0300 +Subject: [PATCH 1/3] edma_tx_rx: support newer kernels time stamping API + +--- + hal/edma/edma_tx_rx.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/hal/edma/edma_tx_rx.c ++++ b/hal/edma/edma_tx_rx.c +@@ -226,10 +226,16 @@ void nss_phy_tstamp_rx_buf(__attribute__ + * set to the correct PTP class value by calling ptp_classify_raw + * in drv->rxtstamp function. + */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) + if (ndev && ndev->phydev && ndev->phydev->drv && + ndev->phydev->drv->rxtstamp) + if(ndev->phydev->drv->rxtstamp(ndev->phydev, skb, 0)) + return; ++#else ++ if (ndev && phy_has_rxtstamp(ndev->phydev)) ++ if (phy_rxtstamp(ndev->phydev, skb, 0)) ++ return; ++#endif + + netif_receive_skb(skb); + } +@@ -247,9 +253,14 @@ void nss_phy_tstamp_tx_buf(struct net_de + * set to the correct PTP class value by calling ptp_classify_raw + * in the drv->txtstamp function. + */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)) + if (ndev && ndev->phydev && ndev->phydev->drv && + ndev->phydev->drv->txtstamp) + ndev->phydev->drv->txtstamp(ndev->phydev, skb, 0); ++#else ++ if (ndev && phy_has_txtstamp(ndev->phydev)) ++ phy_rxtstamp(ndev->phydev, skb, 0); ++#endif + } + EXPORT_SYMBOL(nss_phy_tstamp_tx_buf); + diff --git a/root/package/firmware/nss/qca-nss-dp/patches/0002-nss_dp_main-make-phy-mode-code-compatible-with-newer.patch b/root/package/firmware/nss/qca-nss-dp/patches/0002-nss_dp_main-make-phy-mode-code-compatible-with-newer.patch new file mode 100644 index 00000000..443a57b4 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-dp/patches/0002-nss_dp_main-make-phy-mode-code-compatible-with-newer.patch @@ -0,0 +1,48 @@ +From cef7873a2d77df13ee702d902ed4e06b2248904b Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il> +References: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il> +From: Baruch Siach +Date: Mon, 3 May 2021 20:17:22 +0300 +Subject: [PATCH 2/3] nss_dp_main: make phy mode code compatible with newer + kernels + +--- + include/nss_dp_dev.h | 4 ++-- + nss_dp_main.c | 4 ++++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/include/nss_dp_dev.h ++++ b/include/nss_dp_dev.h +@@ -25,7 +25,7 @@ + #include + #include + #include +-#include ++#include + + #include "nss_dp_api_if.h" + #include "nss_dp_hal_if.h" +@@ -46,7 +46,7 @@ struct nss_dp_dev { + /* Phy related stuff */ + struct phy_device *phydev; /* Phy device */ + struct mii_bus *miibus; /* MII bus */ +- uint32_t phy_mii_type; /* RGMII/SGMII/QSGMII */ ++ phy_interface_t phy_mii_type; /* RGMII/SGMII/QSGMII */ + uint32_t phy_mdio_addr; /* Mdio address */ + bool link_poll; /* Link polling enable? */ + uint32_t forced_speed; /* Forced speed? */ +--- a/nss_dp_main.c ++++ b/nss_dp_main.c +@@ -463,7 +463,11 @@ static int32_t nss_dp_of_get_pdata(struc + hal_pdata->netdev = netdev; + hal_pdata->macid = dp_priv->macid; + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) + dp_priv->phy_mii_type = of_get_phy_mode(np); ++#else ++ of_get_phy_mode(np, &dp_priv->phy_mii_type); ++#endif + dp_priv->link_poll = of_property_read_bool(np, "qcom,link-poll"); + if (of_property_read_u32(np, "qcom,phy-mdio-addr", + &dp_priv->phy_mdio_addr) && dp_priv->link_poll) { diff --git a/root/package/firmware/nss/qca-nss-dp/patches/0003-Drop-_nocache-variants-of-ioremap.patch b/root/package/firmware/nss/qca-nss-dp/patches/0003-Drop-_nocache-variants-of-ioremap.patch new file mode 100644 index 00000000..9c7c53ad --- /dev/null +++ b/root/package/firmware/nss/qca-nss-dp/patches/0003-Drop-_nocache-variants-of-ioremap.patch @@ -0,0 +1,48 @@ +From c8c52512ff48bee578901c381a42f027e79eadf9 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il> +References: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il> +From: Baruch Siach +Date: Mon, 3 May 2021 20:20:29 +0300 +Subject: [PATCH 3/3] Drop _nocache variants of ioremap() + +Recent kernels removed them. +--- + hal/edma/edma_data_plane.c | 2 +- + hal/gmac_hal_ops/qcom/qcom_if.c | 2 +- + hal/gmac_hal_ops/syn/xgmac/syn_if.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/hal/edma/edma_data_plane.c ++++ b/hal/edma/edma_data_plane.c +@@ -797,7 +797,7 @@ int edma_init(void) + /* + * Remap register resource + */ +- edma_hw.reg_base = ioremap_nocache((edma_hw.reg_resource)->start, ++ edma_hw.reg_base = ioremap((edma_hw.reg_resource)->start, + resource_size(edma_hw.reg_resource)); + if (!edma_hw.reg_base) { + pr_warn("Unable to remap EDMA register memory.\n"); +--- a/hal/gmac_hal_ops/qcom/qcom_if.c ++++ b/hal/gmac_hal_ops/qcom/qcom_if.c +@@ -400,7 +400,7 @@ static void *qcom_init(struct gmac_hal_p + qhd->nghd.mac_id = gmacpdata->macid; + + /* Populate the mac base addresses */ +- qhd->nghd.mac_base = devm_ioremap_nocache(&dp_priv->pdev->dev, ++ qhd->nghd.mac_base = devm_ioremap(&dp_priv->pdev->dev, + res->start, resource_size(res)); + if (!qhd->nghd.mac_base) { + netdev_dbg(ndev, "ioremap fail.\n"); +--- a/hal/gmac_hal_ops/syn/xgmac/syn_if.c ++++ b/hal/gmac_hal_ops/syn/xgmac/syn_if.c +@@ -422,7 +422,7 @@ static void *syn_init(struct gmac_hal_pl + + /* Populate the mac base addresses */ + shd->nghd.mac_base = +- devm_ioremap_nocache(&dp_priv->pdev->dev, res->start, ++ devm_ioremap(&dp_priv->pdev->dev, res->start, + resource_size(res)); + if (!shd->nghd.mac_base) { + netdev_dbg(ndev, "ioremap fail.\n"); diff --git a/root/package/firmware/nss/qca-nss-dp/patches/0004-EDMA-Fix-NAPI-packet-counting.patch b/root/package/firmware/nss/qca-nss-dp/patches/0004-EDMA-Fix-NAPI-packet-counting.patch new file mode 100644 index 00000000..eb57fe90 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-dp/patches/0004-EDMA-Fix-NAPI-packet-counting.patch @@ -0,0 +1,31 @@ +From d74920e2a7c413ef40eed72f9cf287cf6fbd5fb8 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Thu, 20 May 2021 14:56:46 +0200 +Subject: [PATCH 1/2] EDMA: Fix NAPI packet counting + +There is a bug in the NAPI packet counting that will +cause NAPI over budget warnings. + +Signed-off-by: Baruch Siach +Signed-off-by: Robert Marko +--- + hal/edma/edma_tx_rx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/hal/edma/edma_tx_rx.c ++++ b/hal/edma/edma_tx_rx.c +@@ -458,12 +458,12 @@ int edma_napi(struct napi_struct *napi, + + for (i = 0; i < ehw->txcmpl_rings; i++) { + txcmpl_ring = &ehw->txcmpl_ring[i]; +- work_done += edma_clean_tx(ehw, txcmpl_ring); ++ edma_clean_tx(ehw, txcmpl_ring); + } + + for (i = 0; i < ehw->rxfill_rings; i++) { + rxfill_ring = &ehw->rxfill_ring[i]; +- work_done += edma_alloc_rx_buffer(ehw, rxfill_ring); ++ edma_alloc_rx_buffer(ehw, rxfill_ring); + } + + /* diff --git a/root/package/firmware/nss/qca-nss-dp/patches/0005-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch b/root/package/firmware/nss/qca-nss-dp/patches/0005-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch new file mode 100644 index 00000000..f231c514 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-dp/patches/0005-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch @@ -0,0 +1,41 @@ +From 44a30d94abcbb10aacc21db29be212518a6b1bf7 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Thu, 20 May 2021 14:57:46 +0200 +Subject: [PATCH] EDMA: Use NAPI_POLL_WEIGHT as NAPI weight + +Currently a weight of 100 is used by the EDMA, according +to upstream max of 64 should be used and that is used for +almost any driver. + +They also introduced NAPI_POLL_WEIGHT define which equals +to 64. + +So use NAPI_POLL_WEIGHT as the weight. + +Signed-off-by: Robert Marko +--- + hal/edma/edma_data_plane.c | 2 +- + hal/edma/edma_data_plane.h | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +--- a/hal/edma/edma_data_plane.c ++++ b/hal/edma/edma_data_plane.c +@@ -582,7 +582,7 @@ static int edma_register_netdevice(struc + */ + if (!edma_hw.napi_added) { + netif_napi_add(netdev, &edma_hw.napi, edma_napi, +- EDMA_NAPI_WORK); ++ NAPI_POLL_WEIGHT); + /* + * Register the interrupt handlers and enable interrupts + */ +--- a/hal/edma/edma_data_plane.h ++++ b/hal/edma/edma_data_plane.h +@@ -27,7 +27,6 @@ + #define EDMA_RX_PREHDR_SIZE (sizeof(struct edma_rx_preheader)) + #define EDMA_TX_PREHDR_SIZE (sizeof(struct edma_tx_preheader)) + #define EDMA_RING_SIZE 128 +-#define EDMA_NAPI_WORK 100 + #define EDMA_START_GMACS NSS_DP_START_IFNUM + #define EDMA_MAX_GMACS NSS_DP_HAL_MAX_PORTS + #define EDMA_TX_PKT_MIN_SIZE 33 /* IPQ807x EDMA needs a minimum packet size of 33 bytes */ diff --git a/root/package/firmware/nss/qca-nss-drv-64/Makefile b/root/package/firmware/nss/qca-nss-drv-64/Makefile new file mode 100644 index 00000000..ac73475f --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/Makefile @@ -0,0 +1,121 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-drv-64 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-drv +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-04-26 +PKG_SOURCE_VERSION:=1cf4bf81fd395f61648efeae78cdf1df60e954ff +PKG_MIRROR_HASH:=3dd84a548a530188021fd4dab54ca4e1eb9056ca77381b24f587365fc7c16f21 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +NSS_CLIENTS_DIR:=$(TOPDIR)/qca/src/qca-nss-clients + +define KernelPackage/qca-nss-drv-64 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@(TARGET_ipq807x||TARGET_ipq60xx) +kmod-qca-nss-dp + TITLE:=Kernel driver for NSS (core driver) + FILES:=$(PKG_BUILD_DIR)/qca-nss-drv.ko + AUTOLOAD:=$(call AutoLoad,32,qca-nss-drv) +endef + +define KernelPackage/qca-nss-drv-64/install + $(INSTALL_DIR) $(1)/lib/debug + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DIR) $(1)/etc/hotplug.d/firmware + $(INSTALL_DIR) $(1)/etc/config + + $(INSTALL_BIN) ./files/qca-nss-drv.debug $(1)/lib/debug/qca-nss-drv + $(INSTALL_BIN) ./files/qca-nss-drv.init $(1)/etc/init.d/qca-nss-drv + $(INSTALL_BIN) ./files/qca-nss-drv.sysctl $(1)/etc/sysctl.d/qca-nss-drv.conf + $(INSTALL_BIN) ./files/qca-nss-drv.hotplug $(1)/etc/hotplug.d/firmware/10-qca-nss-fw + $(INSTALL_BIN) ./files/qca-nss-drv.conf $(1)/etc/config/nss + +endef + +define KernelPackage/qca-nss-drv-64/Description +This package contains a NSS driver for QCA chipset +endef + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-drv + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-drv/ +endef + +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-gmac -I$(STAGING_DIR)/usr/include/qca-nss-dp -I$(STAGING_DIR)/usr/include/qca-ssdk + +ifneq (, $(findstring $(CONFIG_TARGET_BOARD), "ipq807x" "ipq60xx")) +EXTRA_CFLAGS+= -DNSS_MEM_PROFILE_MEDIUM +LOW_MEM_PROFILE_MAKE_OPTS=y +endif + +ifeq ($(CONFIG_KERNEL_SKB_FIXED_SIZE_2K),y) +EXTRA_CFLAGS+= -DNSS_SKB_FIXED_SIZE_2K +endif + +DRV_MAKE_OPTS:= +ifeq ($(LOW_MEM_PROFILE_MAKE_OPTS),y) +DRV_MAKE_OPTS+=NSS_DRV_C2C_ENABLE=n \ + NSS_DRV_CAPWAP_ENABLE=n \ + NSS_DRV_CLMAP_ENABLE=n \ + NSS_DRV_CRYPTO_ENABLE=n \ + NSS_DRV_DTLS_ENABLE=n \ + NSS_DRV_GRE_ENABLE=n \ + NSS_DRV_GRE_REDIR_ENABLE=n \ + NSS_DRV_GRE_TUNNEL_ENABLE=n \ + NSS_DRV_IGS_ENABLE=n \ + NSS_DRV_IPSEC_ENABLE=n \ + NSS_DRV_LAG_ENABLE=n \ + NSS_DRV_L2TP_ENABLE=n \ + NSS_DRV_MAPT_ENABLE=n \ + NSS_DRV_OAM_ENABLE=n \ + NSS_DRV_PPTP_ENABLE=n \ + NSS_DRV_PORTID_ENABLE=n \ + NSS_DRV_PVXLAN_ENABLE=n \ + NSS_DRV_QRFS_ENABLE=n \ + NSS_DRV_QVPN_ENABLE=n \ + NSS_DRV_RMNET_ENABLE=n \ + NSS_DRV_SHAPER_ENABLE=n \ + NSS_DRV_SJACK_ENABLE=n \ + NSS_DRV_TLS_ENABLE=n \ + NSS_DRV_TRUSTSEC_ENABLE=n \ + NSS_DRV_TSTAMP_ENABLE=n \ + NSS_DRV_TUN6RD_ENABLE=n \ + NSS_DRV_TUNIPIP6_ENABLE=n \ + NSS_DRV_VXLAN_ENABLE=n \ + NSS_DRV_MATCH_ENABLE=n \ + NSS_DRV_MIRROR_ENABLE=n +endif + +ifeq ($(CONFIG_TARGET_BOARD), "ipq807x") + SOC="ipq807x_64" +else ifeq ($(CONFIG_TARGET_BOARD), "ipq60xx") + SOC="ipq60xx_64" +endif + +define Build/Configure + $(LN) arch/nss_$(SOC).h $(PKG_BUILD_DIR)/exports/nss_arch.h + sed -i "s/define NSS_FW_VERSION_MAJOR.*/define NSS_FW_VERSION_MAJOR 11/" $(PKG_BUILD_DIR)/exports/nss_fw_version.h + sed -i "s/define NSS_FW_VERSION_MINOR.*/define NSS_FW_VERSION_MINOR 3/" $(PKG_BUILD_DIR)/exports/nss_fw_version.h +endef + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" $(strip $(DRV_MAKE_OPTS)) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC=$(SOC) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-drv-64)) diff --git a/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.conf b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.conf new file mode 100644 index 00000000..a8a1fbf4 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.conf @@ -0,0 +1,6 @@ +config nss_firmware 'qca_nss_0' + +config nss_firmware 'qca_nss_1' + +config general + option enable_rps '1' diff --git a/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.debug b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.debug new file mode 100644 index 00000000..5d435c3a --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.debug @@ -0,0 +1,26 @@ +#!/bin/sh /sbin/sysdebug +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +log cat /sys/kernel/debug/qca-nss-drv/stats/pppoe +log cat /sys/kernel/debug/qca-nss-drv/stats/n2h +log cat /sys/kernel/debug/qca-nss-drv/stats/ipv6 +log cat /sys/kernel/debug/qca-nss-drv/stats/ipv4 +log cat /sys/kernel/debug/qca-nss-drv/stats/gmac +log cat /sys/kernel/debug/qca-nss-drv/stats/drv +log cat /sys/kernel/debug/qca-nss-drv/stats/wifi +log cat /sys/kernel/debug/qca-nss-drv/stats/wifi_if +log cat /sys/kernel/debug/qca-nss-drv/stats/eth_rx diff --git a/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.hotplug b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.hotplug new file mode 100644 index 00000000..1e481383 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.hotplug @@ -0,0 +1,70 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +KERNEL=`uname -r` +case "${KERNEL}" in + 3.4*) + select_or_load=load_nss_fw + ;; + *) + select_or_load=select_nss_fw + ;; +esac + +load_nss_fw () { + ls -l $1 | awk ' { print $9,$5 } '> /dev/console + echo 1 > /sys/class/firmware/$DEVICENAME/loading + cat $1 > /sys/class/firmware/$DEVICENAME/data + echo 0 > /sys/class/firmware/$DEVICENAME/loading +} + +select_nss_fw () { + rm -f /lib/firmware/$DEVICENAME + ln -s $1 /lib/firmware/$DEVICENAME + ls -l /lib/firmware/$DEVICENAME | awk ' { print $9,$5 } '> /dev/console +} + +[ "$ACTION" != "add" ] && exit + +# dev name for UCI, since it doesn't let you use . or - +SDEVNAME=$(echo ${DEVICENAME} | sed s/[.-]/_/g) + +SELECTED_FW=$(uci get nss.${SDEVNAME}.firmware 2>/dev/null) +[ -e "${SELECTED_FW}" ] && { + $select_or_load ${SELECTED_FW} + exit +} + +case $DEVICENAME in + qca-nss0* | qca-nss.0*) + if [ -e /lib/firmware/qca-nss0-enterprise.bin ] ; then + $select_or_load /lib/firmware/qca-nss0-enterprise.bin + else + $select_or_load /lib/firmware/qca-nss0-retail.bin + fi + exit + ;; + qca-nss1* | qca-nss.1*) + if [ -e /lib/firmware/qca-nss1-enterprise.bin ] ; then + $select_or_load /lib/firmware/qca-nss1-enterprise.bin + else + $select_or_load /lib/firmware/qca-nss1-retail.bin + fi + exit + ;; +esac + diff --git a/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.init b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.init new file mode 100644 index 00000000..de12cb6d --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.init @@ -0,0 +1,50 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +START=70 + +enable_rps() { + irq_nss_rps=`grep nss_queue1 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 2 > /proc/irq/$entry/smp_affinity + done + + irq_nss_rps=`grep nss_queue2 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 4 > /proc/irq/$entry/smp_affinity + done + + irq_nss_rps=`grep nss_queue3 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 8 > /proc/irq/$entry/smp_affinity + done + + # Enable NSS RPS + sysctl -w dev.nss.rps.enable=1 >/dev/null 2>/dev/null + +} + + +start() { + local rps_enabled="$(uci_get nss @general[0] enable_rps)" + if [ "$rps_enabled" -eq 1 ]; then + enable_rps + fi +} diff --git a/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.sysctl b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.sysctl new file mode 100644 index 00000000..fc36c33e --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/files/qca-nss-drv.sysctl @@ -0,0 +1,4 @@ +# Default Number of connection configuration +dev.nss.ipv4cfg.ipv4_conn=4096 +dev.nss.ipv6cfg.ipv6_conn=4096 + diff --git a/root/package/firmware/nss/qca-nss-drv-64/patches/0001-core-add-5.10-kernel-to-version-check.patch b/root/package/firmware/nss/qca-nss-drv-64/patches/0001-core-add-5.10-kernel-to-version-check.patch new file mode 100644 index 00000000..3fea9b5c --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/patches/0001-core-add-5.10-kernel-to-version-check.patch @@ -0,0 +1,25 @@ +From 3885c752e12f74cad6c97888b797e5903ad1930d Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Thu, 13 May 2021 23:22:38 +0200 +Subject: [PATCH] core: add 5.10 kernel to version check + +NSS DRV has a kernel version check, so simply add +5.10 as supported. + +Signed-off-by: Robert Marko +--- + nss_core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/nss_core.c ++++ b/nss_core.c +@@ -52,7 +52,8 @@ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)))) || \ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)))) || \ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))) || \ +-(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)))))) ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)))) || \ ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)))))) + #error "Check skb recycle code in this file to match Linux version" + #endif + diff --git a/root/package/firmware/nss/qca-nss-drv-64/patches/0002-nss-drv-replace-ioremap_nocache-with-ioremap.patch b/root/package/firmware/nss/qca-nss-drv-64/patches/0002-nss-drv-replace-ioremap_nocache-with-ioremap.patch new file mode 100644 index 00000000..77155750 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/patches/0002-nss-drv-replace-ioremap_nocache-with-ioremap.patch @@ -0,0 +1,164 @@ +From b5e2a7167ca3df9fce34f0d7c05468d4f5597275 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Thu, 13 May 2021 23:33:18 +0200 +Subject: [PATCH] nss-drv: replace ioremap_nocache() with ioremap() + +ioremap_nocache() does not exist anymore. + +Signed-off-by: Robert Marko +--- + nss_hal/ipq50xx/nss_hal_pvt.c | 6 +++--- + nss_hal/ipq60xx/nss_hal_pvt.c | 8 ++++---- + nss_hal/ipq806x/nss_hal_pvt.c | 4 ++-- + nss_hal/ipq807x/nss_hal_pvt.c | 6 +++--- + nss_hal/nss_hal.c | 4 ++-- + nss_meminfo.c | 2 +- + nss_ppe.c | 2 +- + 7 files changed, 16 insertions(+), 16 deletions(-) + +--- a/nss_hal/ipq50xx/nss_hal_pvt.c ++++ b/nss_hal/ipq50xx/nss_hal_pvt.c +@@ -184,13 +184,13 @@ static struct nss_platform_data *__nss_h + npd->nphys = res_nphys.start; + npd->qgic_phys = res_qgic_phys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + +- npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); ++ npd->qgic_map = ioremap(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; +@@ -348,7 +348,7 @@ static int __nss_hal_common_reset(struct + + of_node_put(cmn); + +- nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); ++ nss_misc_reset = ioremap(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; +--- a/nss_hal/ipq60xx/nss_hal_pvt.c ++++ b/nss_hal/ipq60xx/nss_hal_pvt.c +@@ -207,13 +207,13 @@ static struct nss_platform_data *__nss_h + npd->nphys = res_nphys.start; + npd->qgic_phys = res_qgic_phys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + +- npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); ++ npd->qgic_map = ioremap(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; +@@ -433,13 +433,13 @@ static int __nss_hal_common_reset(struct + + of_node_put(cmn); + +- nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); ++ nss_misc_reset = ioremap(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; + } + +- nss_misc_reset_flag = ioremap_nocache(res_nss_misc_reset_flag.start, resource_size(&res_nss_misc_reset_flag)); ++ nss_misc_reset_flag = ioremap(res_nss_misc_reset_flag.start, resource_size(&res_nss_misc_reset_flag)); + if (!nss_misc_reset_flag) { + pr_err("%px: ioremap fail for nss_misc_reset_flag\n", nss_dev); + return -EFAULT; +--- a/nss_hal/ipq806x/nss_hal_pvt.c ++++ b/nss_hal/ipq806x/nss_hal_pvt.c +@@ -458,7 +458,7 @@ static struct nss_platform_data *__nss_h + npd->nphys = res_nphys.start; + npd->vphys = res_vphys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; +@@ -711,7 +711,7 @@ static int __nss_hal_common_reset(struct + } + of_node_put(cmn); + +- fpb_base = ioremap_nocache(res_nss_fpb_base.start, resource_size(&res_nss_fpb_base)); ++ fpb_base = ioremap(res_nss_fpb_base.start, resource_size(&res_nss_fpb_base)); + if (!fpb_base) { + pr_err("%px: ioremap fail for nss_fpb_base\n", nss_dev); + return -EFAULT; +--- a/nss_hal/ipq807x/nss_hal_pvt.c ++++ b/nss_hal/ipq807x/nss_hal_pvt.c +@@ -234,7 +234,7 @@ static struct nss_platform_data *__nss_h + npd->vphys = res_vphys.start; + npd->qgic_phys = res_qgic_phys.start; + +- npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); ++ npd->nmap = ioremap(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; +@@ -247,7 +247,7 @@ static struct nss_platform_data *__nss_h + goto out; + } + +- npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); ++ npd->qgic_map = ioremap(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; +@@ -467,7 +467,7 @@ static int __nss_hal_common_reset(struct + } + of_node_put(cmn); + +- nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); ++ nss_misc_reset = ioremap(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; +--- a/nss_hal/nss_hal.c ++++ b/nss_hal/nss_hal.c +@@ -78,9 +78,9 @@ int nss_hal_firmware_load(struct nss_ctx + return rc; + } + +- load_mem = ioremap_nocache(npd->load_addr, nss_fw->size); ++ load_mem = ioremap(npd->load_addr, nss_fw->size); + if (!load_mem) { +- nss_info_always("%px: ioremap_nocache failed: %x", nss_ctx, npd->load_addr); ++ nss_info_always("%px: ioremap failed: %x", nss_ctx, npd->load_addr); + release_firmware(nss_fw); + return rc; + } +--- a/nss_meminfo.c ++++ b/nss_meminfo.c +@@ -728,7 +728,7 @@ bool nss_meminfo_init(struct nss_ctx_ins + /* + * meminfo_start is the label where the start address of meminfo map is stored. + */ +- meminfo_start = (uint32_t *)ioremap_nocache(nss_ctx->load + NSS_MEMINFO_MAP_START_OFFSET, ++ meminfo_start = (uint32_t *)ioremap(nss_ctx->load + NSS_MEMINFO_MAP_START_OFFSET, + NSS_MEMINFO_RESERVE_AREA_SIZE); + if (!meminfo_start) { + nss_info_always("%px: cannot remap meminfo start\n", nss_ctx); +--- a/nss_ppe.c ++++ b/nss_ppe.c +@@ -357,7 +357,7 @@ void nss_ppe_init(void) + /* + * Get the PPE base address + */ +- ppe_pvt.ppe_base = ioremap_nocache(PPE_BASE_ADDR, PPE_REG_SIZE); ++ ppe_pvt.ppe_base = ioremap(PPE_BASE_ADDR, PPE_REG_SIZE); + if (!ppe_pvt.ppe_base) { + nss_warning("DRV can't get PPE base address\n"); + return; diff --git a/root/package/firmware/nss/qca-nss-drv-64/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch b/root/package/firmware/nss/qca-nss-drv-64/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch new file mode 100644 index 00000000..0c13a788 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch @@ -0,0 +1,49 @@ +From 62e457f262aaa0db7113ad3ccbcb7ae49d4d7ea8 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 8 Jun 2021 23:24:43 +0200 +Subject: [PATCH] DMA: Fix NULL pointer exceptions + +There are multiple instances that pass NULL instead +of device to DMA functions. +That is incorrect and will cause kernel NULL pointer +exceptions. + +So, simply pass the device structure pointers. + +Signed-off-by: Robert Marko +--- + nss_core.c | 2 +- + nss_coredump.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/nss_core.c ++++ b/nss_core.c +@@ -1617,7 +1617,7 @@ static int32_t nss_core_handle_cause_que + * + */ + if (unlikely((buffer_type == N2H_BUFFER_CRYPTO_RESP))) { +- dma_unmap_single(NULL, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_FROM_DEVICE); ++ dma_unmap_single(nss_ctx->dev, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_FROM_DEVICE); + goto consume; + } + +--- a/nss_coredump.c ++++ b/nss_coredump.c +@@ -154,7 +154,7 @@ void nss_fw_coredump_notify(struct nss_c + dma_addr = nss_own->meminfo_ctx.logbuffer_dma; + } + +- dma_sync_single_for_cpu(NULL, dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(nss_own->dev, dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE); + + /* + * If the current entry is smaller than or equal to the number of NSS_LOG_COREDUMP_LINE_NUM, +@@ -181,7 +181,7 @@ void nss_fw_coredump_notify(struct nss_c + + offset = (index * sizeof(struct nss_log_entry)) + + offsetof(struct nss_log_descriptor, log_ring_buffer); +- dma_sync_single_for_cpu(NULL, dma_addr + offset, ++ dma_sync_single_for_cpu(nss_own->dev, dma_addr + offset, + sizeof(struct nss_log_entry), DMA_FROM_DEVICE); + nss_info_always("%px: %s\n", nss_own, nle_print->message); + nle_print++; diff --git a/root/package/firmware/nss/qca-nss-drv-64/patches/999-treewide-hack-support-for-mismatched-firmware.patch b/root/package/firmware/nss/qca-nss-drv-64/patches/999-treewide-hack-support-for-mismatched-firmware.patch new file mode 100644 index 00000000..46025b82 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv-64/patches/999-treewide-hack-support-for-mismatched-firmware.patch @@ -0,0 +1,344 @@ +From d0bffc800a50305315a0d7cf37140291ef5b1b61 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Thu, 27 May 2021 03:52:47 +0200 +Subject: [PATCH] treewide: hack support for mismatched firmware + +Make new qsdk feature configurable to support old half compatible +firmware. + +Signed-off-by: Ansuel Smith +--- + exports/nss_fw_version.h | 11 +++++++++++ + exports/nss_ipv4.h | 8 ++++++++ + exports/nss_ipv6.h | 7 +++++++ + exports/nss_wifi_vdev.h | 14 ++++++++++++++ + exports/nss_wifili_if.h | 8 ++++++++ + nss_ipv4_stats.c | 2 ++ + nss_ipv4_strings.c | 2 ++ + nss_ipv6_stats.c | 2 ++ + nss_ipv6_strings.c | 2 ++ + 9 files changed, 56 insertions(+) + create mode 100644 exports/nss_fw_version.h + +diff --git a/exports/nss_fw_version.h b/exports/nss_fw_version.h +new file mode 100644 +index 0000000..895d523 +--- /dev/null ++++ b/exports/nss_fw_version.h +@@ -0,0 +1,11 @@ ++#ifndef __NSS_FW_VERSION_H ++#define __NSS_FW_VERSION_H ++ ++#define NSS_FW_VERSION_MAJOR 11 ++#define NSS_FW_VERSION_MINOR 4 ++ ++#define NSS_FW_VERSION(a,b) (((a) << 8) + (b)) ++ ++#define NSS_FW_VERSION_CODE NSS_FW_VERSION(NSS_FW_VERSION_MAJOR, NSS_FW_VERSION_MINOR) ++ ++#endif /* __NSS_FW_VERSION_H */ +\ No newline at end of file +diff --git a/exports/nss_ipv4.h b/exports/nss_ipv4.h +index ee3a552..25c4d82 100644 +--- a/exports/nss_ipv4.h ++++ b/exports/nss_ipv4.h +@@ -26,6 +26,8 @@ + #include "nss_stats_public.h" + #endif + ++#include "nss_fw_version.h" ++ + /** + * @addtogroup nss_ipv4_subsystem + * @{ +@@ -216,12 +218,14 @@ enum nss_ipv4_stats_types { + /**< Number of IPv4 multicast connection destroy requests that missed the cache. */ + NSS_IPV4_STATS_MC_CONNECTION_FLUSHES, + /**< Number of IPv4 multicast connection flushes. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + NSS_IPV4_STATS_CONNECTION_CREATE_INVALID_MIRROR_IFNUM, + /**< Number of IPv4 mirror connection requests with an invalid interface number. */ + NSS_IPV4_STATS_CONNECTION_CREATE_INVALID_MIRROR_IFTYPE, + /**< Number of IPv4 mirror connection requests with an invalid interface type. */ + NSS_IPV4_STATS_MIRROR_FAILURES, + /**< Number of IPv4 mirror failures. */ ++#endif + NSS_IPV4_STATS_MAX, + /**< Maximum message type. */ + }; +@@ -609,8 +613,10 @@ struct nss_ipv4_rule_create_msg { + /**< Ingress shaping related accleration parameters. */ + struct nss_ipv4_identifier_rule identifier; + /**< Rule for adding identifier. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + struct nss_ipv4_mirror_rule mirror_rule; + /**< Mirror rule parameter. */ ++#endif + }; + + /** +@@ -955,6 +961,7 @@ struct nss_ipv4_node_sync { + uint32_t ipv4_mc_connection_flushes; + /**< Number of multicast connection flushes. */ + ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + uint32_t ipv4_connection_create_invalid_mirror_ifnum; + /**< Number of create request failed with an invalid mirror interface number. */ + +@@ -963,6 +970,7 @@ struct nss_ipv4_node_sync { + + uint32_t ipv4_mirror_failures; + /**< Mirror packet failed. */ ++#endif + + uint32_t exception_events[NSS_IPV4_EXCEPTION_EVENT_MAX]; + /**< Number of exception events. */ +diff --git a/exports/nss_ipv6.h b/exports/nss_ipv6.h +index 930e74c..a21f939 100644 +--- a/exports/nss_ipv6.h ++++ b/exports/nss_ipv6.h +@@ -195,6 +195,8 @@ enum nss_ipv6_stats_types { + /**< Number of IPv6 multicast connection destroy requests that missed the cache. */ + NSS_IPV6_STATS_MC_CONNECTION_FLUSHES, + /**< Number of IPv6 multicast connection flushes. */ ++ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + NSS_IPV6_STATS_CONNECTION_CREATE_INVALID_MIRROR_IFNUM, + /**< Number of IPv6 mirror connection requests with an invalid interface number. */ + NSS_IPV6_STATS_CONNECTION_CREATE_INVALID_MIRROR_IFTYPE, +@@ -202,6 +204,7 @@ enum nss_ipv6_stats_types { + + NSS_IPV6_STATS_MIRROR_FAILURES, + /**< Number of IPv6 mirror failures. */ ++#endif + + NSS_IPV6_STATS_MAX, + /**< Maximum message type. */ +@@ -702,8 +705,10 @@ struct nss_ipv6_rule_create_msg { + /**< Ingress shaping related accleration parameters. */ + struct nss_ipv6_identifier_rule identifier; + /**< Rule for adding identifier. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + struct nss_ipv6_mirror_rule mirror_rule; + /**< Mirror rule parameter. */ ++#endif + }; + + /** +@@ -950,6 +955,7 @@ struct nss_ipv6_node_sync { + uint32_t ipv6_mc_connection_flushes; + /**< Number of multicast connection flushes. */ + ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + uint32_t ipv6_connection_create_invalid_mirror_ifnum; + /**< Number of create request failed with an invalid mirror interface number. */ + +@@ -958,6 +964,7 @@ struct nss_ipv6_node_sync { + + uint32_t ipv6_mirror_failures; + /**< Mirror packet failed. */ ++#endif + + uint32_t exception_events[NSS_IPV6_EXCEPTION_EVENT_MAX]; + /**< Number of exception events. */ +diff --git a/exports/nss_wifi_vdev.h b/exports/nss_wifi_vdev.h +index 1b52f66..da91b56 100644 +--- a/exports/nss_wifi_vdev.h ++++ b/exports/nss_wifi_vdev.h +@@ -74,8 +74,10 @@ enum nss_wifi_vdev_msg_types { + NSS_WIFI_VDEV_INTERFACE_RECOVERY_RESET_MSG, + NSS_WIFI_VDEV_INTERFACE_RECOVERY_RECONF_MSG, + NSS_WIFI_VDEV_SET_GROUP_KEY, ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + NSS_WIFI_VDEV_HMMC_MEMBER_ADD_MSG, + NSS_WIFI_VDEV_HMMC_MEMBER_DEL_MSG, ++#endif + NSS_WIFI_VDEV_MAX_MSG + }; + +@@ -130,6 +132,7 @@ enum nss_wifi_vdev_err_types { + NSS_WIFI_VDEV_VLAN_MODE_CONFIG_FAIL, + NSS_WIFI_VDEV_RECOVERY_RESET_FAIL, + NSS_WIFI_VDEV_RECOVERY_RECONF_FAIL, ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + NSS_WIFI_VDEV_CONFIG_GROUP_KEY_FAIL, + NSS_WIFI_VDEV_MULTIPASS_NOT_ENABLED, + NSS_WIFI_VDEV_ALLOC_VLAN_MAP_FAILED, +@@ -139,6 +142,7 @@ enum nss_wifi_vdev_err_types { + NSS_WIFI_VDEV_PPE_PORT_DESTROY_FAIL, + NSS_WIFI_VDEV_PPE_VSI_ASSIGN_FAIL, + NSS_WIFI_VDEV_PPE_VSI_UNASSIGN_FAIL, ++#endif + NSS_WIFI_VDEV_EINV_MAX_CFG + }; + +@@ -161,11 +165,13 @@ enum nss_wifi_vdev_ext_data_pkt_type { + NSS_WIFI_VDEV_EXT_TX_COMPL_PKT_TYPE = 11, /**< Tx completion. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN = 12, /**< WDS source port learning command. */ + NSS_WIFI_VDEV_EXT_DATA_PPDU_INFO = 13, /**< PPDU metadata information. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MCBC_RX = 14, /**< Multicast/broadcast packet received. */ + NSS_WIFI_VDEV_MESH_EXT_DATA_PKT_TYPE_RX_SPL_PACKET = 15, + /**< Mesh link VAP special packet. */ + NSS_WIFI_VDEV_MESH_EXT_DATA_PKT_TYPE_RX_MCAST_EXC = 16, + /**< Mesh link VAP multicast packet. */ ++#endif + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MAX + }; + +@@ -201,9 +207,11 @@ enum nss_wifi_vdev_cmd { + NSS_WIFI_VDEV_ENABLE_IGMP_ME_CMD, /**< Configuration to set IGMP multicast enhancement on VAP. */ + NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD, + /**< Configuration to set WDS backhaul extension on VAP. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD, /**< Configuration to set multicast/broadcast exception to host on VAP. */ + NSS_WIFI_VDEV_CFG_PEER_AUTHORIZE_CMD, + /**< Configuration to enable peer authorization on VAP. */ ++#endif + NSS_WIFI_VDEV_MAX_CMD + }; + +@@ -271,7 +279,9 @@ struct nss_wifi_vdev_config_msg { + uint8_t is_nss_qwrap_en; /**< VAP is configured for NSS firmware QWRAP logic. */ + uint8_t tx_per_pkt_vdev_id_check; /**< Transmit per-packet virtual device ID check. */ + uint8_t align_pad; /**< Reserved field. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + uint32_t vap_ext_mode; /**< Different VAP extended modes. */ ++#endif + }; + + /** +@@ -1037,8 +1047,10 @@ struct nss_wifi_vdev_stats_sync_msg { + uint32_t rx_mcast_bytes; /**< Receive multicast bytes count. */ + uint32_t rx_decrypt_err; /**< Receive decryption error */ + uint32_t rx_mic_err; /**< Receive MIC error */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + uint32_t mcbc_exc_host_fail_cnt; + /**< Number of multicast/broadcast packets failed to send to host through exception path. */ ++#endif + }; + + /** +@@ -1070,6 +1082,7 @@ struct nss_wifi_vdev_msg { + /**< Updates a snooplist group member. */ + struct nss_wifi_vdev_me_snptbl_deny_grp_add_msg vdev_deny_member_add; + /**< Add a snooplist member to the deny list. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + struct nss_wifi_vdev_me_hmmc_add_msg vdev_hmmc_member_add; + /**< Adds a new member into the HMMC list. */ + struct nss_wifi_vdev_me_hmmc_del_msg vdev_hmmc_member_del; +@@ -1078,6 +1091,7 @@ struct nss_wifi_vdev_msg { + /**< Adds a new member into the deny list. */ + struct nss_wifi_vdev_me_deny_ip_del_msg vdev_deny_list_member_del; + /**< Delete a member from the deny list. */ ++#endif + struct nss_wifi_vdev_txmsg vdev_txmsgext; + /**< Transmits special data. */ + struct nss_wifi_vdev_vow_dbg_cfg_msg vdev_vow_dbg_cfg; +diff --git a/exports/nss_wifili_if.h b/exports/nss_wifili_if.h +index fce20fd..1f26d67 100644 +--- a/exports/nss_wifili_if.h ++++ b/exports/nss_wifili_if.h +@@ -62,8 +62,12 @@ + /**< Maximum number of bandwidth supported. */ + #define NSS_WIFILI_REPT_MU_MIMO 1 + #define NSS_WIFILI_REPT_MU_OFDMA_MIMO 3 ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) ++#define NSS_WIFILI_MAX_RESERVED_TYPE 3 ++#else + #define NSS_WIFILI_MAX_RESERVED_TYPE 2 + /**< Maximum reserved type. */ ++#endif + #define NSS_WIFILI_SOC_PER_PACKET_METADATA_SIZE 60 + /**< Metadata area total size. */ + #define NSS_WIFILI_MEC_PEER_ID 0xDEAD +@@ -1333,7 +1337,9 @@ struct nss_wifili_rx_err { + struct nss_wifili_rx_ctrl_stats { + struct nss_wifili_rx_err err; /**< Rx peer errors. */ + uint32_t multipass_rx_pkt_drop; /**< Total number of multipass packets without a VLAN header. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + uint32_t peer_unauth_rx_pkt_drop; /**< Number of receive packets dropped due to an authorized peer. */ ++#endif + uint32_t reserved_type[NSS_WIFILI_MAX_RESERVED_TYPE]; /**< Reserved type for future use. */ + uint32_t non_amsdu_cnt; /**< Number of MSDUs with no MSDU level aggregation. */ + uint32_t amsdu_cnt; /**< Number of MSDUs part of AMSDU. */ +@@ -1810,10 +1816,12 @@ struct nss_wifili_msg { + /**< Peer four-address event message. */ + struct nss_wifili_dbdc_repeater_loop_detection_msg wdrldm; + /**< Wifili DBDC repeater loop detection message. */ ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + struct nss_wifili_peer_update_auth_flag peer_auth; + /**< Peer authentication flag message. */ + struct nss_wifili_mesh_capability_info cap_info; + /**< Mesh capability flag. */ ++#endif + } msg; /**< Message payload. */ + }; + +diff --git a/nss_ipv4_stats.c b/nss_ipv4_stats.c +index 39b162c..c875a63 100644 +--- a/nss_ipv4_stats.c ++++ b/nss_ipv4_stats.c +@@ -177,9 +177,11 @@ void nss_ipv4_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_ + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv4_mc_connection_destroy_requests; + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_DESTROY_MISSES] += nins->ipv4_mc_connection_destroy_misses; + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_FLUSHES] += nins->ipv4_mc_connection_flushes; ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_CREATE_INVALID_MIRROR_IFNUM] += nins->ipv4_connection_create_invalid_mirror_ifnum; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_CREATE_INVALID_MIRROR_IFTYPE] += nins->ipv4_connection_create_invalid_mirror_iftype; + nss_ipv4_stats[NSS_IPV4_STATS_MIRROR_FAILURES] += nins->ipv4_mirror_failures; ++#endif + + for (i = 0; i < NSS_IPV4_EXCEPTION_EVENT_MAX; i++) { + nss_ipv4_exception_stats[i] += nins->exception_events[i]; +diff --git a/nss_ipv4_strings.c b/nss_ipv4_strings.c +index 77ff352..ce4c249 100644 +--- a/nss_ipv4_strings.c ++++ b/nss_ipv4_strings.c +@@ -137,9 +137,11 @@ struct nss_stats_info nss_ipv4_strings_stats[NSS_IPV4_STATS_MAX] = { + {"mc_destroy_requests" , NSS_STATS_TYPE_SPECIAL}, + {"mc_destroy_misses" , NSS_STATS_TYPE_SPECIAL}, + {"mc_flushes" , NSS_STATS_TYPE_SPECIAL}, ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + {"mirror_invalid_ifnum_conn_create_req" , NSS_STATS_TYPE_SPECIAL}, + {"mirror_invalid_iftype_conn_create_req" , NSS_STATS_TYPE_SPECIAL}, + {"mirror_failures" , NSS_STATS_TYPE_SPECIAL}, ++#endif + }; + + /* +diff --git a/nss_ipv6_stats.c b/nss_ipv6_stats.c +index 617f55b..a492a6c 100644 +--- a/nss_ipv6_stats.c ++++ b/nss_ipv6_stats.c +@@ -180,9 +180,11 @@ void nss_ipv6_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_ + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_mc_connection_destroy_requests; + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_DESTROY_MISSES] += nins->ipv6_mc_connection_destroy_misses; + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_FLUSHES] += nins->ipv6_mc_connection_flushes; ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_CREATE_INVALID_MIRROR_IFNUM] += nins->ipv6_connection_create_invalid_mirror_ifnum; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_CREATE_INVALID_MIRROR_IFTYPE] += nins->ipv6_connection_create_invalid_mirror_iftype; + nss_ipv6_stats[NSS_IPV6_STATS_MIRROR_FAILURES] += nins->ipv6_mirror_failures; ++#endif + + for (i = 0; i < NSS_IPV6_EXCEPTION_EVENT_MAX; i++) { + nss_ipv6_exception_stats[i] += nins->exception_events[i]; +diff --git a/nss_ipv6_strings.c b/nss_ipv6_strings.c +index 57b100f..29df9c9 100644 +--- a/nss_ipv6_strings.c ++++ b/nss_ipv6_strings.c +@@ -115,9 +115,11 @@ struct nss_stats_info nss_ipv6_strings_stats[NSS_IPV6_STATS_MAX] = { + {"mc_destroy_requests" ,NSS_STATS_TYPE_SPECIAL}, + {"mc_destroy_misses" ,NSS_STATS_TYPE_SPECIAL}, + {"mc_flushes" ,NSS_STATS_TYPE_SPECIAL}, ++#if (NSS_FW_VERSION_CODE > NSS_FW_VERSION(11,3)) + {"mirror_invalid_ifnum_conn_create_req" ,NSS_STATS_TYPE_SPECIAL}, + {"mirror_invalid_iftype_conn_create_req" ,NSS_STATS_TYPE_SPECIAL}, + {"mirror_failures" ,NSS_STATS_TYPE_SPECIAL}, ++#endif + }; + + /* +-- +2.31.1 + diff --git a/root/package/firmware/nss/qca-nss-drv/Makefile b/root/package/firmware/nss/qca-nss-drv/Makefile new file mode 100644 index 00000000..7e695ca3 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/Makefile @@ -0,0 +1,125 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-nss-drv +PKG_RELEASE:=2 + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-drv +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=809a00deffe9f3d4ecd15965790a152757073437 +PKG_MIRROR_HASH:=9c4340561fe9d6ccaa094bbfc5c7f98c27867d2d9a3f1a3f9a7483bca9bbedf8 + +NSS_CLIENTS_DIR:=$(TOPDIR)/qca/src/qca-nss-clients + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-nss-drv + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq806x||TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq807x||TARGET_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64 \ + +PACKAGE_kmod-qca-nss-gmac:kmod-qca-nss-gmac @LINUX_5_4 + TITLE:=Kernel driver for NSS (core driver) + FILES:=$(PKG_BUILD_DIR)/qca-nss-drv.ko + AUTOLOAD:=$(call AutoLoad,32,qca-nss-drv) +endef + +define KernelPackage/qca-nss-drv/install + $(INSTALL_DIR) $(1)/lib/debug + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DIR) $(1)/etc/hotplug.d/firmware + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DIR) $(1)/lib/firmware + + $(INSTALL_BIN) ./files/qca-nss-drv.debug $(1)/lib/debug/qca-nss-drv + $(INSTALL_BIN) ./files/qca-nss-drv.init $(1)/etc/init.d/qca-nss-drv + $(INSTALL_BIN) ./files/qca-nss-drv.sysctl $(1)/etc/sysctl.d/qca-nss-drv.conf + $(INSTALL_BIN) ./files/qca-nss-drv.hotplug $(1)/etc/hotplug.d/firmware/10-qca-nss-fw + $(INSTALL_BIN) ./files/qca-nss-drv.conf $(1)/etc/config/nss + $(INSTALL_BIN) ./files/nss-firmware/qca-nss0-retail.bin $(1)/lib/firmware/qca-nss0.bin + $(INSTALL_BIN) ./files/nss-firmware/qca-nss1-retail.bin $(1)/lib/firmware/qca-nss1.bin + +endef + +define KernelPackage/qca-nss-drv/Description +This package contains a NSS driver for QCA chipset +endef + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-drv + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-drv/ +ifneq (, $(findstring $(subtarget), "ipq807x" "ipq807x_64" "ipq60xx" "ipq60xx_64" "ipq50xx" "ipq50xx_64")) + $(RM) $(1)/usr/include/qca-nss-drv/nss_ipsecmgr.h + $(INSTALL_DIR) $(1)/usr/include/qca-nss-clients + $(CP) $(NSS_CLIENTS_DIR)/exports/nss_ipsecmgr.h $(1)/usr/include/qca-nss-clients/. +endif +endef + +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-gmac + +# Keeping default as ipq806x for branches that does not have subtarget framework +ifeq ($(CONFIG_TARGET_ipq),y) +subtarget:=$(SUBTARGET) +else +subtarget:=$(CONFIG_TARGET_BOARD) +endif + +ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),256) +EXTRA_CFLAGS+= -DNSS_MEM_PROFILE_LOW +endif + +ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),512) +EXTRA_CFLAGS+= -DNSS_MEM_PROFILE_MEDIUM +endif + +ifeq ($(CONFIG_KERNEL_SKB_FIXED_SIZE_2K),y) +EXTRA_CFLAGS+= -DNSS_SKB_FIXED_SIZE_2K +endif + +DRV_MAKE_OPTS:= +ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),256) +DRV_MAKE_OPTS+=NSS_DRV_C2C_ENABLE=n \ + NSS_DRV_CAPWAP_ENABLE=n \ + NSS_DRV_CLMAP_ENABLE=n \ + NSS_DRV_CRYPTO_ENABLE=n \ + NSS_DRV_DTLS_ENABLE=n \ + NSS_DRV_GRE_ENABLE=n \ + NSS_DRV_GRE_REDIR_ENABLE=n \ + NSS_DRV_GRE_TUNNEL_ENABLE=n \ + NSS_DRV_IGS_ENABLE=n \ + NSS_DRV_IPSEC_ENABLE=n \ + NSS_DRV_LAG_ENABLE=n \ + NSS_DRV_L2TP_ENABLE=n \ + NSS_DRV_MAPT_ENABLE=n \ + NSS_DRV_OAM_ENABLE=n \ + NSS_DRV_PPTP_ENABLE=n \ + NSS_DRV_PORTID_ENABLE=n \ + NSS_DRV_PVXLAN_ENABLE=n \ + NSS_DRV_QRFS_ENABLE=n \ + NSS_DRV_QVPN_ENABLE=n \ + NSS_DRV_RMNET_ENABLE=n \ + NSS_DRV_SHAPER_ENABLE=n \ + NSS_DRV_SJACK_ENABLE=n \ + NSS_DRV_TLS_ENABLE=n \ + NSS_DRV_TRUSTSEC_ENABLE=n \ + NSS_DRV_TSTAMP_ENABLE=n \ + NSS_DRV_TUN6RD_ENABLE=n \ + NSS_DRV_TUNIPIP6_ENABLE=n \ + NSS_DRV_VXLAN_ENABLE=n +endif + +define Build/Configure + $(LN) arch/nss_$(subtarget).h $(PKG_BUILD_DIR)/exports/nss_arch.h +endef + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(DRV_MAKE_OPTS)) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(subtarget)" \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-drv)) diff --git a/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/LICENSE.TXT b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/LICENSE.TXT new file mode 100644 index 00000000..41631989 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/LICENSE.TXT @@ -0,0 +1,45 @@ +Copyright (c) 2014 Qualcomm Atheros, Inc. + +All rights reserved. + +Redistribution and use in binary forms, without +modification, are permitted (subject to the limitations in the +disclaimer below) provided that the following conditions are met: + +*Redistributions must reproduce the above copyright + notice, this list of conditions, and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +*Neither the name of Qualcomm Atheros, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +*No Reverse engineering, decompiling, decrypting, or disassembling of this + software is permitted. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. NO LICENSES OR OTHER RIGHTS, +WHETHER EXPRESS, IMPLIED, BASED ON ESTOPPEL OR OTHERWISE, ARE GRANTED +TO ANY PARTY'S PATENTS, PATENT APPLICATIONS, OR PATENTABLE INVENTIONS +BY VIRTUE OF THIS LICENSE OR THE DELIVERY OR PROVISION BY QUALCOMM +ATHEROS, INC. OF THE SOFTWARE. + +IN NO EVENT SHALL THE COPYRIGHT OWNER OR ANY CONTRIBUTOR BE LIABLE FOR +ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND REGARDLESS OF ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF OR RESULTING FROM THE USE OF THE +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY +EVENT, THE TOTAL AGGREGATE LIABILITY THAT MAY BE IMPOSED ON QUALCOMM +ATHEROS, INC. FOR ANY DIRECT DAMAGES ARISING UNDER OR RESULTING FROM +THIS AGREEMENT OR IN CONNECTION WITH ANY USE OF THE SOFTWARE SHALL NOT +EXCEED A TOTAL AMOUNT OF US$5.00. + +IF ANY OF THE ABOVE PROVISIONS ARE HELD TO BE VOID, INVALID, +UNENFORCEABLE, OR ILLEGAL, THE OTHER PROVISIONS SHALL CONTINUE IN FULL +FORCE AND EFFECT. + diff --git a/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/NOTICE.TXT b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/NOTICE.TXT new file mode 100644 index 00000000..ab54aa01 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/NOTICE.TXT @@ -0,0 +1,217 @@ +============================================================================= + +This Notice.txt file contains certain notices of software components included +with the software that Qualcomm Atheros, Inc. ("Qualcomm Atheros") is required +to provide you. Except where prohibited by the open source license, the content +of this notices file is only provided to satisfy Qualcomm Atheros's attribution +and notice requirement; your use of these software components together with the +Qualcomm Atheros software (Qualcomm Atheros software hereinafter referred to as +"Software") is subject to the terms of your license from Qualcomm Atheros. +Compliance with all copyright laws and software license agreements included in +the notice section of this file are the responsibility of the user. Except as +may be granted by separate express written agreement, this file provides no +license to any Qualcomm Atheros patents, trademarks, copyrights, or other +intellectual property. + +Copyright (c) 2014 Qualcomm Atheros, Inc. All rights reserved. + +Qualcomm is a trademark of Qualcomm Incorporated, registered in the United +States and other countries. All Qualcomm Incorporated trademarks are used with +permission. Atheros is a trademark of Qualcomm Atheros, Inc., registered in the +United States and other countries. Other products and brand names may be +trademarks or registered trademarks of their respective owners. + +NOTICES: + +============================================================================= + +/* + * doprint.c + * Formatted string print support. + * + * Copyright 2001-2012 Qualcomm Atheros, Inc. All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * This code originates with BSD Unix however it has been extensively + * modified. The original copyright is reproduced below: + * + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that: (1) source distributions retain this entire copyright notice and + * comment, and (2) distributions including binaries display the following + * acknowledgement: ``This product includes software developed by the + * University of California, Berkeley and its contributors'' in the + * documentation or other materials provided with the distribution and in + * all advertising materials mentioning features or use of this software. + * Neither the name of the University nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +/* + * math.c + * Support for the standard C library. + * + * Copyright 2006-2012 Qualcomm Atheros, Inc. All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Software contained within this file was originally released with the + * following + * copyright and license statement: + * + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + +/* + * stdlib.c + * Routines from stdlib.h. + * + * Copyright 2004-2012 Qualcomm Atheros, Inc. All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * The code for strtol() and strtoul() are also subject to the following: + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +drr_alg_utils.h: +/****************************************************************************/ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +shaper_list_utils.h: +/****************************************************************************/ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +codel_alg_inv_sqrt.h +/****************************************************************************/ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ diff --git a/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/README.md b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/README.md new file mode 100644 index 00000000..2d0b4750 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/README.md @@ -0,0 +1,10 @@ +NSS FIRMWARE +============ + +This repo contains firmware files to enable the NSS MAC on QCA IPQ806x SoC. + +This product includes software developed by the University of California, +Berkeley and its contributors. + +NSS firmware extracted from Synology RT2600ac SRM 1.2 - Version: 1.2-7742-4 + diff --git a/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/qca-nss0-retail.bin b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/qca-nss0-retail.bin new file mode 100644 index 00000000..08f6efe6 Binary files /dev/null and b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/qca-nss0-retail.bin differ diff --git a/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/qca-nss1-retail.bin b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/qca-nss1-retail.bin new file mode 100644 index 00000000..e79510f3 Binary files /dev/null and b/root/package/firmware/nss/qca-nss-drv/files/nss-firmware/qca-nss1-retail.bin differ diff --git a/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.conf b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.conf new file mode 100644 index 00000000..a8a1fbf4 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.conf @@ -0,0 +1,6 @@ +config nss_firmware 'qca_nss_0' + +config nss_firmware 'qca_nss_1' + +config general + option enable_rps '1' diff --git a/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.debug b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.debug new file mode 100644 index 00000000..5d435c3a --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.debug @@ -0,0 +1,26 @@ +#!/bin/sh /sbin/sysdebug +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +log cat /sys/kernel/debug/qca-nss-drv/stats/pppoe +log cat /sys/kernel/debug/qca-nss-drv/stats/n2h +log cat /sys/kernel/debug/qca-nss-drv/stats/ipv6 +log cat /sys/kernel/debug/qca-nss-drv/stats/ipv4 +log cat /sys/kernel/debug/qca-nss-drv/stats/gmac +log cat /sys/kernel/debug/qca-nss-drv/stats/drv +log cat /sys/kernel/debug/qca-nss-drv/stats/wifi +log cat /sys/kernel/debug/qca-nss-drv/stats/wifi_if +log cat /sys/kernel/debug/qca-nss-drv/stats/eth_rx diff --git a/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.hotplug b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.hotplug new file mode 100644 index 00000000..1e481383 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.hotplug @@ -0,0 +1,70 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +KERNEL=`uname -r` +case "${KERNEL}" in + 3.4*) + select_or_load=load_nss_fw + ;; + *) + select_or_load=select_nss_fw + ;; +esac + +load_nss_fw () { + ls -l $1 | awk ' { print $9,$5 } '> /dev/console + echo 1 > /sys/class/firmware/$DEVICENAME/loading + cat $1 > /sys/class/firmware/$DEVICENAME/data + echo 0 > /sys/class/firmware/$DEVICENAME/loading +} + +select_nss_fw () { + rm -f /lib/firmware/$DEVICENAME + ln -s $1 /lib/firmware/$DEVICENAME + ls -l /lib/firmware/$DEVICENAME | awk ' { print $9,$5 } '> /dev/console +} + +[ "$ACTION" != "add" ] && exit + +# dev name for UCI, since it doesn't let you use . or - +SDEVNAME=$(echo ${DEVICENAME} | sed s/[.-]/_/g) + +SELECTED_FW=$(uci get nss.${SDEVNAME}.firmware 2>/dev/null) +[ -e "${SELECTED_FW}" ] && { + $select_or_load ${SELECTED_FW} + exit +} + +case $DEVICENAME in + qca-nss0* | qca-nss.0*) + if [ -e /lib/firmware/qca-nss0-enterprise.bin ] ; then + $select_or_load /lib/firmware/qca-nss0-enterprise.bin + else + $select_or_load /lib/firmware/qca-nss0-retail.bin + fi + exit + ;; + qca-nss1* | qca-nss.1*) + if [ -e /lib/firmware/qca-nss1-enterprise.bin ] ; then + $select_or_load /lib/firmware/qca-nss1-enterprise.bin + else + $select_or_load /lib/firmware/qca-nss1-retail.bin + fi + exit + ;; +esac + diff --git a/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.init b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.init new file mode 100644 index 00000000..de12cb6d --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.init @@ -0,0 +1,50 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +START=70 + +enable_rps() { + irq_nss_rps=`grep nss_queue1 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 2 > /proc/irq/$entry/smp_affinity + done + + irq_nss_rps=`grep nss_queue2 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 4 > /proc/irq/$entry/smp_affinity + done + + irq_nss_rps=`grep nss_queue3 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 8 > /proc/irq/$entry/smp_affinity + done + + # Enable NSS RPS + sysctl -w dev.nss.rps.enable=1 >/dev/null 2>/dev/null + +} + + +start() { + local rps_enabled="$(uci_get nss @general[0] enable_rps)" + if [ "$rps_enabled" -eq 1 ]; then + enable_rps + fi +} diff --git a/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.sysctl b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.sysctl new file mode 100644 index 00000000..fc36c33e --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/files/qca-nss-drv.sysctl @@ -0,0 +1,4 @@ +# Default Number of connection configuration +dev.nss.ipv4cfg.ipv4_conn=4096 +dev.nss.ipv6cfg.ipv6_conn=4096 + diff --git a/root/package/firmware/nss/qca-nss-drv/patches/100-kernel-5.4-support.patch b/root/package/firmware/nss/qca-nss-drv/patches/100-kernel-5.4-support.patch new file mode 100644 index 00000000..4268225c --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/patches/100-kernel-5.4-support.patch @@ -0,0 +1,107 @@ +diff --git a/Makefile b/Makefile +index d998548..b1a4a83 100644 +--- a/Makefile ++++ b/Makefile +@@ -161,7 +161,7 @@ endif + ccflags-y += -I$(obj)/nss_hal/include -I$(obj)/nss_data_plane/include -I$(obj)/exports -DNSS_DEBUG_LEVEL=0 -DNSS_PKT_STATS_ENABLED=1 + + ccflags-y += -DNSS_PM_DEBUG_LEVEL=0 -DNSS_SKB_REUSE_SUPPORT=1 +-ccflags-y += -Werror ++# ccflags-y += -Werror + + ifneq ($(findstring 3.4, $(KERNELVERSION)),) + NSS_CCFLAGS = -DNSS_DT_SUPPORT=0 -DNSS_FW_DBG_SUPPORT=1 -DNSS_PM_SUPPORT=1 -DNSS_EMPTY_BUFFER_SIZE=1984 +diff --git a/nss_core.c b/nss_core.c +index 6c9716a..8956eb5 100644 +--- a/nss_core.c ++++ b/nss_core.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include "nss_tx_rx_common.h" + #include "nss_data_plane.h" + +@@ -45,7 +46,8 @@ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)))) || \ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)))) || \ + (((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)))) || \ +-(((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))))) ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))) || \ ++(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)))))) + #error "Check skb recycle code in this file to match Linux version" + #endif + +@@ -395,7 +397,11 @@ static void nss_get_ddr_info(struct nss_mmu_ddr_info *mmu, char *name) + struct device_node *node; + + si_meminfo(&vals); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) ++ cached = global_zone_page_state(NR_FILE_PAGES); ++#else + cached = global_page_state(NR_FILE_PAGES); ++#endif /*KERNEL_VERSION(4, 14, 0)*/ + avail_ddr = (vals.totalram + cached + vals.sharedram) * vals.mem_unit; + + /* +@@ -679,7 +685,11 @@ static inline void nss_core_handle_virt_if_pkt(struct nss_ctx_instance *nss_ctx, + * Mimic Linux behavior to allow multi-queue netdev choose which queue to use + */ + if (ndev->netdev_ops->ndo_select_queue) { ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ queue_offset = ndev->netdev_ops->ndo_select_queue(ndev, nbuf, NULL); ++#else + queue_offset = ndev->netdev_ops->ndo_select_queue(ndev, nbuf, NULL, NULL); ++#endif /*KERNEL_VERSION(5, 3, 0)*/ + } + + skb_set_queue_mapping(nbuf, queue_offset); +@@ -2269,7 +2279,11 @@ static inline bool nss_skb_can_reuse(struct nss_ctx_instance *nss_ctx, + * This check is added to avoid deadlock from nf_conntrack + * when ecm is trying to flush a rule. + */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) ++ if (unlikely(skb_nfct(nbuf))) { ++#else + if (unlikely(nbuf->nfct)) { ++#endif /*KERNEL_VERSION(4, 11, 0)*/ + return false; + } + #endif +@@ -2279,7 +2285,11 @@ static inline bool nss_skb_can_reuse(struct nss_ctx_instance *nss_ctx, + * This check is added to avoid deadlock from nf_bridge + * when ecm is trying to flush a rule. + */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) ++ if (unlikely(skb_ext_exist(nbuf, SKB_EXT_BRIDGE_NF))) { ++#else + if (unlikely(nbuf->nf_bridge)) { ++#endif /*KERNEL_VERSION(4, 11, 0)*/ + return false; + } + #endif +diff --git a/nss_n2h.c b/nss_n2h.c +index 781ce2b..695ac13 100644 +--- a/nss_n2h.c ++++ b/nss_n2h.c +@@ -19,6 +19,7 @@ + * NSS N2H node APIs + */ + ++#include + #include "nss_tx_rx_common.h" + #include "nss_n2h_stats.h" + + +--- a/nss_data_plane/nss_data_plane_gmac.c ++++ b/nss_data_plane/nss_data_plane_gmac.c +@@ -20,7 +20,7 @@ + #include "nss_tx_rx_common.h" + #include + +-#define NSS_DP_GMAC_SUPPORTED_FEATURES (NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_FRAGLIST | (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO)) ++#define NSS_DP_GMAC_SUPPORTED_FEATURES (NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_FRAGLIST | (NETIF_F_TSO | NETIF_F_TSO6)) + #define NSS_DATA_PLANE_GMAC_MAX_INTERFACES 4 + + static DEFINE_SPINLOCK(nss_data_plane_gmac_stats_lock); diff --git a/root/package/firmware/nss/qca-nss-drv/patches/101-nss-drv-Control-fab-scaling-from-package-Makefile.patch b/root/package/firmware/nss/qca-nss-drv/patches/101-nss-drv-Control-fab-scaling-from-package-Makefile.patch new file mode 100644 index 00000000..b0facc85 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/patches/101-nss-drv-Control-fab-scaling-from-package-Makefile.patch @@ -0,0 +1,38 @@ +From 40d4b080f17883ac6b39c74a5feb1af384ab6a51 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Thu, 11 Jun 2020 16:57:39 +0200 +Subject: [PATCH] nss-drv: Control fab scaling from package Makefile + +Lets control the fab scaling from the package Makefile +instead of using kernel checks that dont work. +Fab scaling in OpenWrt is done in a external way. + +Signed-off-by: Robert Marko +--- + Makefile | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/Makefile b/Makefile +index 20729ab..2567dd4 100644 +--- a/Makefile ++++ b/Makefile +@@ -405,15 +405,8 @@ NSS_CCFLAGS = -DNSS_DT_SUPPORT=1 -DNSS_FW_DBG_SUPPORT=0 -DNSS_PM_SUPPORT=0 + ccflags-y += -I$(obj) + endif + +-# Fabric scaling is supported in 3.14 and 4.4 only +-ifneq ($(findstring 3.14, $(KERNELVERSION)),) +-NSS_CCFLAGS += -DNSS_FABRIC_SCALING_SUPPORT=1 +-else ifneq ($(findstring 4.4, $(KERNELVERSION)),) +-NSS_CCFLAGS += -DNSS_FABRIC_SCALING_SUPPORT=1 +-else +-NSS_CCFLAGS += -DNSS_FABRIC_SCALING_SUPPORT=0 +-endif ++NSS_CCFLAGS += -DNSS_FABRIC_SCALING_SUPPORT=0 + + # Disable Frequency scaling + ifeq "$(NSS_FREQ_SCALE_DISABLE)" "y" + ccflags-y += -DNSS_FREQ_SCALE_SUPPORT=0 +-- +2.26.2 + diff --git a/root/package/firmware/nss/qca-nss-drv/patches/200-fix-NULL-pointer-exception.patch b/root/package/firmware/nss/qca-nss-drv/patches/200-fix-NULL-pointer-exception.patch new file mode 100644 index 00000000..3d8bba95 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/patches/200-fix-NULL-pointer-exception.patch @@ -0,0 +1,11 @@ +--- a/nss_core.c ++++ b/nss_core.c +@@ -1599,7 +1599,7 @@ static int32_t nss_core_handle_cause_que + * + */ + if (unlikely((buffer_type == N2H_BUFFER_CRYPTO_RESP))) { +- dma_unmap_single(NULL, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_FROM_DEVICE); ++ dma_unmap_single(nss_ctx->dev, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_FROM_DEVICE); + goto consume; + } + diff --git a/root/package/firmware/nss/qca-nss-drv/patches/201-Fix-Kernel-Panic-dma-with-NULL-dev.patch b/root/package/firmware/nss/qca-nss-drv/patches/201-Fix-Kernel-Panic-dma-with-NULL-dev.patch new file mode 100644 index 00000000..addfef1b --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/patches/201-Fix-Kernel-Panic-dma-with-NULL-dev.patch @@ -0,0 +1,82 @@ +From 89949decfd9a0f86427b502aae4fbc3a3ef399f0 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Tue, 23 Jun 2020 19:50:28 +0200 +Subject: [PATCH] Fix Kernel Panic dma with NULL dev + +--- + nss_coredump.c | 4 ++-- + nss_log.c | 8 +++++--- + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/nss_coredump.c b/nss_coredump.c +index aa4ba82..957eca0 100644 +--- a/nss_coredump.c ++++ b/nss_coredump.c +@@ -154,7 +154,7 @@ void nss_fw_coredump_notify(struct nss_ctx_instance *nss_own, + dma_addr = nss_own->meminfo_ctx.logbuffer_dma; + } + +- dma_sync_single_for_cpu(NULL, dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(nss_own->dev, dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE); + + /* + * If the current entry is smaller than or equal to the number of NSS_LOG_COREDUMP_LINE_NUM, +@@ -181,7 +181,7 @@ void nss_fw_coredump_notify(struct nss_ctx_instance *nss_own, + + offset = (index * sizeof(struct nss_log_entry)) + + offsetof(struct nss_log_descriptor, log_ring_buffer); +- dma_sync_single_for_cpu(NULL, dma_addr + offset, ++ dma_sync_single_for_cpu(nss_own->dev, dma_addr + offset, + sizeof(struct nss_log_entry), DMA_FROM_DEVICE); + nss_info_always("%p: %s\n", nss_own, nle_print->message); + nle_print++; +diff --git a/nss_log.c b/nss_log.c +index 06ebba4..f9bd6c8 100644 +--- a/nss_log.c ++++ b/nss_log.c +@@ -44,6 +44,7 @@ struct nss_log_data { + uint32_t last_entry; /* Last known sampled entry (or index) */ + uint32_t nentries; /* Caches the total number of entries of log buffer */ + int nss_id; /* NSS Core id being used */ ++ struct device *nss_dev; + }; + + struct nss_log_ring_buffer_addr nss_rbe[NSS_MAX_CORES]; +@@ -125,6 +126,7 @@ static int nss_log_open(struct inode *inode, struct file *filp) + data->last_entry = 0; + data->nentries = nss_rbe[nss_id].nentries; + data->dma_addr = nss_rbe[nss_id].dma_addr; ++ data->nss_dev = nss_ctx->dev; + + /* + * Increment the reference count so that we don't free +@@ -207,7 +209,7 @@ static ssize_t nss_log_read(struct file *filp, char __user *buf, size_t size, lo + /* + * Get the current index + */ +- dma_sync_single_for_cpu(NULL, data->dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(data->nss_dev, data->dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE); + entry = nss_log_current_entry(desc); + + /* +@@ -251,7 +253,7 @@ static ssize_t nss_log_read(struct file *filp, char __user *buf, size_t size, lo + offset = (offset * sizeof(struct nss_log_entry)) + + offsetof(struct nss_log_descriptor, log_ring_buffer); + +- dma_sync_single_for_cpu(NULL, data->dma_addr + offset, ++ dma_sync_single_for_cpu(data->nss_dev, data->dma_addr + offset, + sizeof(struct nss_log_entry), DMA_FROM_DEVICE); + rb = &desc->log_ring_buffer[index]; + +@@ -510,7 +512,7 @@ bool nss_debug_log_buffer_alloc(uint8_t nss_id, uint32_t nentry) + return true; + + fail: +- dma_unmap_single(NULL, dma_addr, size, DMA_FROM_DEVICE); ++ dma_unmap_single(nss_ctx->dev, dma_addr, size, DMA_FROM_DEVICE); + kfree(addr); + wake_up(&nss_log_wq); + return false; +-- +2.27.0 + diff --git a/root/package/firmware/nss/qca-nss-drv/patches/400-Exported-set-nexthop-function.patch b/root/package/firmware/nss/qca-nss-drv/patches/400-Exported-set-nexthop-function.patch new file mode 100644 index 00000000..8c0ffe77 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-drv/patches/400-Exported-set-nexthop-function.patch @@ -0,0 +1,47 @@ +From f8cf061454a3707c0c84d0fca685e84455f91362 Mon Sep 17 00:00:00 2001 +From: Suruchi Suman +Date: Tue, 3 Dec 2019 12:57:38 +0530 +Subject: [qca-nss-drv] Exported set nexhop function from drv. + +Change-Id: I3df6658bef72fe574ac9acfb7aac61785769766f +Signed-off-by: Suruchi Suman +--- + nss_phys_if.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/nss_phys_if.c b/nss_phys_if.c +index 4f9b20f..0c58d95 100644 +--- a/nss_phys_if.c ++++ b/nss_phys_if.c +@@ -1,6 +1,6 @@ + /* + ************************************************************************** +- * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. +@@ -583,6 +583,12 @@ nss_tx_status_t nss_phys_if_set_nexthop(struct nss_ctx_instance *nss_ctx, uint32 + struct nss_phys_if_msg nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); ++ ++ if (nexthop >= NSS_MAX_NET_INTERFACES) { ++ nss_warning("%p: Invalid nexthop interface number: %d", nss_ctx, nexthop); ++ return NSS_TX_FAILURE_BAD_PARAM; ++ } ++ + nss_info("%p: Phys If nexthop will be set to %d, id:%d\n", nss_ctx, nexthop, if_num); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_SET_NEXTHOP, +@@ -591,6 +597,7 @@ nss_tx_status_t nss_phys_if_set_nexthop(struct nss_ctx_instance *nss_ctx, uint32 + + return nss_phys_if_msg_sync(nss_ctx, &nim); + } ++EXPORT_SYMBOL(nss_phys_if_set_nexthop); + + /* + * nss_get_state() +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm-64/Makefile b/root/package/firmware/nss/qca-nss-ecm-64/Makefile new file mode 100644 index 00000000..f0bec019 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/Makefile @@ -0,0 +1,97 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-ecm-64 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/cc-qrdk/oss/lklm/qca-nss-ecm +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-04-29 +PKG_SOURCE_VERSION:=c115aec34867b582e2e5ea79fc5315971e0e953c +PKG_MIRROR_HASH:=962385b45daa2e552a15018bf2930c2df1f6f575d885375bf935a142b4255da5 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-nss-ecm-64 + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + DEPENDS:=@(TARGET_ipq807x||TARGET_ipq60xx) \ + +kmod-qca-nss-drv-64 \ + +iptables-mod-extra \ + +kmod-ipt-conntrack \ + +kmod-ipt-physdev \ + +iptables-mod-physdev \ + +kmod-ppp \ + +kmod-pppoe + TITLE:=QCA NSS Enhanced Connection Manager (ECM) + FILES:=$(PKG_BUILD_DIR)/*.ko + KCONFIG:=CONFIG_BRIDGE_NETFILTER=y \ + CONFIG_NF_CONNTRACK_EVENTS=y \ + CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y \ + CONFIG_NF_CONNTRACK_DSCPREMARK_EXT=n +endef + +define KernelPackage/qca-nss-ecm-64/Description +This package contains the QCA NSS Enhanced Connection Manager +endef + +define KernelPackage/qca-nss-ecm-64/install + $(INSTALL_DIR) $(1)/etc/firewall.d $(1)/etc/init.d $(1)/usr/bin $(1)/lib/netifd/offload $(1)/etc/config $(1)/etc/uci-defaults $(1)/etc/sysctl.d + $(INSTALL_DATA) ./files/qca-nss-ecm.firewall $(1)/etc/firewall.d/qca-nss-ecm + $(INSTALL_BIN) ./files/qca-nss-ecm.init $(1)/etc/init.d/qca-nss-ecm + $(INSTALL_BIN) ./files/ecm_dump.sh $(1)/usr/bin/ + $(INSTALL_BIN) ./files/on-demand-down $(1)/lib/netifd/offload/on-demand-down + $(INSTALL_DATA) ./files/qca-nss-ecm.uci $(1)/etc/config/ecm + $(INSTALL_DATA) ./files/qca-nss-ecm.defaults $(1)/etc/uci-defaults/99-qca-nss-ecm + $(INSTALL_BIN) ./files/qca-nss-ecm.sysctl $(1)/etc/sysctl.d/qca-nss-ecm.conf + echo 'net.netfilter.nf_conntrack_max=8192' >> $(1)/etc/sysctl.d/qca-nss-ecm.conf +endef + +EXTRA_CFLAGS+=-I$(STAGING_DIR)/usr/include/qca-nss-drv + +ifneq (, $(findstring $(CONFIG_TARGET_BOARD), "ipq807x" "ipq60xx")) +ECM_MAKE_OPTS+= ECM_FRONT_END_NSS_ENABLE=y \ + ECM_CLASSIFIER_HYFI_ENABLE=n \ + ECM_MULTICAST_ENABLE=n \ + ECM_INTERFACE_IPSEC_ENABLE=n \ + ECM_INTERFACE_PPTP_ENABLE=n \ + ECM_INTERFACE_L2TPV2_ENABLE=n \ + ECM_INTERFACE_GRE_TAP_ENABLE=n \ + ECM_INTERFACE_GRE_TUN_ENABLE=n \ + ECM_INTERFACE_SIT_ENABLE=n \ + ECM_INTERFACE_TUNIPIP6_ENABLE=n \ + ECM_INTERFACE_RAWIP_ENABLE=n \ + ECM_INTERFACE_VLAN_ENABLE=n \ + ECM_CLASSIFIER_MARK_ENABLE=n \ + ECM_CLASSIFIER_DSCP_ENABLE=n \ + ECM_CLASSIFIER_PCC_ENABLE=n \ + ECM_BAND_STEERING_ENABLE=n \ + ECM_INTERFACE_PPPOE_ENABLE=y +endif + +ifeq ($(CONFIG_TARGET_BOARD), "ipq807x") + SOC="ipq807x_64" +else ifeq ($(CONFIG_TARGET_BOARD), "ipq60xx") + SOC="ipq60xx_64" +endif + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-ecm + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-ecm +endef + +define Build/Compile + +$(MAKE) -C "$(LINUX_DIR)" $(strip $(ECM_MAKE_OPTS)) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC=$(SOC) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_JOBS) \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-ecm-64)) diff --git a/root/package/firmware/nss/qca-nss-ecm-64/files/ecm_dump.sh b/root/package/firmware/nss/qca-nss-ecm-64/files/ecm_dump.sh new file mode 100755 index 00000000..dbf7de75 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/files/ecm_dump.sh @@ -0,0 +1,95 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +ECM_MODULE=${1:-ecm_state} +MOUNT_ROOT=/dev/ecm + +# +# usage: ecm_dump.sh [module=ecm_db] +# +# with no parameters, ecm_dump.sh will attempt to mount the +# ecm_db state file and cat its contents. +# +# example with a parameter: ecm_dump.sh ecm_classifier_default +# +# this will cause ecm_dump to attempt to find and mount the state +# file for the ecm_classifier_default module, and if successful +# cat the contents. +# + +# this is one of the state files, which happens to be the +# last module started in ecm +ECM_STATE=/sys/kernel/debug/ecm/ecm_state/state_dev_major + +# tests to see if ECM is up and ready to receive commands. +# returns 0 if ECM is fully up and ready, else 1 +ecm_is_ready() { + if [ ! -e "${ECM_STATE}" ] + then + return 1 + fi + return 0 +} + +# +# module_state_mount(module_name) +# Mounts the state file of the module, if supported +# +module_state_mount() { + local module_name=$1 + local mount_dir=$2 + local state_file="/sys/kernel/debug/ecm/${module_name}/state_dev_major" + + if [ -e "${mount_dir}/${module_name}" ] + then + # already mounted + return 0 + fi + + #echo "Mount state file for $module_name ..." + if [ ! -e "$state_file" ] + then + #echo "... $module_name does not support state" + return 1 + fi + + local major="`cat $state_file`" + #echo "... Mounting state $state_file with major: $major" + mknod "${mount_dir}/${module_name}" c $major 0 +} + +# +# main +# +ecm_is_ready || { + #echo "ECM is not running" + exit 1 +} + +# all state files are mounted under MOUNT_ROOT, so make sure it exists +mkdir -p ${MOUNT_ROOT} + +# +# attempt to mount state files for the requested module and cat it +# if the mount succeeded +# +module_state_mount ${ECM_MODULE} ${MOUNT_ROOT} && { + cat ${MOUNT_ROOT}/${ECM_MODULE} + exit 0 +} + +exit 2 diff --git a/root/package/firmware/nss/qca-nss-ecm-64/files/on-demand-down b/root/package/firmware/nss/qca-nss-ecm-64/files/on-demand-down new file mode 100644 index 00000000..02d708e0 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/files/on-demand-down @@ -0,0 +1,6 @@ +#!/bin/sh +# Copyright (c) 2016 The Linux Foundation. All rights reserved. + +[ -e "/sys/kernel/debug/ecm/ecm_db/defunct_all" ] && { + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all +} diff --git a/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.defaults b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.defaults new file mode 100644 index 00000000..308e265c --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.defaults @@ -0,0 +1,28 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +uci -q batch << EOF + delete firewall.qcanssecm + set firewall.qcanssecm=include + set firewall.qcanssecm.type=script + set firewall.qcanssecm.path=/etc/firewall.d/qca-nss-ecm + set firewall.qcanssecm.family=any + set firewall.qcanssecm.reload=1 + commit firewall +EOF + +exit 0 diff --git a/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.firewall b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.firewall new file mode 100644 index 00000000..24c64def --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.firewall @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +iptables -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT diff --git a/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.init b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.init new file mode 100644 index 00000000..78cf16dc --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.init @@ -0,0 +1,137 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2014, 2019-2020 The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# The shebang above has an extra space intentially to avoid having +# openwrt build scripts automatically enable this package starting +# at boot. + +START=19 + +get_front_end_mode() { + config_load "ecm" + config_get front_end global acceleration_engine "auto" + + case $front_end in + auto) + echo '0' + ;; + nss) + echo '1' + ;; + sfe) + echo '2' + ;; + *) + echo 'uci_option_acceleration_engine is invalid' + esac +} + +support_bridge() { + #NSS support bridge acceleration + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && return 0 + #SFE doesn't support bridge acceleration + [ -d /sys/kernel/debug/ecm/ecm_sfe_ipv4 ] && return 1 +} + +load_sfe() { + local kernel_version=$(uname -r) + + [ -e "/lib/modules/$kernel_version/shortcut-fe.ko" ] && { + [ -d /sys/module/shortcut_fe ] || insmod shortcut-fe + } + + [ -e "/lib/modules/$kernel_version/shortcut-fe-ipv6.ko" ] && { + [ -d /sys/module/shortcut_fe_ipv6 ] || insmod shortcut-fe-ipv6 + } + + [ -e "/lib/modules/$kernel_version/shortcut-fe-cm.ko" ] && { + [ -d /sys/module/shortcut_fe_cm ] || insmod shortcut-fe-cm + } + + [ -e "/lib/modules/$kernel_version/shortcut-fe-drv.ko" ] && { + [ -d /sys/module/shortcut_fe_drv ] || insmod shortcut-fe-drv + } +} + +load_ecm() { + [ -d /sys/module/ecm ] || { + [ ! -e /proc/device-tree/MP_256 ] && load_sfe + insmod ecm front_end_selection=$(get_front_end_mode) + } + + support_bridge && { + sysctl -w net.bridge.bridge-nf-call-ip6tables=1 + sysctl -w net.bridge.bridge-nf-call-iptables=1 + } +} + +unload_ecm() { + sysctl -w net.bridge.bridge-nf-call-ip6tables=0 + sysctl -w net.bridge.bridge-nf-call-iptables=0 + + if [ -d /sys/module/ecm ]; then + # + # Stop ECM frontends + # + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + + # + # Defunct the connections + # + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 5; + + rmmod ecm + sleep 1 + fi +} + +start() { + load_ecm + + # If the acceleration engine is NSS, enable wifi redirect. + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=1 + + support_bridge && { + echo 'net.bridge.bridge-nf-call-ip6tables=1' >> /etc/sysctl.d/qca-nss-ecm.conf + echo 'net.bridge.bridge-nf-call-iptables=1' >> /etc/sysctl.d/qca-nss-ecm.conf + } + + if [ -d /sys/module/qca_ovsmgr ]; then + insmod ecm_ovs + fi + +} + +stop() { + # If ECM is already not loaded, just return. + if [ ! -d /sys/module/ecm ]; then + return + fi + + # If the acceleration engine is NSS, disable wifi redirect. + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=0 + + sed '/net.bridge.bridge-nf-call-ip6tables=1/d' -i /etc/sysctl.d/qca-nss-ecm.conf + sed '/net.bridge.bridge-nf-call-iptables=1/d' -i /etc/sysctl.d/qca-nss-ecm.conf + + if [ -d /sys/module/ecm_ovs ]; then + rmmod ecm_ovs + fi + + unload_ecm +} diff --git a/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.sysctl b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.sysctl new file mode 100644 index 00000000..1a3d76b1 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.sysctl @@ -0,0 +1,2 @@ +# nf_conntrack_tcp_no_window_check is 0 by default, set it to 1 +net.netfilter.nf_conntrack_tcp_no_window_check=1 diff --git a/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.uci b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.uci new file mode 100644 index 00000000..4f2de687 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/files/qca-nss-ecm.uci @@ -0,0 +1,2 @@ +config ecm 'global' + option acceleration_engine 'auto' diff --git a/root/package/firmware/nss/qca-nss-ecm-64/patches/001-treewide-componentize-the-module-even-more.patch b/root/package/firmware/nss/qca-nss-ecm-64/patches/001-treewide-componentize-the-module-even-more.patch new file mode 100644 index 00000000..4e7932c9 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/patches/001-treewide-componentize-the-module-even-more.patch @@ -0,0 +1,335 @@ +From 73345c87b28a473b35b57e673f8de963c3d73da1 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 19 May 2021 02:38:53 +0200 +Subject: [PATCH] treewide: componentize the module even more + +Signed-off-by: Ansuel Smith +--- + Makefile | 56 +++++++++++++++++++++++++------- + ecm_db/ecm_db_connection.c | 8 +++++ + ecm_db/ecm_db_node.c | 4 +++ + ecm_interface.c | 8 +++++ + frontends/ecm_front_end_common.c | 7 ++++ + 5 files changed, 72 insertions(+), 11 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -82,10 +82,18 @@ ccflags-$(ECM_INTERFACE_BOND_ENABLE) += + # Define ECM_INTERFACE_PPPOE_ENABLE=y in order + # to enable support for PPPoE acceleration. + # ############################################################################# +-ECM_INTERFACE_PPPOE_ENABLE=y ++ifndef $(ECM_INTERFACE_PPPOE_ENABLE) ++ ECM_INTERFACE_PPPOE_ENABLE=y ++endif + ccflags-$(ECM_INTERFACE_PPPOE_ENABLE) += -DECM_INTERFACE_PPPOE_ENABLE + + # ############################################################################# ++# Define ECM_INTERFACE_L2TPV2_PPTP_ENABLE=y in order ++# to enable support for l2tpv2 or PPTP detection. ++# ############################################################################# ++ccflags-$(ECM_INTERFACE_L2TPV2_PPTP_ENABLE) += -DECM_INTERFACE_L2TPV2_PPTP_ENABLE ++ ++# ############################################################################# + # Define ECM_INTERFACE_L2TPV2_ENABLE=y in order + # to enable support for l2tpv2 acceleration. + # ############################################################################# +@@ -118,6 +126,12 @@ ccflags-$(ECM_INTERFACE_PPP_ENABLE) += - + ccflags-$(ECM_INTERFACE_MAP_T_ENABLE) += -DECM_INTERFACE_MAP_T_ENABLE + + # ############################################################################# ++# Define ECM_INTERFACE_GRE_ENABLE=y in order ++# to enable support for GRE detection. ++# ############################################################################# ++ccflags-$(ECM_INTERFACE_GRE_ENABLE) += -DECM_INTERFACE_GRE_ENABLE ++ ++# ############################################################################# + # Define ECM_INTERFACE_GRE_TAP_ENABLE=y in order + # to enable support for GRE TAP interface. + # ############################################################################# +@@ -186,7 +200,9 @@ ccflags-$(ECM_INTERFACE_OVS_BRIDGE_ENABL + # ############################################################################# + # Define ECM_INTERFACE_VLAN_ENABLE=y in order to enable support for VLAN + # ############################################################################# +-ECM_INTERFACE_VLAN_ENABLE=y ++ifndef $(ECM_INTERFACE_VLAN_ENABLE) ++ ECM_INTERFACE_VLAN_ENABLE=y ++endif + ccflags-$(ECM_INTERFACE_VLAN_ENABLE) += -DECM_INTERFACE_VLAN_ENABLE + + # ############################################################################# +@@ -228,7 +244,9 @@ ccflags-$(ECM_CLASSIFIER_OVS_ENABLE) += + # ############################################################################# + # Define ECM_CLASSIFIER_MARK_ENABLE=y in order to enable mark classifier. + # ############################################################################# +-ECM_CLASSIFIER_MARK_ENABLE=y ++ifndef $(ECM_CLASSIFIER_MARK_ENABLE) ++ ECM_CLASSIFIER_MARK_ENABLE=y ++endif + ecm-$(ECM_CLASSIFIER_MARK_ENABLE) += ecm_classifier_mark.o + ccflags-$(ECM_CLASSIFIER_MARK_ENABLE) += -DECM_CLASSIFIER_MARK_ENABLE + +@@ -247,7 +265,9 @@ ccflags-$(ECM_CLASSIFIER_NL_ENABLE) += - + # ############################################################################# + # Define ECM_CLASSIFIER_DSCP_ENABLE=y in order to enable DSCP classifier. + # ############################################################################# +-ECM_CLASSIFIER_DSCP_ENABLE=y ++ifndef $(ECM_CLASSIFIER_DSCP_ENABLE) ++ ECM_CLASSIFIER_DSCP_ENABLE=y ++endif + ecm-$(ECM_CLASSIFIER_DSCP_ENABLE) += ecm_classifier_dscp.o + ccflags-$(ECM_CLASSIFIER_DSCP_ENABLE) += -DECM_CLASSIFIER_DSCP_ENABLE + ccflags-$(ECM_CLASSIFIER_DSCP_IGS) += -DECM_CLASSIFIER_DSCP_IGS +@@ -274,7 +294,9 @@ endif + # the Parental Controls subsystem classifier in ECM. Currently disabled until + # customers require it / if they need to integrate their Parental Controls with it. + # ############################################################################# +-ECM_CLASSIFIER_PCC_ENABLE=y ++ifndef $(ECM_CLASSIFIER_PCC_ENABLE) ++ ECM_CLASSIFIER_PCC_ENABLE=y ++endif + ecm-$(ECM_CLASSIFIER_PCC_ENABLE) += ecm_classifier_pcc.o + ccflags-$(ECM_CLASSIFIER_PCC_ENABLE) += -DECM_CLASSIFIER_PCC_ENABLE + +@@ -301,28 +323,36 @@ ccflags-$(ECM_NON_PORTED_SUPPORT_ENABLE) + # ############################################################################# + # Define ECM_STATE_OUTPUT_ENABLE=y to support XML state output + # ############################################################################# +-ECM_STATE_OUTPUT_ENABLE=y ++ifndef $(ECM_STATE_OUTPUT_ENABLE) ++ ECM_STATE_OUTPUT_ENABLE=y ++endif + ecm-$(ECM_STATE_OUTPUT_ENABLE) += ecm_state.o + ccflags-$(ECM_STATE_OUTPUT_ENABLE) += -DECM_STATE_OUTPUT_ENABLE + + # ############################################################################# + # Define ECM_DB_ADVANCED_STATS_ENABLE to support XML state output + # ############################################################################# +-ECM_DB_ADVANCED_STATS_ENABLE=y ++ifndef $(ECM_DB_ADVANCED_STATS_ENABLE) ++ ECM_DB_ADVANCED_STATS_ENABLE=y ++endif + ccflags-$(ECM_DB_ADVANCED_STATS_ENABLE) += -DECM_DB_ADVANCED_STATS_ENABLE + + # ############################################################################# + # Define ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE=y in order to enable + # the database to track relationships between objects. + # ############################################################################# +-ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE=y ++ifndef $(ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE) ++ ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE=y ++endif + ccflags-$(ECM_DB_CONNECTION_CROSS_REFERENCING_ENABLE) += -DECM_DB_XREF_ENABLE + + # ############################################################################# + # Define ECM_TRACKER_DPI_SUPPORT_ENABLE=y in order to enable support for + # deep packet inspection and tracking of data with the trackers. + # ############################################################################# +-ECM_TRACKER_DPI_SUPPORT_ENABLE=y ++ifndef $(ECM_TRACKER_DPI_SUPPORT_ENABLE) ++ ECM_TRACKER_DPI_SUPPORT_ENABLE=y ++endif + ccflags-$(ECM_TRACKER_DPI_SUPPORT_ENABLE) += -DECM_TRACKER_DPI_SUPPORT_ENABLE + + # ############################################################################# +@@ -330,14 +360,18 @@ ccflags-$(ECM_TRACKER_DPI_SUPPORT_ENABLE + # support for the database keeping lists of connections that are assigned + # on a per TYPE of classifier basis. + # ############################################################################# +-ECM_DB_CLASSIFIER_TYPE_ASSIGNMENTS_TRACK_ENABLE=y ++ifndef $(ECM_DB_CLASSIFIER_TYPE_ASSIGNMENTS_TRACK_ENABLE) ++ ECM_DB_CLASSIFIER_TYPE_ASSIGNMENTS_TRACK_ENABLE=y ++endif + ccflags-$(ECM_DB_CLASSIFIER_TYPE_ASSIGNMENTS_TRACK_ENABLE) += -DECM_DB_CTA_TRACK_ENABLE + + # ############################################################################# + # Define ECM_BAND_STEERING_ENABLE=y in order to enable + # band steering feature. + # ############################################################################# +-ECM_BAND_STEERING_ENABLE=y ++ifndef $(ECM_BAND_STEERING_ENABLE) ++ ECM_BAND_STEERING_ENABLE=y ++endif + ccflags-$(ECM_BAND_STEERING_ENABLE) += -DECM_BAND_STEERING_ENABLE + + # ############################################################################# +--- a/ecm_db/ecm_db_connection.c ++++ b/ecm_db/ecm_db_connection.c +@@ -430,7 +430,9 @@ EXPORT_SYMBOL(ecm_db_connection_make_def + */ + void ecm_db_connection_data_totals_update(struct ecm_db_connection_instance *ci, bool is_from, uint64_t size, uint64_t packets) + { ++#ifdef ECM_DB_ADVANCED_STATS_ENABLE + int32_t i; ++#endif + + DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%px: magic failed\n", ci); + +@@ -529,7 +531,9 @@ EXPORT_SYMBOL(ecm_db_connection_data_tot + */ + void ecm_db_connection_data_totals_update_dropped(struct ecm_db_connection_instance *ci, bool is_from, uint64_t size, uint64_t packets) + { ++#ifdef ECM_DB_ADVANCED_STATS_ENABLE + int32_t i; ++#endif + + DEBUG_CHECK_MAGIC(ci, ECM_DB_CONNECTION_INSTANCE_MAGIC, "%px: magic failed\n", ci); + +@@ -1508,6 +1512,7 @@ void ecm_db_connection_defunct_all(void) + } + EXPORT_SYMBOL(ecm_db_connection_defunct_all); + ++#ifdef ECM_INTERFACE_OVS_BRIDGE_ENABLE + /* + * ecm_db_connection_defunct_by_classifier() + * Make defunct based on masked fields +@@ -1667,6 +1672,7 @@ next_ci: + ECM_IP_ADDR_TO_OCTAL(dest_addr_mask), dest_port_mask, proto_mask, cnt); + } + } ++#endif + + /* + * ecm_db_connection_defunct_by_port() +@@ -1956,6 +1962,7 @@ struct ecm_db_node_instance *ecm_db_conn + } + EXPORT_SYMBOL(ecm_db_connection_node_get_and_ref); + ++#ifdef ECM_DB_XREF_ENABLE + /* + * ecm_db_connection_mapping_get_and_ref_next() + * Return reference to next connection in the mapping chain in the specified direction. +@@ -1997,6 +2004,7 @@ struct ecm_db_connection_instance *ecm_d + return nci; + } + EXPORT_SYMBOL(ecm_db_connection_iface_get_and_ref_next); ++#endif + + /* + * ecm_db_connection_mapping_get_and_ref() +--- a/ecm_db/ecm_db_node.c ++++ b/ecm_db/ecm_db_node.c +@@ -224,9 +224,11 @@ EXPORT_SYMBOL(ecm_db_node_get_and_ref_ne + */ + int ecm_db_node_deref(struct ecm_db_node_instance *ni) + { ++#ifdef ECM_DB_XREF_ENABLE + #if (DEBUG_LEVEL >= 1) + int dir; + #endif ++#endif + DEBUG_CHECK_MAGIC(ni, ECM_DB_NODE_INSTANCE_MAGIC, "%px: magic failed\n", ni); + + spin_lock_bh(&ecm_db_lock); +@@ -486,9 +488,11 @@ EXPORT_SYMBOL(ecm_db_node_iface_get_and_ + void ecm_db_node_add(struct ecm_db_node_instance *ni, struct ecm_db_iface_instance *ii, uint8_t *address, + ecm_db_node_final_callback_t final, void *arg) + { ++#ifdef ECM_DB_XREF_ENABLE + #if (DEBUG_LEVEL >= 1) + int dir; + #endif ++#endif + ecm_db_node_hash_t hash_index; + struct ecm_db_listener_instance *li; + +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -1343,6 +1343,7 @@ struct neighbour *ecm_interface_ipv6_nei + */ + bool ecm_interface_is_pptp(struct sk_buff *skb, const struct net_device *out) + { ++#ifdef ECM_INTERFACE_PPTP_ENABLE + struct net_device *in; + + /* +@@ -1367,6 +1368,7 @@ bool ecm_interface_is_pptp(struct sk_buf + } + + dev_put(in); ++#endif + return false; + } + +@@ -1379,6 +1381,7 @@ bool ecm_interface_is_pptp(struct sk_buf + */ + bool ecm_interface_is_l2tp_packet_by_version(struct sk_buff *skb, const struct net_device *out, int ver) + { ++#ifdef ECM_INTERFACE_L2TPV2_PPTP_ENABLE + uint32_t flag = 0; + struct net_device *in; + +@@ -1411,6 +1414,7 @@ bool ecm_interface_is_l2tp_packet_by_ver + } + + dev_put(in); ++#endif + return false; + } + +@@ -1423,6 +1427,7 @@ bool ecm_interface_is_l2tp_packet_by_ver + */ + bool ecm_interface_is_l2tp_pptp(struct sk_buff *skb, const struct net_device *out) + { ++#ifdef ECM_INTERFACE_L2TPV2_PPTP_ENABLE + struct net_device *in; + + /* +@@ -1445,6 +1450,7 @@ bool ecm_interface_is_l2tp_pptp(struct s + } + + dev_put(in); ++#endif + return false; + } + +@@ -6630,6 +6636,7 @@ static void ecm_interface_regenerate_con + return; + } + ++#ifdef ECM_DB_XREF_ENABLE + for (dir = 0; dir < ECM_DB_OBJ_DIR_MAX; dir++) { + /* + * Re-generate all connections associated with this interface +@@ -6645,6 +6652,7 @@ static void ecm_interface_regenerate_con + ci[dir] = cin; + } + } ++#endif + + #ifdef ECM_MULTICAST_ENABLE + /* +--- a/frontends/ecm_front_end_common.c ++++ b/frontends/ecm_front_end_common.c +@@ -106,6 +106,7 @@ bool ecm_front_end_gre_proto_is_accel_al + struct nf_conntrack_tuple *tuple, + int ip_version) + { ++#ifdef ECM_INTERFACE_GRE_ENABLE + struct net_device *dev; + struct gre_base_hdr *greh; + +@@ -117,10 +118,12 @@ bool ecm_front_end_gre_proto_is_accel_al + /* + * Case 1: PPTP locally terminated + */ ++#ifdef ECM_INTERFACE_PPTP_ENABLE + if (ecm_interface_is_pptp(skb, outdev)) { + DEBUG_TRACE("%px: PPTP GRE locally terminated - allow acceleration\n", skb); + return true; + } ++#endif + + /* + * Case 2: PPTP pass through +@@ -223,6 +226,10 @@ bool ecm_front_end_gre_proto_is_accel_al + */ + DEBUG_TRACE("%px: GRE IPv%d pass through - allow acceleration\n", skb, ip_version); + return true; ++#else ++ DEBUG_TRACE("%px: GRE%d feature is disabled - do not allow acceleration\n", skb, ip_version); ++ return false; ++#endif + } + + #ifdef ECM_CLASSIFIER_DSCP_ENABLE diff --git a/root/package/firmware/nss/qca-nss-ecm-64/patches/100-kernel-5.10-support.patch b/root/package/firmware/nss/qca-nss-ecm-64/patches/100-kernel-5.10-support.patch new file mode 100644 index 00000000..107b9571 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/patches/100-kernel-5.10-support.patch @@ -0,0 +1,831 @@ +From e8b642c23af9146c973e828a7f4e0fb56cfc8d0b Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 15 May 2021 03:51:14 +0200 +Subject: [PATCH] add support for kernel 5.10 + +Signed-off-by: Ansuel Smith +--- + ecm_classifier_default.c | 24 +++--------- + ecm_classifier_dscp.c | 8 +--- + ecm_classifier_emesh.c | 16 ++------ + ecm_classifier_hyfi.c | 7 +--- + ecm_classifier_mark.c | 8 +--- + ecm_classifier_ovs.c | 8 +--- + ecm_classifier_pcc.c | 8 +--- + ecm_conntrack_notifier.c | 8 +--- + ecm_db/ecm_db_connection.c | 7 +--- + ecm_db/ecm_db_host.c | 7 +--- + ecm_db/ecm_db_iface.c | 7 +--- + ecm_db/ecm_db_mapping.c | 7 +--- + ecm_db/ecm_db_node.c | 7 +--- + ecm_interface.c | 4 +- + ecm_state.c | 14 ++----- + frontends/ecm_front_end_common.c | 4 +- + frontends/ecm_front_end_ipv4.c | 7 +--- + frontends/ecm_front_end_ipv6.c | 7 +--- + frontends/nss/ecm_nss_bond_notifier.c | 8 +--- + frontends/nss/ecm_nss_ipv4.c | 49 +++++++------------------ + frontends/nss/ecm_nss_ipv6.c | 49 +++++++------------------ + frontends/nss/ecm_nss_multicast_ipv4.c | 7 +--- + frontends/nss/ecm_nss_multicast_ipv6.c | 7 +--- + frontends/nss/ecm_nss_non_ported_ipv4.c | 7 +--- + frontends/nss/ecm_nss_non_ported_ipv6.c | 7 +--- + frontends/nss/ecm_nss_ported_ipv4.c | 8 +--- + frontends/nss/ecm_nss_ported_ipv6.c | 8 +--- + frontends/sfe/ecm_sfe_ipv4.c | 49 +++++++------------------ + frontends/sfe/ecm_sfe_ipv6.c | 49 +++++++------------------ + frontends/sfe/ecm_sfe_non_ported_ipv4.c | 7 +--- + frontends/sfe/ecm_sfe_non_ported_ipv6.c | 7 +--- + frontends/sfe/ecm_sfe_ported_ipv4.c | 8 +--- + frontends/sfe/ecm_sfe_ported_ipv6.c | 8 +--- + 33 files changed, 122 insertions(+), 314 deletions(-) + +--- a/ecm_classifier_default.c ++++ b/ecm_classifier_default.c +@@ -776,26 +776,14 @@ int ecm_classifier_default_init(struct d + return -1; + } + +- if (!debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry, +- (u32 *)&ecm_classifier_default_enabled)) { +- DEBUG_ERROR("Failed to create ecm deafult classifier enabled file in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_default_dentry); +- return -1; +- } ++ debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry, ++ (u32 *)&ecm_classifier_default_enabled); + +- if (!debugfs_create_u32("accel_mode", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry, +- (u32 *)&ecm_classifier_default_accel_mode)) { +- DEBUG_ERROR("Failed to create ecm deafult classifier accel_mode file in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_default_dentry); +- return -1; +- } ++ debugfs_create_u32("accel_mode", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry, ++ (u32 *)&ecm_classifier_default_accel_mode); + +- if (!debugfs_create_u32("accel_delay_pkts", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry, +- (u32 *)&ecm_classifier_accel_delay_pkts)) { +- DEBUG_ERROR("Failed to create accel delay packet counts in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_default_dentry); +- return -1; +- } ++ debugfs_create_u32("accel_delay_pkts", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry, ++ (u32 *)&ecm_classifier_accel_delay_pkts); + + return 0; + } +--- a/ecm_classifier_dscp.c ++++ b/ecm_classifier_dscp.c +@@ -747,12 +747,8 @@ int ecm_classifier_dscp_init(struct dent + return -1; + } + +- if (!debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_dscp_dentry, +- (u32 *)&ecm_classifier_dscp_enabled)) { +- DEBUG_ERROR("Failed to create dscp enabled file in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_dscp_dentry); +- return -1; +- } ++ debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_dscp_dentry, ++ (u32 *)&ecm_classifier_dscp_enabled); + + return 0; + } +--- a/ecm_classifier_emesh.c ++++ b/ecm_classifier_emesh.c +@@ -977,19 +977,11 @@ int ecm_classifier_emesh_init(struct den + return -1; + } + +- if (!debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_emesh_dentry, +- (u32 *)&ecm_classifier_emesh_enabled)) { +- DEBUG_ERROR("Failed to create ecm emesh classifier enabled file in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_emesh_dentry); +- return -1; +- } ++ debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_emesh_dentry, ++ (u32 *)&ecm_classifier_emesh_enabled); + +- if (!debugfs_create_u32("latency_config_enabled", S_IRUGO | S_IWUSR, ecm_classifier_emesh_dentry, +- (u32 *)&ecm_classifier_emesh_latency_config_enabled)) { +- DEBUG_ERROR("Failed to create ecm emesh classifier latency config enabled file in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_emesh_dentry); +- return -1; +- } ++ debugfs_create_u32("latency_config_enabled", S_IRUGO | S_IWUSR, ecm_classifier_emesh_dentry, ++ (u32 *)&ecm_classifier_emesh_latency_config_enabled); + + /* + * Register for service prioritization notification update. +--- a/ecm_classifier_hyfi.c ++++ b/ecm_classifier_hyfi.c +@@ -1099,11 +1099,8 @@ int ecm_classifier_hyfi_rules_init(struc + goto classifier_task_cleanup; + } + +- if (!debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_hyfi_dentry, +- (u32 *)&ecm_classifier_hyfi_enabled)) { +- DEBUG_ERROR("Failed to create ecm hyfi classifier enabled file in debugfs\n"); +- goto classifier_task_cleanup; +- } ++ debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_hyfi_dentry, ++ (u32 *)&ecm_classifier_hyfi_enabled); + + if (!debugfs_create_file("cmd", S_IWUSR, ecm_classifier_hyfi_dentry, + NULL, &ecm_classifier_hyfi_cmd_fops)) { +--- a/ecm_classifier_mark.c ++++ b/ecm_classifier_mark.c +@@ -753,12 +753,8 @@ int ecm_classifier_mark_init(struct dent + return -1; + } + +- if (!debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_mark_dentry, +- (u32 *)&ecm_classifier_mark_enabled)) { +- DEBUG_ERROR("Failed to create mark enabled file in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_mark_dentry); +- return -1; +- } ++ debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_mark_dentry, ++ (u32 *)&ecm_classifier_mark_enabled); + + return 0; + } +--- a/ecm_classifier_ovs.c ++++ b/ecm_classifier_ovs.c +@@ -2200,12 +2200,8 @@ int ecm_classifier_ovs_init(struct dentr + return -1; + } + +- if (!debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_ovs_dentry, +- (u32 *)&ecm_classifier_ovs_enabled)) { +- DEBUG_ERROR("Failed to create ovs enabled file in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_ovs_dentry); +- return -1; +- } ++ debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_ovs_dentry, ++ (u32 *)&ecm_classifier_ovs_enabled); + + return 0; + } +--- a/ecm_classifier_pcc.c ++++ b/ecm_classifier_pcc.c +@@ -1308,12 +1308,8 @@ int ecm_classifier_pcc_init(struct dentr + return -1; + } + +- if (!debugfs_create_u32("enabled", S_IRUGO, ecm_classifier_pcc_dentry, +- (u32 *)&ecm_classifier_pcc_enabled)) { +- DEBUG_ERROR("Failed to create pcc enabled file in debugfs\n"); +- debugfs_remove_recursive(ecm_classifier_pcc_dentry); +- return -1; +- } ++ debugfs_create_u32("enabled", S_IRUGO, ecm_classifier_pcc_dentry, ++ (u32 *)&ecm_classifier_pcc_enabled); + + return 0; + } +--- a/ecm_conntrack_notifier.c ++++ b/ecm_conntrack_notifier.c +@@ -414,12 +414,8 @@ int ecm_conntrack_notifier_init(struct d + return -1; + } + +- if (!debugfs_create_u32("stop", S_IRUGO | S_IWUSR, ecm_conntrack_notifier_dentry, +- (u32 *)&ecm_conntrack_notifier_stopped)) { +- DEBUG_ERROR("Failed to create ecm conntrack notifier stopped file in debugfs\n"); +- debugfs_remove_recursive(ecm_conntrack_notifier_dentry); +- return -1; +- } ++ debugfs_create_u32("stop", S_IRUGO | S_IWUSR, ecm_conntrack_notifier_dentry, ++ (u32 *)&ecm_conntrack_notifier_stopped); + + #ifdef CONFIG_NF_CONNTRACK_EVENTS + /* +--- a/ecm_db/ecm_db_connection.c ++++ b/ecm_db/ecm_db_connection.c +@@ -3642,11 +3642,8 @@ static struct file_operations ecm_db_con + */ + bool ecm_db_connection_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("connection_count", S_IRUGO, dentry, +- (u32 *)&ecm_db_connection_count)) { +- DEBUG_ERROR("Failed to create ecm db connection count file in debugfs\n"); +- return false; +- } ++ debugfs_create_u32("connection_count", S_IRUGO, dentry, ++ (u32 *)&ecm_db_connection_count); + + if (!debugfs_create_file("connection_count_simple", S_IRUGO, dentry, + NULL, &ecm_db_connection_count_simple_fops)) { +--- a/ecm_db/ecm_db_host.c ++++ b/ecm_db/ecm_db_host.c +@@ -770,11 +770,8 @@ EXPORT_SYMBOL(ecm_db_host_alloc); + bool ecm_db_host_init(struct dentry *dentry) + { + +- if (!debugfs_create_u32("host_count", S_IRUGO, dentry, +- (u32 *)&ecm_db_host_count)) { +- DEBUG_ERROR("Failed to create ecm db host count file in debugfs\n"); +- return false;; +- } ++ debugfs_create_u32("host_count", S_IRUGO, dentry, ++ (u32 *)&ecm_db_host_count); + + ecm_db_host_table = vzalloc(sizeof(struct ecm_db_host_instance *) * ECM_DB_HOST_HASH_SLOTS); + if (!ecm_db_host_table) { +--- a/ecm_db/ecm_db_iface.c ++++ b/ecm_db/ecm_db_iface.c +@@ -3670,11 +3670,8 @@ EXPORT_SYMBOL(ecm_db_iface_alloc); + */ + bool ecm_db_iface_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("iface_count", S_IRUGO, dentry, +- (u32 *)&ecm_db_iface_count)) { +- DEBUG_ERROR("Failed to create ecm db iface count file in debugfs\n"); +- return false; +- } ++ debugfs_create_u32("iface_count", S_IRUGO, dentry, ++ (u32 *)&ecm_db_iface_count); + + return true; + } +--- a/ecm_db/ecm_db_mapping.c ++++ b/ecm_db/ecm_db_mapping.c +@@ -806,11 +806,8 @@ EXPORT_SYMBOL(ecm_db_mapping_alloc); + */ + bool ecm_db_mapping_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("mapping_count", S_IRUGO, dentry, +- (u32 *)&ecm_db_mapping_count)) { +- DEBUG_ERROR("Failed to create ecm db mapping count file in debugfs\n"); +- return false; +- } ++ debugfs_create_u32("mapping_count", S_IRUGO, dentry, ++ (u32 *)&ecm_db_mapping_count); + + ecm_db_mapping_table = vzalloc(sizeof(struct ecm_db_mapping_instance *) * ECM_DB_MAPPING_HASH_SLOTS); + if (!ecm_db_mapping_table) { +--- a/ecm_db/ecm_db_node.c ++++ b/ecm_db/ecm_db_node.c +@@ -1187,11 +1187,8 @@ keep_sni_conn: + */ + bool ecm_db_node_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("node_count", S_IRUGO, dentry, +- (u32 *)&ecm_db_node_count)) { +- DEBUG_ERROR("Failed to create ecm db node count file in debugfs\n"); +- return false; +- } ++ debugfs_create_u32("node_count", S_IRUGO, dentry, ++ (u32 *)&ecm_db_node_count); + + ecm_db_node_table = vzalloc(sizeof(struct ecm_db_node_instance *) * ECM_DB_NODE_HASH_SLOTS); + if (!ecm_db_node_table) { +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -332,7 +332,7 @@ static struct net_device *ecm_interface_ + struct net_device *dev; + + ECM_IP_ADDR_TO_NIN6_ADDR(addr6, addr); +- dev = (struct net_device *)ipv6_dev_find(&init_net, &addr6, 1); ++ dev = (struct net_device *)ipv6_dev_find_and_hold(&init_net, &addr6, 1); + return dev; + } + #endif +@@ -734,7 +734,7 @@ static bool ecm_interface_mac_addr_get_i + * Get the MAC address that corresponds to IP address given. + */ + ECM_IP_ADDR_TO_NIN6_ADDR(daddr, addr); +- local_dev = ipv6_dev_find(&init_net, &daddr, 1); ++ local_dev = ipv6_dev_find_and_hold(&init_net, &daddr, 1); + if (local_dev) { + DEBUG_TRACE("%pi6 is a local address\n", &daddr); + memcpy(mac_addr, dev->dev_addr, ETH_ALEN); +--- a/ecm_state.c ++++ b/ecm_state.c +@@ -899,17 +899,11 @@ int ecm_state_init(struct dentry *dentry + return -1; + } + +- if (!debugfs_create_u32("state_dev_major", S_IRUGO, ecm_state_dentry, +- (u32 *)&ecm_state_dev_major_id)) { +- DEBUG_ERROR("Failed to create ecm state dev major file in debugfs\n"); +- goto init_cleanup; +- } ++ debugfs_create_u32("state_dev_major", S_IRUGO, ecm_state_dentry, ++ (u32 *)&ecm_state_dev_major_id); + +- if (!debugfs_create_u32("state_file_output_mask", S_IRUGO | S_IWUSR, ecm_state_dentry, +- (u32 *)&ecm_state_file_output_mask)) { +- DEBUG_ERROR("Failed to create ecm state output mask file in debugfs\n"); +- goto init_cleanup; +- } ++ debugfs_create_u32("state_file_output_mask", S_IRUGO | S_IWUSR, ecm_state_dentry, ++ (u32 *)&ecm_state_file_output_mask); + + /* + * Register a char device that we will use to provide a dump of our state +--- a/frontends/ecm_front_end_common.c ++++ b/frontends/ecm_front_end_common.c +@@ -192,7 +192,7 @@ bool ecm_front_end_gre_proto_is_accel_al + return false; + } + } else { +- dev = ipv6_dev_find(&init_net, &(tuple->src.u3.in6), 1); ++ dev = ipv6_dev_find_and_hold(&init_net, &(tuple->src.u3.in6), 1); + if (dev) { + /* + * Source IP address is local +@@ -202,7 +202,7 @@ bool ecm_front_end_gre_proto_is_accel_al + return false; + } + +- dev = ipv6_dev_find(&init_net, &(tuple->dst.u3.in6), 1); ++ dev = ipv6_dev_find_and_hold(&init_net, &(tuple->dst.u3.in6), 1); + if (dev) { + /* + * Destination IP address is local +--- a/frontends/ecm_front_end_ipv4.c ++++ b/frontends/ecm_front_end_ipv4.c +@@ -376,11 +376,8 @@ void ecm_front_end_ipv4_stop(int num) + */ + int ecm_front_end_ipv4_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("front_end_ipv4_stop", S_IRUGO | S_IWUSR, dentry, +- (u32 *)&ecm_front_end_ipv4_stopped)) { +- DEBUG_ERROR("Failed to create ecm front end ipv4 stop file in debugfs\n"); +- return -1; +- } ++ debugfs_create_u32("front_end_ipv4_stop", S_IRUGO | S_IWUSR, dentry, ++ (u32 *)&ecm_front_end_ipv4_stopped); + + switch (ecm_front_end_type_get()) { + case ECM_FRONT_END_TYPE_NSS: +--- a/frontends/ecm_front_end_ipv6.c ++++ b/frontends/ecm_front_end_ipv6.c +@@ -255,11 +255,8 @@ void ecm_front_end_ipv6_stop(int num) + */ + int ecm_front_end_ipv6_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("front_end_ipv6_stop", S_IRUGO | S_IWUSR, dentry, +- (u32 *)&ecm_front_end_ipv6_stopped)) { +- DEBUG_ERROR("Failed to create ecm front end ipv6 stop file in debugfs\n"); +- return -1; +- } ++ debugfs_create_u32("front_end_ipv6_stop", S_IRUGO | S_IWUSR, dentry, ++ (u32 *)&ecm_front_end_ipv6_stopped); + + switch (ecm_front_end_type_get()) { + case ECM_FRONT_END_TYPE_NSS: +--- a/frontends/nss/ecm_nss_bond_notifier.c ++++ b/frontends/nss/ecm_nss_bond_notifier.c +@@ -240,12 +240,8 @@ int ecm_nss_bond_notifier_init(struct de + return -1; + } + +- if (!debugfs_create_u32("stop", S_IRUGO | S_IWUSR, ecm_nss_bond_notifier_dentry, +- (u32 *)&ecm_nss_bond_notifier_stopped)) { +- DEBUG_ERROR("Failed to create ecm bond notifier stopped file in debugfs\n"); +- debugfs_remove_recursive(ecm_nss_bond_notifier_dentry); +- return -1; +- } ++ debugfs_create_u32("stop", S_IRUGO | S_IWUSR, ecm_nss_bond_notifier_dentry, ++ (u32 *)&ecm_nss_bond_notifier_stopped); + + /* + * Register Link Aggregation callbacks with the bonding driver +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -2802,41 +2802,23 @@ int ecm_nss_ipv4_init(struct dentry *den + return result; + } + +- if (!debugfs_create_u32("no_action_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, +- (u32 *)&ecm_nss_ipv4_no_action_limit_default)) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 no_action_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("no_action_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, ++ (u32 *)&ecm_nss_ipv4_no_action_limit_default); + +- if (!debugfs_create_u32("driver_fail_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, +- (u32 *)&ecm_nss_ipv4_driver_fail_limit_default)) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 driver_fail_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("driver_fail_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, ++ (u32 *)&ecm_nss_ipv4_driver_fail_limit_default); + +- if (!debugfs_create_u32("nack_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, +- (u32 *)&ecm_nss_ipv4_nack_limit_default)) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 nack_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("nack_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, ++ (u32 *)&ecm_nss_ipv4_nack_limit_default); + +- if (!debugfs_create_u32("accelerated_count", S_IRUGO, ecm_nss_ipv4_dentry, +- (u32 *)&ecm_nss_ipv4_accelerated_count)) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 accelerated_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("accelerated_count", S_IRUGO, ecm_nss_ipv4_dentry, ++ (u32 *)&ecm_nss_ipv4_accelerated_count); + +- if (!debugfs_create_u32("pending_accel_count", S_IRUGO, ecm_nss_ipv4_dentry, +- (u32 *)&ecm_nss_ipv4_pending_accel_count)) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 pending_accel_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("pending_accel_count", S_IRUGO, ecm_nss_ipv4_dentry, ++ (u32 *)&ecm_nss_ipv4_pending_accel_count); + +- if (!debugfs_create_u32("pending_decel_count", S_IRUGO, ecm_nss_ipv4_dentry, +- (u32 *)&ecm_nss_ipv4_pending_decel_count)) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 pending_decel_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("pending_decel_count", S_IRUGO, ecm_nss_ipv4_dentry, ++ (u32 *)&ecm_nss_ipv4_pending_decel_count); + + if (!debugfs_create_file("accel_limit_mode", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, + NULL, &ecm_nss_ipv4_accel_limit_mode_fops)) { +@@ -2867,11 +2849,8 @@ int ecm_nss_ipv4_init(struct dentry *den + goto task_cleanup; + } + +- if (!debugfs_create_u32("vlan_passthrough_set", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, +- (u32 *)&ecm_nss_ipv4_vlan_passthrough_enable)) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 vlan passthrough file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("vlan_passthrough_set", S_IRUGO | S_IWUSR, ecm_nss_ipv4_dentry, ++ (u32 *)&ecm_nss_ipv4_vlan_passthrough_enable); + + #ifdef ECM_NON_PORTED_SUPPORT_ENABLE + if (!ecm_nss_non_ported_ipv4_debugfs_init(ecm_nss_ipv4_dentry)) { +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -2542,41 +2542,23 @@ int ecm_nss_ipv6_init(struct dentry *den + return result; + } + +- if (!debugfs_create_u32("no_action_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, +- (u32 *)&ecm_nss_ipv6_no_action_limit_default)) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 no_action_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("no_action_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, ++ (u32 *)&ecm_nss_ipv6_no_action_limit_default); + +- if (!debugfs_create_u32("driver_fail_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, +- (u32 *)&ecm_nss_ipv6_driver_fail_limit_default)) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 driver_fail_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("driver_fail_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, ++ (u32 *)&ecm_nss_ipv6_driver_fail_limit_default); + +- if (!debugfs_create_u32("nack_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, +- (u32 *)&ecm_nss_ipv6_nack_limit_default)) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 nack_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("nack_limit_default", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, ++ (u32 *)&ecm_nss_ipv6_nack_limit_default); + +- if (!debugfs_create_u32("accelerated_count", S_IRUGO, ecm_nss_ipv6_dentry, +- (u32 *)&ecm_nss_ipv6_accelerated_count)) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 accelerated_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("accelerated_count", S_IRUGO, ecm_nss_ipv6_dentry, ++ (u32 *)&ecm_nss_ipv6_accelerated_count); + +- if (!debugfs_create_u32("pending_accel_count", S_IRUGO, ecm_nss_ipv6_dentry, +- (u32 *)&ecm_nss_ipv6_pending_accel_count)) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 pending_accel_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("pending_accel_count", S_IRUGO, ecm_nss_ipv6_dentry, ++ (u32 *)&ecm_nss_ipv6_pending_accel_count); + +- if (!debugfs_create_u32("pending_decel_count", S_IRUGO, ecm_nss_ipv6_dentry, +- (u32 *)&ecm_nss_ipv6_pending_decel_count)) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 pending_decel_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("pending_decel_count", S_IRUGO, ecm_nss_ipv6_dentry, ++ (u32 *)&ecm_nss_ipv6_pending_decel_count); + + if (!debugfs_create_file("accel_limit_mode", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, + NULL, &ecm_nss_ipv6_accel_limit_mode_fops)) { +@@ -2607,11 +2589,8 @@ int ecm_nss_ipv6_init(struct dentry *den + goto task_cleanup; + } + +- if (!debugfs_create_u32("vlan_passthrough_set", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, +- (u32 *)&ecm_nss_ipv6_vlan_passthrough_enable)) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 vlan passthrough file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("vlan_passthrough_set", S_IRUGO | S_IWUSR, ecm_nss_ipv6_dentry, ++ (u32 *)&ecm_nss_ipv6_vlan_passthrough_enable); + + #ifdef ECM_NON_PORTED_SUPPORT_ENABLE + if (!ecm_nss_non_ported_ipv6_debugfs_init(ecm_nss_ipv6_dentry)) { +--- a/frontends/nss/ecm_nss_multicast_ipv4.c ++++ b/frontends/nss/ecm_nss_multicast_ipv4.c +@@ -4139,11 +4139,8 @@ void ecm_nss_multicast_ipv4_stop(int num + */ + int ecm_nss_multicast_ipv4_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("ecm_nss_multicast_ipv4_stop", S_IRUGO | S_IWUSR, dentry, +- (u32 *)&ecm_front_end_ipv4_mc_stopped)) { +- DEBUG_ERROR("Failed to create ecm front end ipv4 mc stop file in debugfs\n"); +- return -1; +- } ++ debugfs_create_u32("ecm_nss_multicast_ipv4_stop", S_IRUGO | S_IWUSR, dentry, ++ (u32 *)&ecm_front_end_ipv4_mc_stopped); + + /* + * Register multicast update callback to MCS snooper +--- a/frontends/nss/ecm_nss_multicast_ipv6.c ++++ b/frontends/nss/ecm_nss_multicast_ipv6.c +@@ -3939,11 +3939,8 @@ void ecm_nss_multicast_ipv6_stop(int num + */ + int ecm_nss_multicast_ipv6_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("ecm_nss_multicast_ipv6_stop", S_IRUGO | S_IWUSR, dentry, +- (u32 *)&ecm_front_end_ipv6_mc_stopped)) { +- DEBUG_ERROR("Failed to create ecm front end ipv6 mc stop file in debugfs\n"); +- return -1; +- } ++ debugfs_create_u32("ecm_nss_multicast_ipv6_stop", S_IRUGO | S_IWUSR, dentry, ++ (u32 *)&ecm_front_end_ipv6_mc_stopped); + + /* + * Register multicast update callback to MCS snooper +--- a/frontends/nss/ecm_nss_non_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_non_ported_ipv4.c +@@ -2615,11 +2615,8 @@ done: + */ + bool ecm_nss_non_ported_ipv4_debugfs_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("non_ported_accelerated_count", S_IRUGO, dentry, +- (u32 *)&ecm_nss_non_ported_ipv4_accelerated_count)) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 non_ported_accelerated_count file in debugfs\n"); +- return false; +- } ++ debugfs_create_u32("non_ported_accelerated_count", S_IRUGO, dentry, ++ (u32 *)&ecm_nss_non_ported_ipv4_accelerated_count); + + return true; + } +--- a/frontends/nss/ecm_nss_non_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_non_ported_ipv6.c +@@ -2329,11 +2329,8 @@ done: + */ + bool ecm_nss_non_ported_ipv6_debugfs_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("non_ported_accelerated_count", S_IRUGO, dentry, +- (u32 *)&ecm_nss_non_ported_ipv6_accelerated_count)) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 non_ported_accelerated_count file in debugfs\n"); +- return false; +- } ++ debugfs_create_u32("non_ported_accelerated_count", S_IRUGO, dentry, ++ (u32 *)&ecm_nss_non_ported_ipv6_accelerated_count); + + return true; + } +--- a/frontends/nss/ecm_nss_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_ported_ipv4.c +@@ -2944,12 +2944,8 @@ bool ecm_nss_ported_ipv4_debugfs_init(st + return false; + } + +- if (!debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, +- &ecm_nss_ported_ipv4_accelerated_count[ECM_NSS_PORTED_IPV4_PROTO_TCP])) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 tcp_accelerated_count file in debugfs\n"); +- debugfs_remove(udp_dentry); +- return false; +- } ++ debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, ++ &ecm_nss_ported_ipv4_accelerated_count[ECM_NSS_PORTED_IPV4_PROTO_TCP]); + + return true; + } +--- a/frontends/nss/ecm_nss_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_ported_ipv6.c +@@ -2732,12 +2732,8 @@ bool ecm_nss_ported_ipv6_debugfs_init(st + return false; + } + +- if (!debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, +- &ecm_nss_ported_ipv6_accelerated_count[ECM_NSS_PORTED_IPV6_PROTO_TCP])) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 tcp_accelerated_count file in debugfs\n"); +- debugfs_remove(udp_dentry); +- return false; +- } ++ debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, ++ &ecm_nss_ported_ipv6_accelerated_count[ECM_NSS_PORTED_IPV6_PROTO_TCP]); + + return true; + } +--- a/frontends/sfe/ecm_sfe_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ipv4.c +@@ -1808,48 +1808,27 @@ int ecm_sfe_ipv4_init(struct dentry *den + } + + #ifdef CONFIG_XFRM +- if (!debugfs_create_u32("reject_acceleration_for_ipsec", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, +- (u32 *)&ecm_sfe_ipv4_reject_acceleration_for_ipsec)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 reject_acceleration_for_ipsec file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("reject_acceleration_for_ipsec", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, ++ (u32 *)&ecm_sfe_ipv4_reject_acceleration_for_ipsec); + #endif + +- if (!debugfs_create_u32("no_action_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, +- (u32 *)&ecm_sfe_ipv4_no_action_limit_default)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 no_action_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("no_action_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, ++ (u32 *)&ecm_sfe_ipv4_no_action_limit_default); + +- if (!debugfs_create_u32("driver_fail_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, +- (u32 *)&ecm_sfe_ipv4_driver_fail_limit_default)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 driver_fail_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("driver_fail_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, ++ (u32 *)&ecm_sfe_ipv4_driver_fail_limit_default); + +- if (!debugfs_create_u32("nack_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, +- (u32 *)&ecm_sfe_ipv4_nack_limit_default)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 nack_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("nack_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, ++ (u32 *)&ecm_sfe_ipv4_nack_limit_default); + +- if (!debugfs_create_u32("accelerated_count", S_IRUGO, ecm_sfe_ipv4_dentry, +- (u32 *)&ecm_sfe_ipv4_accelerated_count)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 accelerated_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("accelerated_count", S_IRUGO, ecm_sfe_ipv4_dentry, ++ (u32 *)&ecm_sfe_ipv4_accelerated_count); + +- if (!debugfs_create_u32("pending_accel_count", S_IRUGO, ecm_sfe_ipv4_dentry, +- (u32 *)&ecm_sfe_ipv4_pending_accel_count)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 pending_accel_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("pending_accel_count", S_IRUGO, ecm_sfe_ipv4_dentry, ++ (u32 *)&ecm_sfe_ipv4_pending_accel_count); + +- if (!debugfs_create_u32("pending_decel_count", S_IRUGO, ecm_sfe_ipv4_dentry, +- (u32 *)&ecm_sfe_ipv4_pending_decel_count)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 pending_decel_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("pending_decel_count", S_IRUGO, ecm_sfe_ipv4_dentry, ++ (u32 *)&ecm_sfe_ipv4_pending_decel_count); + + if (!debugfs_create_file("accel_limit_mode", S_IRUGO | S_IWUSR, ecm_sfe_ipv4_dentry, + NULL, &ecm_sfe_ipv4_accel_limit_mode_fops)) { +--- a/frontends/sfe/ecm_sfe_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ipv6.c +@@ -1532,48 +1532,27 @@ int ecm_sfe_ipv6_init(struct dentry *den + } + + #ifdef CONFIG_XFRM +- if (!debugfs_create_u32("reject_acceleration_for_ipsec", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, +- (u32 *)&ecm_sfe_ipv6_reject_acceleration_for_ipsec)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 reject_acceleration_for_ipsec file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("reject_acceleration_for_ipsec", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, ++ (u32 *)&ecm_sfe_ipv6_reject_acceleration_for_ipsec); + #endif + +- if (!debugfs_create_u32("no_action_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, +- (u32 *)&ecm_sfe_ipv6_no_action_limit_default)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 no_action_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("no_action_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, ++ (u32 *)&ecm_sfe_ipv6_no_action_limit_default); + +- if (!debugfs_create_u32("driver_fail_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, +- (u32 *)&ecm_sfe_ipv6_driver_fail_limit_default)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 driver_fail_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("driver_fail_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, ++ (u32 *)&ecm_sfe_ipv6_driver_fail_limit_default); + +- if (!debugfs_create_u32("nack_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, +- (u32 *)&ecm_sfe_ipv6_nack_limit_default)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 nack_limit_default file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("nack_limit_default", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, ++ (u32 *)&ecm_sfe_ipv6_nack_limit_default); + +- if (!debugfs_create_u32("accelerated_count", S_IRUGO, ecm_sfe_ipv6_dentry, +- (u32 *)&ecm_sfe_ipv6_accelerated_count)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 accelerated_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("accelerated_count", S_IRUGO, ecm_sfe_ipv6_dentry, ++ (u32 *)&ecm_sfe_ipv6_accelerated_count); + +- if (!debugfs_create_u32("pending_accel_count", S_IRUGO, ecm_sfe_ipv6_dentry, +- (u32 *)&ecm_sfe_ipv6_pending_accel_count)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 pending_accel_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("pending_accel_count", S_IRUGO, ecm_sfe_ipv6_dentry, ++ (u32 *)&ecm_sfe_ipv6_pending_accel_count); + +- if (!debugfs_create_u32("pending_decel_count", S_IRUGO, ecm_sfe_ipv6_dentry, +- (u32 *)&ecm_sfe_ipv6_pending_decel_count)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 pending_decel_count file in debugfs\n"); +- goto task_cleanup; +- } ++ debugfs_create_u32("pending_decel_count", S_IRUGO, ecm_sfe_ipv6_dentry, ++ (u32 *)&ecm_sfe_ipv6_pending_decel_count); + + if (!debugfs_create_file("accel_limit_mode", S_IRUGO | S_IWUSR, ecm_sfe_ipv6_dentry, + NULL, &ecm_sfe_ipv6_accel_limit_mode_fops)) { +--- a/frontends/sfe/ecm_sfe_non_ported_ipv4.c ++++ b/frontends/sfe/ecm_sfe_non_ported_ipv4.c +@@ -2284,11 +2284,8 @@ done: + */ + bool ecm_sfe_non_ported_ipv4_debugfs_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("non_ported_accelerated_count", S_IRUGO, dentry, +- (u32 *)&ecm_sfe_non_ported_ipv4_accelerated_count)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 non_ported_accelerated_count file in debugfs\n"); +- return false; +- } ++ debugfs_create_u32("non_ported_accelerated_count", S_IRUGO, dentry, ++ (u32 *)&ecm_sfe_non_ported_ipv4_accelerated_count); + + return true; + } +--- a/frontends/sfe/ecm_sfe_non_ported_ipv6.c ++++ b/frontends/sfe/ecm_sfe_non_ported_ipv6.c +@@ -2083,11 +2083,8 @@ done: + */ + bool ecm_sfe_non_ported_ipv6_debugfs_init(struct dentry *dentry) + { +- if (!debugfs_create_u32("non_ported_accelerated_count", S_IRUGO, dentry, +- (u32 *)&ecm_sfe_non_ported_ipv6_accelerated_count)) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 non_ported_accelerated_count file in debugfs\n"); +- return false; +- } ++ debugfs_create_u32("non_ported_accelerated_count", S_IRUGO, dentry, ++ (u32 *)&ecm_sfe_non_ported_ipv6_accelerated_count); + + return true; + } +--- a/frontends/sfe/ecm_sfe_ported_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv4.c +@@ -2528,12 +2528,8 @@ bool ecm_sfe_ported_ipv4_debugfs_init(st + return false; + } + +- if (!debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, +- &ecm_sfe_ported_ipv4_accelerated_count[ECM_SFE_PORTED_IPV4_PROTO_TCP])) { +- DEBUG_ERROR("Failed to create ecm sfe ipv4 tcp_accelerated_count file in debugfs\n"); +- debugfs_remove(udp_dentry); +- return false; +- } ++ debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, ++ &ecm_sfe_ported_ipv4_accelerated_count[ECM_SFE_PORTED_IPV4_PROTO_TCP]); + + return true; + } +--- a/frontends/sfe/ecm_sfe_ported_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv6.c +@@ -2374,12 +2374,8 @@ bool ecm_sfe_ported_ipv6_debugfs_init(st + return false; + } + +- if (!debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, +- &ecm_sfe_ported_ipv6_accelerated_count[ECM_SFE_PORTED_IPV6_PROTO_TCP])) { +- DEBUG_ERROR("Failed to create ecm sfe ipv6 tcp_accelerated_count file in debugfs\n"); +- debugfs_remove(udp_dentry); +- return false; +- } ++ debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, ++ &ecm_sfe_ported_ipv6_accelerated_count[ECM_SFE_PORTED_IPV6_PROTO_TCP]); + + return true; + } diff --git a/root/package/firmware/nss/qca-nss-ecm-64/patches/203-rework-nfct-notification.patch b/root/package/firmware/nss/qca-nss-ecm-64/patches/203-rework-nfct-notification.patch new file mode 100644 index 00000000..72005cd7 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/patches/203-rework-nfct-notification.patch @@ -0,0 +1,25 @@ +--- a/ecm_conntrack_notifier.c ++++ b/ecm_conntrack_notifier.c +@@ -421,7 +421,11 @@ int ecm_conntrack_notifier_init(struct d + /* + * Eventing subsystem is available so we register a notifier hook to get fast notifications of expired connections + */ ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ result = nf_conntrack_register_chain_notifier(&init_net, &ecm_conntrack_notifier); ++#else + result = nf_conntrack_register_notifier(&init_net, &ecm_conntrack_notifier); ++#endif + if (result < 0) { + DEBUG_ERROR("Can't register nf notifier hook.\n"); + debugfs_remove_recursive(ecm_conntrack_notifier_dentry); +@@ -439,7 +443,9 @@ EXPORT_SYMBOL(ecm_conntrack_notifier_ini + void ecm_conntrack_notifier_exit(void) + { + DEBUG_INFO("ECM Conntrack Notifier exit\n"); +-#ifdef CONFIG_NF_CONNTRACK_EVENTS ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ nf_conntrack_unregister_chain_notifier(&init_net, &ecm_conntrack_notifier); ++#else + nf_conntrack_unregister_notifier(&init_net, &ecm_conntrack_notifier); + #endif + /* diff --git a/root/package/firmware/nss/qca-nss-ecm-64/patches/204-More-compile-fixes.patch b/root/package/firmware/nss/qca-nss-ecm-64/patches/204-More-compile-fixes.patch new file mode 100644 index 00000000..a998d829 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/patches/204-More-compile-fixes.patch @@ -0,0 +1,58 @@ +From e6d701c0d454d841366c556b2ef07a5203ffb35d Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 21 May 2021 21:41:31 +0200 +Subject: [PATCH] More compile fixes + +More runtime compile fixes. + +Signed-off-by: Robert Marko +--- + frontends/nss/ecm_nss_ported_ipv4.c | 12 +++--------- + frontends/nss/ecm_nss_ported_ipv6.c | 12 +++--------- + 2 files changed, 6 insertions(+), 18 deletions(-) + +diff --git a/frontends/nss/ecm_nss_ported_ipv4.c b/frontends/nss/ecm_nss_ported_ipv4.c +index 3522f0f..7f5fcd1 100644 +--- a/frontends/nss/ecm_nss_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_ported_ipv4.c +@@ -2935,14 +2935,8 @@ done: + */ + bool ecm_nss_ported_ipv4_debugfs_init(struct dentry *dentry) + { +- struct dentry *udp_dentry; +- +- udp_dentry = debugfs_create_u32("udp_accelerated_count", S_IRUGO, dentry, ++ debugfs_create_u32("udp_accelerated_count", S_IRUGO, dentry, + &ecm_nss_ported_ipv4_accelerated_count[ECM_NSS_PORTED_IPV4_PROTO_UDP]); +- if (!udp_dentry) { +- DEBUG_ERROR("Failed to create ecm nss ipv4 udp_accelerated_count file in debugfs\n"); +- return false; +- } + + debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, + &ecm_nss_ported_ipv4_accelerated_count[ECM_NSS_PORTED_IPV4_PROTO_TCP]); +diff --git a/frontends/nss/ecm_nss_ported_ipv6.c b/frontends/nss/ecm_nss_ported_ipv6.c +index f43ac95..e0f779c 100644 +--- a/frontends/nss/ecm_nss_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_ported_ipv6.c + /* + * ecm_nss_ported_ipv6_connection_callback() +@@ -2723,14 +2723,8 @@ done: + */ + bool ecm_nss_ported_ipv6_debugfs_init(struct dentry *dentry) + { +- struct dentry *udp_dentry; +- +- udp_dentry = debugfs_create_u32("udp_accelerated_count", S_IRUGO, dentry, ++ debugfs_create_u32("udp_accelerated_count", S_IRUGO, dentry, + &ecm_nss_ported_ipv6_accelerated_count[ECM_NSS_PORTED_IPV6_PROTO_UDP]); +- if (!udp_dentry) { +- DEBUG_ERROR("Failed to create ecm nss ipv6 udp_accelerated_count file in debugfs\n"); +- return false; +- } + + debugfs_create_u32("tcp_accelerated_count", S_IRUGO, dentry, + &ecm_nss_ported_ipv6_accelerated_count[ECM_NSS_PORTED_IPV6_PROTO_TCP]); +-- +2.31.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm-64/patches/205-resolve-high-load.patch b/root/package/firmware/nss/qca-nss-ecm-64/patches/205-resolve-high-load.patch new file mode 100644 index 00000000..f4106a35 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm-64/patches/205-resolve-high-load.patch @@ -0,0 +1,61 @@ +From 6924b71ed809b37fffd74d6428a8ca83e5919746 Mon Sep 17 00:00:00 2001 +From: Dirk Buchwalder +Date: Sun, 27 Jun 2021 16:52:39 +0200 +Subject: [PATCH] qca-nss-ecm: resolve the cpu high load regarding ecm + +If using ECM, cpu load goes up (around 1.0) and stucks there. +This is due to using uninterruptible sleep function, +the patch changes this to interruptible sleep function. + +Signed-off-by: Dirk Buchwalder buchwalder@posteo.de +--- + frontends/nss/ecm_nss_ipv4.c | 4 ++-- + frontends/nss/ecm_nss_ipv6.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c +index e00553c..94b39cd 100644 +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -2471,7 +2471,7 @@ static void ecm_nss_ipv4_stats_sync_req_work(struct work_struct *work) + } + spin_unlock_bh(&ecm_nss_ipv4_lock); + +- usleep_range(ECM_NSS_IPV4_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV4_STATS_SYNC_UDELAY); ++ msleep_interruptible(ECM_NSS_IPV4_STATS_SYNC_UDELAY / 1000); + + /* + * If index is 0, we are starting a new round, but if we still have time remain +@@ -2485,7 +2485,7 @@ static void ecm_nss_ipv4_stats_sync_req_work(struct work_struct *work) + } + + if (time_after(ecm_nss_ipv4_next_req_time, current_jiffies)) { +- msleep(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies)); ++ msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies)); + } + ecm_nss_ipv4_roll_check_jiffies = jiffies; + ecm_nss_ipv4_next_req_time = ecm_nss_ipv4_roll_check_jiffies + ECM_NSS_IPV4_STATS_SYNC_PERIOD; +diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c +index 82e739f..30af050 100644 +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -2210,7 +2210,7 @@ static void ecm_nss_ipv6_stats_sync_req_work(struct work_struct *work) + } + spin_unlock_bh(&ecm_nss_ipv6_lock); + +- usleep_range(ECM_NSS_IPV6_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV6_STATS_SYNC_UDELAY); ++ msleep_interruptible(ECM_NSS_IPV6_STATS_SYNC_UDELAY / 1000); + + /* + * If index is 0, we are starting a new round, but if we still have time remain +@@ -2224,7 +2224,7 @@ static void ecm_nss_ipv6_stats_sync_req_work(struct work_struct *work) + } + + if (time_after(ecm_nss_ipv6_next_req_time, current_jiffies)) { +- msleep(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies)); ++ msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies)); + } + ecm_nss_ipv6_roll_check_jiffies = jiffies; + ecm_nss_ipv6_next_req_time = ecm_nss_ipv6_roll_check_jiffies + ECM_NSS_IPV6_STATS_SYNC_PERIOD; +-- +2.31.1 diff --git a/root/package/firmware/nss/qca-nss-ecm/Makefile b/root/package/firmware/nss/qca-nss-ecm/Makefile new file mode 100644 index 00000000..a570c955 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/Makefile @@ -0,0 +1,273 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-nss-ecm +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/qca-nss-ecm +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=9228212b4238c0d8c296f795948ede8f2ca0242e +PKG_MIRROR_HASH:=02fe4c86c8c88fb15704b1b253ab756a2658f24ce5db64a7909cb60bf9c1cdff + +LOCAL_VARIANT=$(patsubst qca-nss-ecm-%,%,$(patsubst qca-nss-ecm-%,%,$(BUILD_VARIANT))) +include $(INCLUDE_DIR)/package.mk + +ifeq ($(CONFIG_QCA_NSS_ECM_EXAMPLES_PCC),y) + FILES_EXAMPLES=$(PKG_BUILD_DIR)/examples/ecm_pcc_test.ko +endif + +ifeq ($(CONFIG_QCA_NSS_ECM_EXAMPLES_MARK),y) + FILES_EXAMPLES+=$(PKG_BUILD_DIR)/examples/ecm_mark_test.ko +endif + +#Explicitly enable OVS external module, if ovsmgr is enabled. +ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),) +CONFIG_QCA_NSS_ECM_OVS=y +endif + +ifeq ($(CONFIG_QCA_NSS_ECM_OVS),y) + FILES_EXAMPLES+=$(PKG_BUILD_DIR)/examples/ecm_ovs.ko +endif + +define KernelPackage/qca-nss-ecm/Default + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + DEPENDS:=+TARGET_ipq806x:kmod-qca-nss-drv \ + +TARGET_ipq_ipq806x:kmod-qca-nss-drv \ + +TARGET_ipq_ipq807x:kmod-qca-nss-drv \ + +TARGET_ipq_ipq807x_64:kmod-qca-nss-drv \ + +TARGET_ipq807x:kmod-qca-nss-drv \ + +TARGET_ipq807x_64:kmod-qca-nss-drv \ + +TARGET_ipq_ipq60xx:kmod-qca-nss-drv \ + +TARGET_ipq_ipq60xx_64:kmod-qca-nss-drv \ + +TARGET_ipq_ipq50xx:kmod-qca-nss-drv \ + +TARGET_ipq_ipq50xx_64:kmod-qca-nss-drv \ + +iptables-mod-extra +kmod-ipt-conntrack \ + +kmod-pppoe @LINUX_5_4 \ + +kmod-ipsec + TITLE:=QCA NSS Enhanced Connection Manager (ECM) + FILES:=$(PKG_BUILD_DIR)/*.ko $(FILES_EXAMPLES) + KCONFIG:=CONFIG_BRIDGE_NETFILTER=y \ + CONFIG_NF_CONNTRACK_EVENTS=y \ + CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y \ + CONFIG_NF_CONNTRACK_DSCPREMARK_EXT=y + MENU:=1 + PROVIDES:=kmod-qca-nss-ecm +endef + +define KernelPackage/qca-nss-ecm/Description/Default +This package contains the QCA NSS Enhanced Connection Manager +endef + +define KernelPackage/qca-nss-ecm/Default/install + $(INSTALL_DIR) $(1)/etc/firewall.d $(1)/etc/init.d $(1)/usr/bin $(1)/lib/netifd/offload $(1)/etc/config $(1)/etc/uci-defaults $(1)/etc/sysctl.d + $(INSTALL_DATA) ./files/qca-nss-ecm.firewall $(1)/etc/firewall.d/qca-nss-ecm + $(INSTALL_BIN) ./files/qca-nss-ecm.init $(1)/etc/init.d/qca-nss-ecm + $(INSTALL_BIN) ./files/ecm_dump.sh $(1)/usr/bin/ + $(INSTALL_BIN) ./files/on-demand-down $(1)/lib/netifd/offload/on-demand-down + $(INSTALL_DATA) ./files/qca-nss-ecm.uci $(1)/etc/config/ecm + $(INSTALL_DATA) ./files/qca-nss-ecm.defaults $(1)/etc/uci-defaults/99-qca-nss-ecm + $(INSTALL_BIN) ./files/qca-nss-ecm.sysctl $(1)/etc/sysctl.d/qca-nss-ecm.conf +ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),256) + echo 'net.netfilter.nf_conntrack_max=2048' >> $(1)/etc/sysctl.d/qca-nss-ecm.conf +endif +ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),512) + echo 'net.netfilter.nf_conntrack_max=8192' >> $(1)/etc/sysctl.d/qca-nss-ecm.conf +endif +endef + +define KernelPackage/qca-nss-ecm-standard + $(call KernelPackage/qca-nss-ecm/Default) + VARIANT:=standard +endef + +define KernelPackage/qca-nss-ecm-standard/Description + $(call KernelPackage/qca-nss-ecm/Description/Default) +endef + +define KernelPackage/qca-nss-ecm-standard/install +$(call KernelPackage/qca-nss-ecm/Default/install, $(1)) +endef + +# Variant with additional features enabled for premium profile +define KernelPackage/qca-nss-ecm-premium/Default +$(call KernelPackage/qca-nss-ecm/Default) + TITLE+= (with premium features) + VARIANT:=premium + DEPENDS+=+kmod-nat46 \ + +kmod-l2tp +kmod-pppol2tp +kmod-pptp \ + +kmod-bonding +endef + +define KernelPackage/qca-nss-ecm-premium/Description/Default +$(call KernelPackage/qca-nss-ecm/Description/Default) +with the premium features enabled +endef + +define KernelPackage/qca-nss-ecm-premium/Default/install +$(call KernelPackage/qca-nss-ecm/install) +endef + +define KernelPackage/qca-nss-ecm-premium +$(call KernelPackage/qca-nss-ecm-premium/Default) +endef + +define KernelPackage/qca-nss-ecm-premium/Description +$(call KernelPackage/qca-nss-ecm-premium/Description/Default) +endef + +define KernelPackage/qca-nss-ecm-premium/install +$(call KernelPackage/qca-nss-ecm-standard/install, $(1)) +endef + +# Variant with additional features enabled for noload profile +define KernelPackage/qca-nss-ecm-noload + $(call KernelPackage/qca-nss-ecm/Default) + TITLE+= (with noload features) + PROVIDES:=kmod-qca-nss-ecm + VARIANT:=noload + DEPENDS+=+kmod-l2tp +kmod-pppol2tp +kmod-pptp \ + +kmod-bonding +endef + +define KernelPackage/qca-nss-ecm-noload/Description + $(call KernelPackage/qca-nss-ecm/Description/Default) + When selected, this package installs the driver but does not load it at init. +endef + +define KernelPackage/qca-nss-ecm-noload/install +$(call KernelPackage/qca-nss-ecm/Default/install, $(1)) + # + # Remove the START line from the init script, so that the symlink + # in the /etc/rc.d directory is not created. + # + sed -i '/START=/d' $(1)/etc/init.d/qca-nss-ecm +endef + +define KernelPackage/qca-nss-ecm-premium-noload + $(call KernelPackage/qca-nss-ecm-premium/Default) + PROVIDES:=kmod-qca-nss-ecm-premium +endef + +define KernelPackage/qca-nss-ecm-premium-noload/Description + $(call KernelPackage/qca-nss-ecm-premium/Description/Default) + When selected, this package installs the driver but does not load it at init. +endef + +define KernelPackage/qca-nss-ecm-premium-noload/install +$(call KernelPackage/qca-nss-ecm-premium/Default/install, $(1)) +endef + +define Build/InstallDev/qca-nss-ecm + $(INSTALL_DIR) $(1)/usr/include/qca-nss-ecm + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-ecm/ +endef + +define Build/InstallDev + $(call Build/InstallDev/qca-nss-ecm,$(1)) +endef + +EXTRA_CFLAGS+= \ + -I$(STAGING_DIR)/usr/include/hyfibr \ + -I$(STAGING_DIR)/usr/include/qca-mcs \ + -I$(STAGING_DIR)/usr/include/qca-nss-drv \ + -I$(STAGING_DIR)/usr/include/shortcut-fe \ + -I$(STAGING_DIR)/usr/include/nat46 + +ECM_MAKE_OPTS:=ECM_CLASSIFIER_HYFI_ENABLE=y +ifneq ($(LOCAL_VARIANT),standard) +ECM_MAKE_OPTS+=ECM_MULTICAST_ENABLE=y \ + ECM_INTERFACE_IPSEC_ENABLE=y \ + # ECM_INTERFACE_PPTP_ENABLE=y \ + ECM_INTERFACE_L2TPV2_ENABLE=y \ + ECM_INTERFACE_GRE_TAP_ENABLE=y \ + ECM_INTERFACE_GRE_TUN_ENABLE=y \ + ECM_INTERFACE_SIT_ENABLE=y \ + ECM_INTERFACE_TUNIPIP6_ENABLE=y \ + ECM_INTERFACE_RAWIP_ENABLE=y + +ifeq ($(CONFIG_TARGET_ipq_ipq40xx)$(CONFIG_TARGET_ipq40xx),) +ECM_MAKE_OPTS+=ECM_INTERFACE_BOND_ENABLE=y +endif +endif + +ifeq ($(filter $(CONFIG_KERNEL_IPQ_MEM_PROFILE), 256),) +ECM_MAKE_OPTS+=ECM_XFRM_ENABLE=y +endif + +# ifneq ($(CONFIG_PACKAGE_kmod-nat46),) +# ECM_MAKE_OPTS+=ECM_INTERFACE_MAP_T_ENABLE=y +# endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-ovpn-link),) +ECM_MAKE_OPTS+=ECM_INTERFACE_OVPN_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vxlanmgr),) +ECM_MAKE_OPTS+=ECM_INTERFACE_VXLAN_ENABLE=y +endif + +ifneq ($(CONFIG_PACKAGE_kmod-qca-ovsmgr),) +ECM_MAKE_OPTS+=ECM_INTERFACE_OVS_BRIDGE_ENABLE=y \ + ECM_CLASSIFIER_OVS_ENABLE=y +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-ovsmgr +endif + +# Keeping default as ipq806x for branches that does not have subtarget framework +ifeq ($(CONFIG_TARGET_ipq),y) +subtarget:=$(SUBTARGET) +else +subtarget:=$(CONFIG_TARGET_BOARD) +endif + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-nss-ecm + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-ecm +endef + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" $(strip $(ECM_MAKE_OPTS)) \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(subtarget)" \ + EXAMPLES_BUILD_PCC="$(CONFIG_QCA_NSS_ECM_EXAMPLES_PCC)" \ + EXAMPLES_BUILD_MARK="$(CONFIG_QCA_NSS_ECM_EXAMPLES_MARK)" \ + EXAMPLES_BUILD_OVS="$(CONFIG_QCA_NSS_ECM_OVS)" \ + ECM_FRONT_END_SFE_ENABLE="$(CONFIG_QCA_ECM_SFE_SUPPORT)" \ + modules +endef + +define KernelPackage/qca-nss-ecm-premium/config +menu "ECM Configuration" + depends on PACKAGE_kmod_qca-nss-ecm-premium + + config QCA_NSS_ECM_EXAMPLES_PCC + bool "Build PCC usage example" + help + Selecting this will build the PCC classifier usage example module. + default n + + config QCA_NSS_ECM_EXAMPLES_MARK + bool "Build Mark classifier usage example" + help + Selecting this will build the Mark classifier usage example module. + default n + + config QCA_NSS_ECM_OVS + bool "Build OVS classifier external module" + help + Selecting this will build the OVS classifier external module. + default n + + config QCA_ECM_SFE_SUPPORT + bool "Add SFE support to ECM driver" + default n +endmenu +endef + +$(eval $(call KernelPackage,qca-nss-ecm-noload)) +$(eval $(call KernelPackage,qca-nss-ecm-standard)) +$(eval $(call KernelPackage,qca-nss-ecm-premium-noload)) +$(eval $(call KernelPackage,qca-nss-ecm-premium)) diff --git a/root/package/firmware/nss/qca-nss-ecm/files/ecm_dump.sh b/root/package/firmware/nss/qca-nss-ecm/files/ecm_dump.sh new file mode 100644 index 00000000..dbf7de75 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/files/ecm_dump.sh @@ -0,0 +1,95 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +ECM_MODULE=${1:-ecm_state} +MOUNT_ROOT=/dev/ecm + +# +# usage: ecm_dump.sh [module=ecm_db] +# +# with no parameters, ecm_dump.sh will attempt to mount the +# ecm_db state file and cat its contents. +# +# example with a parameter: ecm_dump.sh ecm_classifier_default +# +# this will cause ecm_dump to attempt to find and mount the state +# file for the ecm_classifier_default module, and if successful +# cat the contents. +# + +# this is one of the state files, which happens to be the +# last module started in ecm +ECM_STATE=/sys/kernel/debug/ecm/ecm_state/state_dev_major + +# tests to see if ECM is up and ready to receive commands. +# returns 0 if ECM is fully up and ready, else 1 +ecm_is_ready() { + if [ ! -e "${ECM_STATE}" ] + then + return 1 + fi + return 0 +} + +# +# module_state_mount(module_name) +# Mounts the state file of the module, if supported +# +module_state_mount() { + local module_name=$1 + local mount_dir=$2 + local state_file="/sys/kernel/debug/ecm/${module_name}/state_dev_major" + + if [ -e "${mount_dir}/${module_name}" ] + then + # already mounted + return 0 + fi + + #echo "Mount state file for $module_name ..." + if [ ! -e "$state_file" ] + then + #echo "... $module_name does not support state" + return 1 + fi + + local major="`cat $state_file`" + #echo "... Mounting state $state_file with major: $major" + mknod "${mount_dir}/${module_name}" c $major 0 +} + +# +# main +# +ecm_is_ready || { + #echo "ECM is not running" + exit 1 +} + +# all state files are mounted under MOUNT_ROOT, so make sure it exists +mkdir -p ${MOUNT_ROOT} + +# +# attempt to mount state files for the requested module and cat it +# if the mount succeeded +# +module_state_mount ${ECM_MODULE} ${MOUNT_ROOT} && { + cat ${MOUNT_ROOT}/${ECM_MODULE} + exit 0 +} + +exit 2 diff --git a/root/package/firmware/nss/qca-nss-ecm/files/on-demand-down b/root/package/firmware/nss/qca-nss-ecm/files/on-demand-down new file mode 100644 index 00000000..02d708e0 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/files/on-demand-down @@ -0,0 +1,6 @@ +#!/bin/sh +# Copyright (c) 2016 The Linux Foundation. All rights reserved. + +[ -e "/sys/kernel/debug/ecm/ecm_db/defunct_all" ] && { + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all +} diff --git a/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.defaults b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.defaults new file mode 100644 index 00000000..308e265c --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.defaults @@ -0,0 +1,28 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +uci -q batch << EOF + delete firewall.qcanssecm + set firewall.qcanssecm=include + set firewall.qcanssecm.type=script + set firewall.qcanssecm.path=/etc/firewall.d/qca-nss-ecm + set firewall.qcanssecm.family=any + set firewall.qcanssecm.reload=1 + commit firewall +EOF + +exit 0 diff --git a/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.firewall b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.firewall new file mode 100644 index 00000000..24c64def --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.firewall @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +iptables -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT diff --git a/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.init b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.init new file mode 100644 index 00000000..0d58c359 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.init @@ -0,0 +1,133 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2014, 2019 The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# The shebang above has an extra space intentially to avoid having +# openwrt build scripts automatically enable this package starting +# at boot. + +START=19 + +get_front_end_mode() { + config_load "ecm" + config_get front_end global acceleration_engine "auto" + + case $front_end in + auto) + echo '0' + ;; + nss) + echo '1' + ;; + sfe) + echo '2' + ;; + *) + echo 'uci_option_acceleration_engine is invalid' + esac +} + +support_bridge() { + #NSS support bridge acceleration + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && return 0 + #SFE doesn't support bridge acceleration + [ -d /sys/kernel/debug/ecm/ecm_sfe_ipv4 ] && return 1 +} + +load_sfe() { + local kernel_version=$(uname -r) + + [ -e "/lib/modules/$kernel_version/shortcut-fe.ko" ] && { + [ -d /sys/module/shortcut_fe ] || insmod shortcut-fe + } + + [ -e "/lib/modules/$kernel_version/shortcut-fe-ipv6.ko" ] && { + [ -d /sys/module/shortcut_fe_ipv6 ] || insmod shortcut-fe-ipv6 + } + + [ -e "/lib/modules/$kernel_version/shortcut-fe-cm.ko" ] && { + [ -d /sys/module/shortcut_fe_cm ] || insmod shortcut-fe-cm + } + + [ -e "/lib/modules/$kernel_version/shortcut-fe-drv.ko" ] && { + [ -d /sys/module/shortcut_fe_drv ] || insmod shortcut-fe-drv + } + +} + +load_ecm() { + [ -d /sys/module/ecm ] || { + [ ! -e /proc/device-tree/MP_256 ] && load_sfe + insmod ecm front_end_selection=$(get_front_end_mode) + } + + support_bridge && { + sysctl -w net.bridge.bridge-nf-call-ip6tables=1 + sysctl -w net.bridge.bridge-nf-call-iptables=1 + } +} + +unload_ecm() { + sysctl -w net.bridge.bridge-nf-call-ip6tables=0 + sysctl -w net.bridge.bridge-nf-call-iptables=0 + + if [ -d /sys/module/ecm ]; then + # + # Stop ECM frontends + # + echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop + echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop + + # + # Defunct the connections + # + echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all + sleep 5; + + rmmod ecm + sleep 1 + fi +} + +start() { + load_ecm + + # If the acceleration engine is NSS, enable wifi redirect. + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=1 + + support_bridge && { + echo 'net.bridge.bridge-nf-call-ip6tables=1' >> /etc/sysctl.d/qca-nss-ecm.conf + echo 'net.bridge.bridge-nf-call-iptables=1' >> /etc/sysctl.d/qca-nss-ecm.conf + } + + if [ -d /sys/module/qca_ovsmgr ]; then + insmod ecm_ovs + fi + +} + +stop() { + # If the acceleration engine is NSS, disable wifi redirect. + [ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=0 + + sed '/net.bridge.bridge-nf-call-ip6tables=1/d' -i /etc/sysctl.d/qca-nss-ecm.conf + sed '/net.bridge.bridge-nf-call-iptables=1/d' -i /etc/sysctl.d/qca-nss-ecm.conf + + if [ -d /sys/module/ecm_ovs ]; then + rmmod ecm_ovs + fi + + unload_ecm +} diff --git a/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.sysctl b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.sysctl new file mode 100644 index 00000000..1a3d76b1 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.sysctl @@ -0,0 +1,2 @@ +# nf_conntrack_tcp_no_window_check is 0 by default, set it to 1 +net.netfilter.nf_conntrack_tcp_no_window_check=1 diff --git a/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.uci b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.uci new file mode 100644 index 00000000..4f2de687 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/files/qca-nss-ecm.uci @@ -0,0 +1,2 @@ +config ecm 'global' + option acceleration_engine 'auto' diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch b/root/package/firmware/nss/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch new file mode 100644 index 00000000..b1cd2b7b --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch @@ -0,0 +1,12 @@ +--- a/Makefile ++++ b/Makefile +@@ -66,8 +66,7 @@ endif + # Define ECM_FRONT_END_SFE_ENABLE=y in order to select + # sfe as ECM's front end. + # ############################################################################# +-ifeq ($(SoC),$(filter $(SoC),ipq806x ipq40xx)) +-ECM_FRONT_END_SFE_ENABLE=y ++ifeq ($(ECM_FRONT_END_SFE_ENABLE), y) + ecm-$(ECM_FRONT_END_SFE_ENABLE) += frontends/sfe/ecm_sfe_ipv4.o + ecm-$(ECM_FRONT_END_SFE_ENABLE) += frontends/sfe/ecm_sfe_ported_ipv4.o + ccflags-$(ECM_FRONT_END_SFE_ENABLE) += -DECM_FRONT_END_SFE_ENABLE diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/100-kernel-5.4-support.patch b/root/package/firmware/nss/qca-nss-ecm/patches/100-kernel-5.4-support.patch new file mode 100644 index 00000000..b863ad7e --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/100-kernel-5.4-support.patch @@ -0,0 +1,1276 @@ +--- a/ecm_classifier_default.c ++++ b/ecm_classifier_default.c +@@ -42,7 +42,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_classifier_dscp.c ++++ b/ecm_classifier_dscp.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_classifier_hyfi.c ++++ b/ecm_classifier_hyfi.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_classifier_nl.c ++++ b/ecm_classifier_nl.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 2, 0)) + #include + #else +@@ -146,12 +145,42 @@ static struct genl_multicast_group ecm_c + }, + }; + ++static int ecm_classifier_nl_genl_msg_ACCEL(struct sk_buff *skb, struct genl_info *info); ++static int ecm_classifier_nl_genl_msg_DUMP(struct sk_buff *skb, struct netlink_callback *cb); ++ ++/* ++ * Generic Netlink message-to-handler mapping ++ */ ++static struct genl_ops ecm_cl_nl_genl_ops[] = { ++ { ++ .cmd = ECM_CL_NL_GENL_CMD_ACCEL, ++ .flags = 0, ++ .doit = ecm_classifier_nl_genl_msg_ACCEL, ++ .dumpit = NULL, ++ }, ++ { ++ .cmd = ECM_CL_NL_GENL_CMD_ACCEL_OK, ++ .flags = 0, ++ .doit = NULL, ++ .dumpit = ecm_classifier_nl_genl_msg_DUMP, ++ }, ++ { ++ .cmd = ECM_CL_NL_GENL_CMD_CONNECTION_CLOSED, ++ .flags = 0, ++ .doit = NULL, ++ .dumpit = ecm_classifier_nl_genl_msg_DUMP, ++ }, ++}; ++ + static struct genl_family ecm_cl_nl_genl_family = { +- .id = GENL_ID_GENERATE, + .hdrsize = 0, + .name = ECM_CL_NL_GENL_NAME, + .version = ECM_CL_NL_GENL_VERSION, + .maxattr = ECM_CL_NL_GENL_ATTR_MAX, ++ .ops = ecm_cl_nl_genl_ops, ++ .n_ops = ARRAY_SIZE(ecm_cl_nl_genl_ops), ++ .mcgrps = ecm_cl_nl_genl_mcgrp, ++ .n_mcgrps = ARRAY_SIZE(ecm_cl_nl_genl_mcgrp), + }; + + /* +@@ -215,12 +244,7 @@ ecm_classifier_nl_send_genl_msg(enum ECM + return ret; + } + +- ret = genlmsg_end(skb, msg_head); +- if (ret < 0) { +- DEBUG_WARN("failed to finalize genl msg: %d\n", ret); +- nlmsg_free(skb); +- return ret; +- } ++ genlmsg_end(skb, msg_head); + + /* genlmsg_multicast frees the skb in both success and error cases */ + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) +@@ -1377,85 +1401,14 @@ static struct file_operations ecm_classi + .write = ecm_classifier_nl_set_command, + }; + +-/* +- * Generic Netlink attr checking policies +- */ +-static struct nla_policy +-ecm_cl_nl_genl_policy[ECM_CL_NL_GENL_ATTR_COUNT] = { +- [ECM_CL_NL_GENL_ATTR_TUPLE] = { +- .type = NLA_UNSPEC, +- .len = sizeof(struct ecm_cl_nl_genl_attr_tuple), }, +-}; +- +-/* +- * Generic Netlink message-to-handler mapping +- */ +-static struct genl_ops ecm_cl_nl_genl_ops[] = { +- { +- .cmd = ECM_CL_NL_GENL_CMD_ACCEL, +- .flags = 0, +- .policy = ecm_cl_nl_genl_policy, +- .doit = ecm_classifier_nl_genl_msg_ACCEL, +- .dumpit = NULL, +- }, +- { +- .cmd = ECM_CL_NL_GENL_CMD_ACCEL_OK, +- .flags = 0, +- .policy = ecm_cl_nl_genl_policy, +- .doit = NULL, +- .dumpit = ecm_classifier_nl_genl_msg_DUMP, +- }, +- { +- .cmd = ECM_CL_NL_GENL_CMD_CONNECTION_CLOSED, +- .flags = 0, +- .policy = ecm_cl_nl_genl_policy, +- .doit = NULL, +- .dumpit = ecm_classifier_nl_genl_msg_DUMP, +- }, +-}; +- + static int ecm_classifier_nl_register_genl(void) + { + int result; + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) +- result = genl_register_family_with_ops_groups(&ecm_cl_nl_genl_family, +- ecm_cl_nl_genl_ops, +- ecm_cl_nl_genl_mcgrp); +- if (result != 0) { +- DEBUG_ERROR("failed to register genl ops: %d\n", result); +- return result; +- } +-#else + result = genl_register_family(&ecm_cl_nl_genl_family); +- if (result != 0) { ++ if (result != 0) + DEBUG_ERROR("failed to register genl family: %d\n", result); +- goto err1; +- } +- +- result = genl_register_ops(&ecm_cl_nl_genl_family, +- ecm_cl_nl_genl_ops); +- if (result != 0) { +- DEBUG_ERROR("failed to register genl ops: %d\n", result); +- goto err2; +- } +- +- result = genl_register_mc_group(&ecm_cl_nl_genl_family, +- ecm_cl_nl_genl_mcgrp); +- if (result != 0) { +- DEBUG_ERROR("failed to register genl multicast group: %d\n", +- result); +- goto err3; +- } +- +- return 0; + +-err3: +- genl_unregister_ops(&ecm_cl_nl_genl_family, ecm_cl_nl_genl_ops); +-err2: +- genl_unregister_family(&ecm_cl_nl_genl_family); +-err1: +-#endif + return result; + } + +--- a/ecm_classifier_pcc.c ++++ b/ecm_classifier_pcc.c +@@ -49,7 +49,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_conntrack_notifier.c ++++ b/ecm_conntrack_notifier.c +@@ -51,7 +51,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -345,14 +344,6 @@ static int ecm_conntrack_event(unsigned + return NOTIFY_DONE; + } + +- /* +- * Special untracked connection is not monitored +- */ +- if (ct == &nf_conntrack_untracked) { +- DEBUG_TRACE("Fake connection event - ignoring\n"); +- return NOTIFY_DONE; +- } +- + /* + * Only interested if this is IPv4 or IPv6. + */ +--- a/ecm_db/ecm_db.c ++++ b/ecm_db/ecm_db.c +@@ -42,7 +42,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_db/ecm_db_connection.c ++++ b/ecm_db/ecm_db_connection.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_db/ecm_db_host.c ++++ b/ecm_db/ecm_db_host.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_db/ecm_db_iface.c ++++ b/ecm_db/ecm_db_iface.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_db/ecm_db_listener.c ++++ b/ecm_db/ecm_db_listener.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_db/ecm_db_mapping.c ++++ b/ecm_db/ecm_db_mapping.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_db/ecm_db_multicast.c ++++ b/ecm_db/ecm_db_multicast.c +@@ -42,7 +42,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_db/ecm_db_node.c ++++ b/ecm_db/ecm_db_node.c +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_db/ecm_db_timer.c ++++ b/ecm_db/ecm_db_timer.c +@@ -42,7 +42,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -387,7 +386,7 @@ EXPORT_SYMBOL(ecm_db_time_get); + * Manage expiration of connections + * NOTE: This is softirq context + */ +-static void ecm_db_timer_callback(unsigned long data) ++static void ecm_db_timer_callback(struct timer_list *arg) + { + uint32_t timer; + +@@ -425,9 +424,7 @@ void ecm_db_timer_init(void) + /* + * Set a timer to manage cleanup of expired connections + */ +- init_timer(&ecm_db_timer); +- ecm_db_timer.function = ecm_db_timer_callback; +- ecm_db_timer.data = 0; ++ timer_setup(&ecm_db_timer, ecm_db_timer_callback, 0); + ecm_db_timer.expires = jiffies + HZ; + add_timer(&ecm_db_timer); + +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -66,7 +66,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -537,7 +536,7 @@ static bool ecm_interface_find_gateway_ipv4(ip_addr_t addr, ip_addr_t gw_addr) + return false; + } + +- ECM_NIN4_ADDR_TO_IP_ADDR(gw_addr, rt->rt_gateway) ++ ECM_NIN4_ADDR_TO_IP_ADDR(gw_addr, rt->rt_gw4) + ecm_interface_route_release(&ecm_rt); + return true; + } +@@ -596,7 +595,7 @@ static bool ecm_interface_mac_addr_get_ipv4(ip_addr_t addr, uint8_t *mac_addr, b + if (rt->rt_uses_gateway || (rt->rt_flags & RTF_GATEWAY)) { + #endif + *on_link = false; +- ECM_NIN4_ADDR_TO_IP_ADDR(gw_addr, rt->rt_gateway) ++ ECM_NIN4_ADDR_TO_IP_ADDR(gw_addr, rt->rt_gw4) + } else { + *on_link = true; + } +@@ -1003,7 +1002,7 @@ static bool ecm_interface_find_route_by_addr_ipv6(ip_addr_t addr, struct ecm_int + * Get a route to the given IP address, this will allow us to also find the interface + * it is using to communicate with that IP address. + */ +- ecm_rt->rt.rtv6 = rt6_lookup(&init_net, &naddr, NULL, 0, 0); ++ ecm_rt->rt.rtv6 = rt6_lookup(&init_net, &naddr, NULL, 0, NULL, 0); + if (!ecm_rt->rt.rtv6) { + DEBUG_TRACE("No output route to: " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr)); + return NULL; +@@ -1077,7 +1076,7 @@ void ecm_interface_send_neighbour_solicitation(struct net_device *dev, ip_addr_t + /* + * Find the route entry + */ +- rt6i = rt6_lookup(netf, &dst_addr, NULL, 0, 0); ++ rt6i = rt6_lookup(netf, &dst_addr, NULL, 0, NULL, 0); + if (!rt6i) { + DEBUG_TRACE("IPv6 Route lookup failure for destination IPv6 address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr)); + return; +@@ -1104,7 +1103,7 @@ void ecm_interface_send_neighbour_solicitation(struct net_device *dev, ip_addr_t + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) + ndisc_send_ns(dev, neigh, &dst_addr, &mc_dst_addr, &src_addr); + #else +- ndisc_send_ns(dev, &dst_addr, &mc_dst_addr, &src_addr); ++ ndisc_send_ns(dev, &dst_addr, &mc_dst_addr, &src_addr, 0); + #endif + neigh_release(neigh); + dst_release(&rt6i->dst); +@@ -1194,7 +1193,7 @@ struct neighbour *ecm_interface_ipv6_neigh_get(ip_addr_t addr) + struct in6_addr ipv6_addr; + + ECM_IP_ADDR_TO_NIN6_ADDR(ipv6_addr, addr); +- rt = rt6_lookup(&init_net, &ipv6_addr, NULL, 0, 0); ++ rt = rt6_lookup(&init_net, &ipv6_addr, NULL, 0, NULL, 0); + if (!rt) { + return NULL; + } +@@ -1220,7 +1219,7 @@ bool ecm_interface_is_pptp(struct sk_buff *skb, const struct net_device *out) + * skip first pass of l2tp/pptp tunnel encapsulated traffic + */ + if (out->type == ARPHRD_PPP) { +- if (out->priv_flags & IFF_PPP_PPTP) { ++ if (out->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_PPTP) { + return true; + } + } +@@ -1231,7 +1230,7 @@ bool ecm_interface_is_pptp(struct sk_buff *skb, const struct net_device *out) + } + + if (in->type == ARPHRD_PPP) { +- if (in->priv_flags & IFF_PPP_PPTP) { ++ if (in->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_PPTP) { + dev_put(in); + return true; + } +@@ -1256,10 +1255,10 @@ bool ecm_interface_is_l2tp_packet_by_version(struct sk_buff *skb, const struct n + + switch (ver) { + case 2: +- flag = IFF_PPP_L2TPV2; ++ flag = IFF_QCA_ECM_PPP_L2TPV2; + break; + case 3: +- flag = IFF_PPP_L2TPV3; ++ flag = IFF_QCA_ECM_PPP_L2TPV3; + break; + default: + break; +@@ -1268,10 +1267,8 @@ bool ecm_interface_is_l2tp_packet_by_version(struct sk_buff *skb, const struct n + /* + * skip first pass of l2tp/pptp tunnel encapsulated traffic + */ +- if (out->type == ARPHRD_PPP) { +- if (out->priv_flags & flag) { +- return true; +- } ++ if (out->priv_flags_qca_ecm & flag) { ++ return true; + } + + in = dev_get_by_index(&init_net, skb->skb_iif); +@@ -1279,11 +1276,9 @@ bool ecm_interface_is_l2tp_packet_by_version(struct sk_buff *skb, const struct n + return true; + } + +- if (in->type == ARPHRD_PPP) { +- if (in->priv_flags & flag) { +- dev_put(in); +- return true; +- } ++ if (out->priv_flags_qca_ecm & flag) { ++ dev_put(in); ++ return true; + } + + dev_put(in); +@@ -1304,11 +1299,9 @@ bool ecm_interface_is_l2tp_pptp(struct sk_buff *skb, const struct net_device *ou + /* + * skip first pass of l2tp/pptp tunnel encapsulated traffic + */ +- if (out->type == ARPHRD_PPP) { +- if (out->priv_flags & (IFF_PPP_L2TPV2 | IFF_PPP_L2TPV3 | +- IFF_PPP_PPTP)) { +- return true; +- } ++ if (out->priv_flags_qca_ecm & (IFF_QCA_ECM_PPP_L2TPV2 | IFF_QCA_ECM_PPP_L2TPV3 | ++ IFF_QCA_ECM_PPP_PPTP)) { ++ return true; + } + + in = dev_get_by_index(&init_net, skb->skb_iif); +@@ -1316,12 +1309,10 @@ bool ecm_interface_is_l2tp_pptp(struct sk_buff *skb, const struct net_device *ou + return true; + } + +- if (in->type == ARPHRD_PPP) { +- if (in->priv_flags & (IFF_PPP_L2TPV2 | IFF_PPP_L2TPV3 | +- IFF_PPP_PPTP)) { +- dev_put(in); +- return true; +- } ++ if (out->priv_flags_qca_ecm & (IFF_QCA_ECM_PPP_L2TPV2 | IFF_QCA_ECM_PPP_L2TPV3 | ++ IFF_QCA_ECM_PPP_PPTP)) { ++ dev_put(in); ++ return true; + } + + dev_put(in); +@@ -2416,7 +2407,7 @@ struct ecm_db_iface_instance *ecm_interface_establish_and_ref(struct ecm_front_e + /* + * GRE TAP? + */ +- if (dev->priv_flags & (IFF_GRE_V4_TAP | IFF_GRE_V6_TAP)) { ++ if (dev->priv_flags_qca_ecm & (IFF_QCA_ECM_GRE_V4_TAP | IFF_QCA_ECM_GRE_V6_TAP)) { + interface_type = feci->ae_interface_type_get(feci, dev); + ae_interface_num = feci->ae_interface_number_by_dev_type_get(dev, interface_type); + +@@ -2680,7 +2671,7 @@ identifier_update: + /* + * OVPN Tunnel? + */ +- if ((dev_type == ARPHRD_NONE) && (dev->priv_flags & IFF_TUN_TAP)) { ++ if ((dev_type == ARPHRD_NONE) && (dev->priv_flags_qca_ecm & IFF_QCA_ECM_TUN_TAP)) { + struct net_device *tun_dev = NULL; + ip_addr_t saddr, daddr; + +@@ -2746,7 +2737,7 @@ identifier_update: + * ppp_is_multilink() and ppp_hold_channels() which acquire same lock + */ + +- if ((dev->priv_flags & IFF_PPP_L2TPV2) && ppp_is_xmit_locked(dev)) { ++ if ((dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_L2TPV2) && ppp_is_xmit_locked(dev)) { + if (skb && (skb->skb_iif == dev->ifindex)) { + struct pppol2tp_common_addr info; + +@@ -2804,7 +2795,7 @@ identifier_update: + #endif + + #ifdef ECM_INTERFACE_PPTP_ENABLE +- if ((protocol == IPPROTO_GRE) && skb && v4_hdr && (dev->priv_flags & IFF_PPP_PPTP)) { ++ if ((protocol == IPPROTO_GRE) && skb && v4_hdr && (dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_PPTP)) { + struct gre_hdr_pptp *gre_hdr; + uint16_t proto; + int ret; +@@ -3972,7 +3963,7 @@ int32_t ecm_interface_heirarchy_construct(struct ecm_front_end_connection_instan + if (((ip_version == 4) && (protocol == IPPROTO_IPV6)) || + ((ip_version == 6) && (protocol == IPPROTO_IPIP)) || + (protocol == IPPROTO_GRE) || +- ((given_dest_dev->type == ARPHRD_NONE) && (given_dest_dev->priv_flags & IFF_TUN_TAP))) { ++ ((given_dest_dev->type == ARPHRD_NONE) && (given_dest_dev->priv_flags_qca_ecm & IFF_QCA_ECM_TUN_TAP))) { + dev_put(dest_dev); + dest_dev = given_dest_dev; + if (dest_dev) { +@@ -3991,7 +3982,7 @@ int32_t ecm_interface_heirarchy_construct(struct ecm_front_end_connection_instan + /* + * if the address is a local address and indev=l2tp. + */ +- if ((given_src_dev->type == ARPHRD_PPP) && (given_src_dev->priv_flags & IFF_PPP_L2TPV2) && ppp_is_xmit_locked(given_src_dev)) { ++ if ((given_src_dev->type == ARPHRD_PPP) && (given_src_dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_L2TPV2) && ppp_is_xmit_locked(given_src_dev)) { + dev_put(dest_dev); + dest_dev = given_dest_dev; + if (dest_dev) { +@@ -4005,7 +3996,7 @@ int32_t ecm_interface_heirarchy_construct(struct ecm_front_end_connection_instan + /* + * if the address is a local address and indev=PPTP. + */ +- if (protocol == IPPROTO_GRE && given_dest_dev && (given_dest_dev->priv_flags & IFF_PPP_PPTP)){ ++ if (protocol == IPPROTO_GRE && given_dest_dev && (given_dest_dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_PPTP)){ + dev_put(dest_dev); + dest_dev = given_dest_dev; + if (dest_dev) { +@@ -4054,7 +4045,7 @@ int32_t ecm_interface_heirarchy_construct(struct ecm_front_end_connection_instan + if (((ip_version == 4) && (protocol == IPPROTO_IPV6)) || + ((ip_version == 6) && (protocol == IPPROTO_IPIP)) || + (protocol == IPPROTO_GRE) || +- ((given_src_dev->type == ARPHRD_NONE) && (given_src_dev->priv_flags & IFF_TUN_TAP))) { ++ ((given_src_dev->type == ARPHRD_NONE) && (given_src_dev->priv_flags_qca_ecm & IFF_QCA_ECM_TUN_TAP))) { + dev_put(src_dev); + src_dev = given_src_dev; + if (src_dev) { +@@ -4504,7 +4495,7 @@ lag_success: + /* + * OVPN ? + */ +- if ((dest_dev_type == ARPHRD_NONE) && (dest_dev->priv_flags & IFF_TUN_TAP)) { ++ if ((dest_dev_type == ARPHRD_NONE) && (dest_dev->priv_flags_qca_ecm & IFF_QCA_ECM_TUN_TAP)) { + DEBUG_TRACE("Net device: %p is OVPN, device name: %s\n", dest_dev, dest_dev->name); + break; + } +@@ -4523,7 +4514,7 @@ lag_success: + DEBUG_TRACE("%p: Net device: %p is PPP\n", feci, dest_dev); + + #ifdef ECM_INTERFACE_L2TPV2_ENABLE +- if ((given_src_dev->priv_flags & IFF_PPP_L2TPV2) && ppp_is_xmit_locked(given_src_dev)) { ++ if ((given_src_dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_L2TPV2) && ppp_is_xmit_locked(given_src_dev)) { + if (skb->skb_iif == dest_dev->ifindex) { + DEBUG_TRACE("%p: Net device: %p PPP channel is PPPoL2TPV2\n", feci, dest_dev); + break; +@@ -4532,7 +4523,7 @@ lag_success: + #endif + + #ifdef ECM_INTERFACE_PPTP_ENABLE +- if (protocol == IPPROTO_GRE && dest_dev && (dest_dev->priv_flags & IFF_PPP_PPTP)) { ++ if (protocol == IPPROTO_GRE && dest_dev && (dest_dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_PPTP)) { + DEBUG_TRACE("%p: Net device: %p PPP channel is PPTP\n", feci, dest_dev); + break; + } +@@ -4798,7 +4789,7 @@ int32_t ecm_interface_multicast_from_heirarchy_construct(struct ecm_front_end_co + /* + * if the address is a local address and indev=l2tp. + */ +- if ((given_src_dev->type == ARPHRD_PPP) && (given_src_dev->priv_flags & IFF_PPP_L2TPV2) && ppp_is_xmit_locked(given_src_dev)) { ++ if ((given_src_dev->type == ARPHRD_PPP) && (given_src_dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_L2TPV2) && ppp_is_xmit_locked(given_src_dev)) { + dev_put(dest_dev); + dest_dev = given_dest_dev; + if (dest_dev) { +@@ -5265,7 +5256,7 @@ int32_t ecm_interface_multicast_from_heirarchy_construct(struct ecm_front_end_co + DEBUG_TRACE("Net device: %p is PPP\n", dest_dev); + + #ifdef ECM_INTERFACE_L2TPV2_ENABLE +- if ((given_src_dev->priv_flags & IFF_PPP_L2TPV2) && ppp_is_xmit_locked(given_src_dev)) { ++ if ((given_src_dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_L2TPV2) && ppp_is_xmit_locked(given_src_dev)) { + if (skb->skb_iif == dest_dev->ifindex) { + DEBUG_TRACE("Net device: %p PPP channel is PPPoL2TPV2\n", dest_dev); + break; +@@ -6520,7 +6511,7 @@ static int ecm_interface_wifi_event_rx(struct socket *sock, struct sockaddr_nl * + #endif + oldfs = get_fs(); + set_fs(KERNEL_DS); +- size = sock_recvmsg(sock, &msg, len, msg.msg_flags); ++ size = sock_recvmsg(sock, &msg, msg.msg_flags); + set_fs(oldfs); + + return size; +@@ -6609,7 +6600,7 @@ int ecm_interface_wifi_event_stop(void) + } + + DEBUG_INFO("kill ecm_interface_wifi_event thread\n"); +- force_sig(SIGKILL, __ewn.thread); ++ send_sig(SIGKILL, __ewn.thread, 1); + err = kthread_stop(__ewn.thread); + __ewn.thread = NULL; + +--- a/ecm_tracker.c ++++ b/ecm_tracker.c +@@ -43,7 +43,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_tracker_datagram.c ++++ b/ecm_tracker_datagram.c +@@ -43,7 +43,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/ecm_tracker_tcp.c ++++ b/ecm_tracker_tcp.c +@@ -43,7 +43,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1143,7 +1142,7 @@ static bool ecm_tracker_tcp_extract_mss( + const u8 *hash_location; + tcp_parse_options(skb, &opt_rx, &hash_location, 0); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) +- tcp_parse_options(skb, &opt_rx, 0, NULL); ++ tcp_parse_options(&init_net, skb, &opt_rx, 0, NULL); + #else + #error "Unsupported kernel version for tcp_parse_options()" + #endif +--- a/ecm_tracker_udp.c ++++ b/ecm_tracker_udp.c +@@ -43,7 +43,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/frontends/ecm_front_end_ipv4.c ++++ b/frontends/ecm_front_end_ipv4.c +@@ -215,7 +215,7 @@ bool ecm_front_end_ipv4_interface_constr + * behind a gateway. + */ + DEBUG_TRACE("Gateway address will be looked up overwrite the rt_dst_addr\n"); +- ECM_NIN4_ADDR_TO_IP_ADDR(rt_dst_addr, rt->rt_gateway) ++ ECM_NIN4_ADDR_TO_IP_ADDR(rt_dst_addr, rt->rt_gw4) + gateway = true; + } + +--- a/frontends/include/ecm_front_end_common.h ++++ b/frontends/include/ecm_front_end_common.h +@@ -98,13 +98,6 @@ static inline bool ecm_front_end_acceler + return false; + } + +- if (unlikely(nf_ct_is_untracked(ct))) { +- /* +- * Untracked traffic certainly can't be accelerated. +- */ +- return true; +- } +- + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 6, 0)) + acct = nf_conn_acct_find(ct); + #else +--- a/frontends/nss/ecm_nss_bond_notifier.c ++++ b/frontends/nss/ecm_nss_bond_notifier.c +@@ -52,7 +52,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/frontends/nss/ecm_nss_common.h ++++ b/frontends/nss/ecm_nss_common.h +@@ -144,7 +144,7 @@ static inline int32_t ecm_nss_common_get_interface_type(struct ecm_front_end_con + /* + * If device is not GRETAP then return NONE. + */ +- if (!(dev->priv_flags & (IFF_GRE_V4_TAP | IFF_GRE_V6_TAP))) { ++ if (!(dev->priv_flags_qca_ecm & (IFF_QCA_ECM_GRE_V4_TAP | IFF_QCA_ECM_GRE_V6_TAP))) { + break; + } + #endif +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -48,7 +48,6 @@ + #include + #include + #include +-#include + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 2, 0)) + #include + #else +@@ -1053,7 +1052,7 @@ static unsigned int ecm_nss_ipv4_ip_process(struct net_device *out_dev, struct n + * If any of the input or output interface is a GRE V4 TAP/TUN interface + * we can continue to accelerate it. + */ +- if ((in_dev->priv_flags & IFF_GRE_V4_TAP) || (out_dev->priv_flags & IFF_GRE_V4_TAP)) { ++ if ((in_dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V4_TAP) || (out_dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V4_TAP)) { + #ifndef ECM_INTERFACE_GRE_TAP_ENABLE + DEBUG_TRACE("GRE TAP acceleration is disabled\n"); + return NF_ACCEPT; +@@ -1082,7 +1081,7 @@ static unsigned int ecm_nss_ipv4_ip_process(struct net_device *out_dev, struct n + reply_tuple.dst.u3.ip = orig_tuple.src.u3.ip; + sender = ECM_TRACKER_SENDER_TYPE_SRC; + } else { +- if (unlikely(ct == &nf_conntrack_untracked)) { ++ if (unlikely(ctinfo == IP_CT_UNTRACKED)) { + DEBUG_TRACE("%p: ct: untracked\n", skb); + return NF_ACCEPT; + } +@@ -2097,7 +2096,6 @@ sync_conntrack: + } + + ct = nf_ct_tuplehash_to_ctrack(h); +- NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct); + DEBUG_TRACE("%p: NSS Sync: conntrack connection\n", ct); + + ecm_front_end_flow_and_return_directions_get(ct, flow_ip, 4, &flow_dir, &return_dir); +@@ -2108,7 +2106,7 @@ sync_conntrack: + */ + if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) { + spin_lock_bh(&ct->lock); +- ct->timeout.expires += delta_jiffies; ++ ct->timeout += delta_jiffies; + spin_unlock_bh(&ct->lock); + } + +@@ -2166,17 +2164,15 @@ sync_conntrack: + u_int64_t reply_pkts = atomic64_read(&acct[IP_CT_DIR_REPLY].packets); + + if (reply_pkts != 0) { +- struct nf_conntrack_l4proto *l4proto; + unsigned int *timeouts; + + set_bit(IPS_SEEN_REPLY_BIT, &ct->status); + set_bit(IPS_ASSURED_BIT, &ct->status); + +- l4proto = __nf_ct_l4proto_find(AF_INET, IPPROTO_UDP); +- timeouts = nf_ct_timeout_lookup(&init_net, ct, l4proto); ++ timeouts = nf_ct_timeout_lookup(ct); + + spin_lock_bh(&ct->lock); +- ct->timeout.expires = jiffies + timeouts[UDP_CT_REPLIED]; ++ ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); + } + } +@@ -2690,7 +2686,8 @@ int ecm_nss_ipv4_init(struct dentry *dentry) + /* + * Register netfilter hooks + */ +- result = nf_register_hooks(ecm_nss_ipv4_netfilter_hooks, ARRAY_SIZE(ecm_nss_ipv4_netfilter_hooks)); ++ result = nf_register_net_hooks(&init_net, ecm_nss_ipv4_netfilter_hooks, \ ++ ARRAY_SIZE(ecm_nss_ipv4_netfilter_hooks)); + if (result < 0) { + DEBUG_ERROR("Can't register netfilter hooks.\n"); + nss_ipv4_notify_unregister(); +@@ -2702,8 +2699,8 @@ int ecm_nss_ipv4_init(struct dentry *dentry) + if (result < 0) { + DEBUG_ERROR("Failed to init ecm ipv4 multicast frontend\n"); + nss_ipv4_notify_unregister(); +- nf_unregister_hooks(ecm_nss_ipv4_netfilter_hooks, +- ARRAY_SIZE(ecm_nss_ipv4_netfilter_hooks)); ++ nf_unregister_net_hooks(&init_net, ecm_nss_ipv4_netfilter_hooks, ++ ARRAY_SIZE(ecm_nss_ipv4_netfilter_hooks)); + goto task_cleanup; + } + #endif +@@ -2714,8 +2711,8 @@ int ecm_nss_ipv4_init(struct dentry *dentry) + #ifdef ECM_MULTICAST_ENABLE + ecm_nss_multicast_ipv4_exit(); + #endif +- nf_unregister_hooks(ecm_nss_ipv4_netfilter_hooks, +- ARRAY_SIZE(ecm_nss_ipv4_netfilter_hooks)); ++ nf_unregister_net_hooks(&init_net, ecm_nss_ipv4_netfilter_hooks, ++ ARRAY_SIZE(ecm_nss_ipv4_netfilter_hooks)); + goto task_cleanup; + } + +@@ -2742,8 +2739,8 @@ void ecm_nss_ipv4_exit(void) + /* + * Stop the network stack hooks + */ +- nf_unregister_hooks(ecm_nss_ipv4_netfilter_hooks, +- ARRAY_SIZE(ecm_nss_ipv4_netfilter_hooks)); ++ nf_unregister_net_hooks(&init_net, ecm_nss_ipv4_netfilter_hooks, ++ ARRAY_SIZE(ecm_nss_ipv4_netfilter_hooks)); + + /* + * Unregister from the Linux NSS Network driver +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -51,7 +51,6 @@ + #include + #include + #include +-#include + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 2, 0)) + #include + #else +@@ -1035,7 +1034,7 @@ static unsigned int ecm_nss_ipv6_ip_process(struct net_device *out_dev, struct n + * If any of the input or output interface is a GRE V4 TAP/TUN interface + * we can continue to accelerate it. + */ +- if ((in_dev->priv_flags & IFF_GRE_V4_TAP) || (out_dev->priv_flags & IFF_GRE_V4_TAP)) { ++ if ((in_dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V4_TAP) || (out_dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V4_TAP)) { + #ifndef ECM_INTERFACE_GRE_TAP_ENABLE + DEBUG_TRACE("GRE TAP acceleration is disabled\n"); + return NF_ACCEPT; +@@ -1064,7 +1063,7 @@ static unsigned int ecm_nss_ipv6_ip_process(struct net_device *out_dev, struct n + ECM_IP_ADDR_TO_NIN6_ADDR(reply_tuple.dst.u3.in6, ip_hdr.src_addr); + sender = ECM_TRACKER_SENDER_TYPE_SRC; + } else { +- if (unlikely(ct == &nf_conntrack_untracked)) { ++ if (unlikely(ctinfo == IP_CT_UNTRACKED)) { + DEBUG_TRACE("%p: ct: untracked\n", skb); + return NF_ACCEPT; + } +@@ -1809,7 +1808,6 @@ sync_conntrack: + } + + ct = nf_ct_tuplehash_to_ctrack(h); +- NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct); + DEBUG_TRACE("%p: NSS Sync: conntrack connection\n", ct); + + ecm_front_end_flow_and_return_directions_get(ct, flow_ip, 6, &flow_dir, &return_dir); +@@ -1820,7 +1818,7 @@ sync_conntrack: + */ + if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) { + spin_lock_bh(&ct->lock); +- ct->timeout.expires += delta_jiffies; ++ ct->timeout += delta_jiffies; + spin_unlock_bh(&ct->lock); + } + +@@ -1878,17 +1876,15 @@ sync_conntrack: + u_int64_t reply_pkts = atomic64_read(&acct[IP_CT_DIR_REPLY].packets); + + if (reply_pkts != 0) { +- struct nf_conntrack_l4proto *l4proto; + unsigned int *timeouts; + + set_bit(IPS_SEEN_REPLY_BIT, &ct->status); + set_bit(IPS_ASSURED_BIT, &ct->status); + +- l4proto = __nf_ct_l4proto_find(AF_INET6, IPPROTO_UDP); +- timeouts = nf_ct_timeout_lookup(&init_net, ct, l4proto); ++ timeouts = nf_ct_timeout_lookup(ct); + + spin_lock_bh(&ct->lock); +- ct->timeout.expires = jiffies + timeouts[UDP_CT_REPLIED]; ++ ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); + } + } +@@ -2402,7 +2398,7 @@ int ecm_nss_ipv6_init(struct dentry *dentry) + /* + * Register netfilter hooks + */ +- result = nf_register_hooks(ecm_nss_ipv6_netfilter_hooks, ARRAY_SIZE(ecm_nss_ipv6_netfilter_hooks)); ++ result = nf_register_net_hooks(&init_net, ecm_nss_ipv6_netfilter_hooks, ARRAY_SIZE(ecm_nss_ipv6_netfilter_hooks)); + if (result < 0) { + DEBUG_ERROR("Can't register netfilter hooks.\n"); + nss_ipv6_notify_unregister(); +@@ -2414,8 +2410,8 @@ int ecm_nss_ipv6_init(struct dentry *dentry) + if (result < 0) { + DEBUG_ERROR("Failed to init ecm ipv6 multicast frontend\n"); + nss_ipv6_notify_unregister(); +- nf_unregister_hooks(ecm_nss_ipv6_netfilter_hooks, +- ARRAY_SIZE(ecm_nss_ipv6_netfilter_hooks)); ++ nf_unregister_net_hooks(&init_net, ecm_nss_ipv6_netfilter_hooks, ++ ARRAY_SIZE(ecm_nss_ipv6_netfilter_hooks)); + goto task_cleanup; + } + #endif +@@ -2426,8 +2422,8 @@ int ecm_nss_ipv6_init(struct dentry *dentry) + #ifdef ECM_MULTICAST_ENABLE + ecm_nss_multicast_ipv6_exit(); + #endif +- nf_unregister_hooks(ecm_nss_ipv6_netfilter_hooks, +- ARRAY_SIZE(ecm_nss_ipv6_netfilter_hooks)); ++ nf_unregister_net_hooks(&init_net, ecm_nss_ipv6_netfilter_hooks, ++ ARRAY_SIZE(ecm_nss_ipv6_netfilter_hooks)); + goto task_cleanup; + } + +@@ -2453,8 +2449,8 @@ void ecm_nss_ipv6_exit(void) + /* + * Stop the network stack hooks + */ +- nf_unregister_hooks(ecm_nss_ipv6_netfilter_hooks, +- ARRAY_SIZE(ecm_nss_ipv6_netfilter_hooks)); ++ nf_unregister_net_hooks(&init_net, ecm_nss_ipv6_netfilter_hooks, ++ ARRAY_SIZE(ecm_nss_ipv6_netfilter_hooks)); + + /* + * Unregister from the Linux NSS Network driver +--- a/frontends/nss/ecm_nss_multicast_ipv4.c ++++ b/frontends/nss/ecm_nss_multicast_ipv4.c +@@ -50,7 +50,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/frontends/nss/ecm_nss_multicast_ipv6.c ++++ b/frontends/nss/ecm_nss_multicast_ipv6.c +@@ -51,7 +51,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/frontends/nss/ecm_nss_non_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_non_ported_ipv4.c +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -640,7 +639,7 @@ static void ecm_nss_non_ported_ipv4_connection_accelerate(struct ecm_front_end_c + #ifdef ECM_INTERFACE_GRE_TAP_ENABLE + dev = dev_get_by_index(&init_net, ecm_db_iface_interface_identifier_get(ii)); + if (dev) { +- if (dev->priv_flags & IFF_GRE_V4_TAP) { ++ if (dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V4_TAP) { + /* + * Clear QOS_VALID to prevent outer rule from overwriting + * inner flow's QoS classification. +--- a/frontends/nss/ecm_nss_non_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_non_ported_ipv6.c +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -548,7 +547,7 @@ static void ecm_nss_non_ported_ipv6_connection_accelerate(struct ecm_front_end_c + #ifdef ECM_INTERFACE_GRE_TAP_ENABLE + dev = dev_get_by_index(&init_net, ecm_db_iface_interface_identifier_get(ii)); + if (dev) { +- if (dev->priv_flags & IFF_GRE_V6_TAP) { ++ if (dev->priv_flags_qca_ecm & IFF_QCA_ECM_GRE_V6_TAP) { + /* + * Clear QOS_VALID to prevent outer rule from overwriting + * inner flow's QoS classification. +--- a/frontends/nss/ecm_nss_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_ported_ipv4.c +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- a/frontends/nss/ecm_nss_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_ported_ipv6.c +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1996,7 +1995,7 @@ unsigned int ecm_nss_ported_ipv6_process + /* + * Deny acceleration for L2TP-over-UDP tunnel + */ +- if ((in_dev->priv_flags & IFF_PPP_L2TPV2) && ppp_is_xmit_locked(in_dev)) { ++ if ((in_dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_L2TPV2) && ppp_is_xmit_locked(in_dev)) { + DEBUG_TRACE("Skip packets for L2TP tunnel in skb %p\n", skb); + can_accel = false; + } +--- a/frontends/sfe/ecm_sfe_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ipv4.c +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 2, 0)) + #include + #else +@@ -746,7 +745,8 @@ static unsigned int ecm_sfe_ipv4_ip_proc + * If skb_dst(skb)->xfrm is not null, packet is to be encrypted by ipsec, we can't accelerate it. + * If skb->sp is not null, packet is decrypted by ipsec. We only accelerate it when configuration didn't reject ipsec. + */ +- if (unlikely((skb_dst(skb) && skb_dst(skb)->xfrm) || (ecm_sfe_ipv4_reject_acceleration_for_ipsec && skb->sp))) { ++ if (unlikely((skb_dst(skb) && skb_dst(skb)->xfrm) || \ ++ (ecm_sfe_ipv4_reject_acceleration_for_ipsec && skb_ext_exist(skb, SKB_EXT_SEC_PATH)))) { + DEBUG_TRACE("skip local ipsec flows\n"); + return NF_ACCEPT; + } +@@ -762,7 +762,7 @@ static unsigned int ecm_sfe_ipv4_ip_process(struct net_device *out_dev, struct n + reply_tuple.dst.u3.ip = orig_tuple.src.u3.ip; + sender = ECM_TRACKER_SENDER_TYPE_SRC; + } else { +- if (unlikely(ct == &nf_conntrack_untracked)) { ++ if (unlikely(ctinfo == IP_CT_UNTRACKED)) { + DEBUG_TRACE("%p: ct: untracked\n", skb); + return NF_ACCEPT; + } +@@ -1531,7 +1526,6 @@ sync_conntrack: + } + + ct = nf_ct_tuplehash_to_ctrack(h); +- NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct); + DEBUG_TRACE("%p: SFE Sync: conntrack connection\n", ct); + + ecm_front_end_flow_and_return_directions_get(ct, flow_ip, 4, &flow_dir, &return_dir); +@@ -1551,7 +1545,7 @@ sync_conntrack: + delta_jiffies = ((sync->inc_ticks * HZ) + (MSEC_PER_SEC / 2)) / MSEC_PER_SEC; + + spin_lock_bh(&ct->lock); +- ct->timeout.expires += delta_jiffies; ++ ct->timeout += delta_jiffies; + spin_unlock_bh(&ct->lock); + } + +@@ -1609,17 +1603,15 @@ sync_conntrack: + u_int64_t reply_pkts = atomic64_read(&acct[IP_CT_DIR_REPLY].packets); + + if (reply_pkts != 0) { +- struct nf_conntrack_l4proto *l4proto; + unsigned int *timeouts; + + set_bit(IPS_SEEN_REPLY_BIT, &ct->status); + set_bit(IPS_ASSURED_BIT, &ct->status); + +- l4proto = __nf_ct_l4proto_find(AF_INET, IPPROTO_UDP); +- timeouts = nf_ct_timeout_lookup(&init_net, ct, l4proto); ++ timeouts = nf_ct_timeout_lookup(ct); + + spin_lock_bh(&ct->lock); +- ct->timeout.expires = jiffies + timeouts[UDP_CT_REPLIED]; ++ ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); + } + } +@@ -1901,7 +1893,7 @@ int ecm_sfe_ipv4_init(struct dentry *den + /* + * Register netfilter hooks + */ +- result = nf_register_hooks(ecm_sfe_ipv4_netfilter_hooks, ARRAY_SIZE(ecm_sfe_ipv4_netfilter_hooks)); ++ result = nf_register_net_hooks(&init_net, ecm_sfe_ipv4_netfilter_hooks, ARRAY_SIZE(ecm_sfe_ipv4_netfilter_hooks)); + if (result < 0) { + DEBUG_ERROR("Can't register netfilter hooks.\n"); + sfe_drv_ipv4_notify_unregister(); +@@ -1934,8 +1926,8 @@ void ecm_sfe_ipv4_exit(void) + /* + * Stop the network stack hooks + */ +- nf_unregister_hooks(ecm_sfe_ipv4_netfilter_hooks, +- ARRAY_SIZE(ecm_sfe_ipv4_netfilter_hooks)); ++ nf_unregister_net_hooks(&init_net, ecm_sfe_ipv4_netfilter_hooks, ++ ARRAY_SIZE(ecm_sfe_ipv4_netfilter_hooks)); + + /* + * Unregister from the simulated sfe driver +--- a/frontends/sfe/ecm_sfe_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ipv6.c +@@ -51,7 +51,6 @@ + #include + #include + #include +-#include + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 2, 0)) + #include + #else +@@ -714,7 +713,8 @@ static unsigned int ecm_sfe_ipv6_ip_proc + * If skb_dst(skb)->xfrm is not null, packet is to be encrypted by ipsec, we can't accelerate it. + * If skb->sp is not null, packet is decrypted by ipsec. We only accelerate it when configuration didn't reject ipsec. + */ +- if (unlikely((skb_dst(skb) && skb_dst(skb)->xfrm) || (ecm_sfe_ipv6_reject_acceleration_for_ipsec && skb->sp))) { ++ if (unlikely((skb_dst(skb) && skb_dst(skb)->xfrm) || \ ++ (ecm_sfe_ipv6_reject_acceleration_for_ipsec && skb_ext_exist(skb, SKB_EXT_SEC_PATH)))) { + DEBUG_TRACE("skip local ipsec flows\n"); + return NF_ACCEPT; + } +@@ -733,7 +733,7 @@ static unsigned int ecm_sfe_ipv6_ip_proc + ECM_IP_ADDR_TO_NIN6_ADDR(reply_tuple.dst.u3.in6, ip_hdr.src_addr); + sender = ECM_TRACKER_SENDER_TYPE_SRC; + } else { +- if (unlikely(ct == &nf_conntrack_untracked)) { ++ if (unlikely(ctinfo == IP_CT_UNTRACKED)) { + DEBUG_TRACE("%p: ct: untracked\n", skb); + return NF_ACCEPT; + } +@@ -1255,7 +1255,6 @@ sync_conntrack: + } + + ct = nf_ct_tuplehash_to_ctrack(h); +- NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct); + DEBUG_TRACE("%p: SFE Sync: conntrack connection\n", ct); + + ecm_front_end_flow_and_return_directions_get(ct, flow_ip, 6, &flow_dir, &return_dir); +@@ -1275,7 +1274,7 @@ sync_conntrack: + delta_jiffies = ((sync->inc_ticks * HZ) + (MSEC_PER_SEC / 2)) / MSEC_PER_SEC; + + spin_lock_bh(&ct->lock); +- ct->timeout.expires += delta_jiffies; ++ ct->timeout += delta_jiffies; + spin_unlock_bh(&ct->lock); + } + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0)) +@@ -1332,17 +1331,15 @@ sync_conntrack: + u_int64_t reply_pkts = atomic64_read(&acct[IP_CT_DIR_REPLY].packets); + + if (reply_pkts != 0) { +- struct nf_conntrack_l4proto *l4proto; + unsigned int *timeouts; + + set_bit(IPS_SEEN_REPLY_BIT, &ct->status); + set_bit(IPS_ASSURED_BIT, &ct->status); + +- l4proto = __nf_ct_l4proto_find(AF_INET6, IPPROTO_UDP); +- timeouts = nf_ct_timeout_lookup(&init_net, ct, l4proto); ++ timeouts = nf_ct_timeout_lookup(ct); + + spin_lock_bh(&ct->lock); +- ct->timeout.expires = jiffies + timeouts[UDP_CT_REPLIED]; ++ ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); + } + } +@@ -1624,7 +1621,7 @@ int ecm_sfe_ipv6_init(struct dentry *den + /* + * Register netfilter hooks + */ +- result = nf_register_hooks(ecm_sfe_ipv6_netfilter_hooks, ARRAY_SIZE(ecm_sfe_ipv6_netfilter_hooks)); ++ result = nf_register_net_hooks(&init_net, ecm_sfe_ipv6_netfilter_hooks, ARRAY_SIZE(ecm_sfe_ipv6_netfilter_hooks)); + if (result < 0) { + DEBUG_ERROR("Can't register netfilter hooks.\n"); + sfe_drv_ipv6_notify_unregister(); +@@ -1656,8 +1653,8 @@ void ecm_sfe_ipv6_exit(void) + /* + * Stop the network stack hooks + */ +- nf_unregister_hooks(ecm_sfe_ipv6_netfilter_hooks, +- ARRAY_SIZE(ecm_sfe_ipv6_netfilter_hooks)); ++ nf_unregister_net_hooks(&init_net, ecm_sfe_ipv6_netfilter_hooks, ++ ARRAY_SIZE(ecm_sfe_ipv6_netfilter_hooks)); + + /* + * Unregister from the Linux SFE Network driver +--- a/frontends/sfe/ecm_sfe_non_ported_ipv4.c ++++ b/frontends/sfe/ecm_sfe_non_ported_ipv4.c +@@ -46,7 +46,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1829,7 +1828,7 @@ unsigned int ecm_sfe_non_ported_ipv4_pro + /* + * Packet has been decrypted by ipsec, mark it in connection. + */ +- if (unlikely(skb->sp)) { ++ if (unlikely(skb_ext_exist(skb, SKB_EXT_SEC_PATH))) { + ((struct ecm_sfe_non_ported_ipv4_connection_instance *)feci)->flow_ipsec_state = ECM_SFE_IPSEC_STATE_WAS_DECRYPTED; + ((struct ecm_sfe_non_ported_ipv4_connection_instance *)feci)->return_ipsec_state = ECM_SFE_IPSEC_STATE_TO_ENCRYPT; + } +--- a/frontends/sfe/ecm_sfe_non_ported_ipv6.c ++++ b/frontends/sfe/ecm_sfe_non_ported_ipv6.c +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1710,7 +1709,7 @@ unsigned int ecm_sfe_non_ported_ipv6_pro + /* + * Packet has been decrypted by ipsec, mark it in connection. + */ +- if (unlikely(skb->sp)) { ++ if (unlikely(skb_ext_exist(skb, SKB_EXT_SEC_PATH))) { + ((struct ecm_sfe_non_ported_ipv6_connection_instance *)feci)->flow_ipsec_state = ECM_SFE_IPSEC_STATE_WAS_DECRYPTED; + ((struct ecm_sfe_non_ported_ipv6_connection_instance *)feci)->return_ipsec_state = ECM_SFE_IPSEC_STATE_TO_ENCRYPT; + } +--- a/frontends/sfe/ecm_sfe_ported_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv4.c +@@ -46,7 +46,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -2053,7 +2052,7 @@ unsigned int ecm_sfe_ported_ipv4_process + /* + * Packet has been decrypted by ipsec, mark it in connection. + */ +- if (unlikely(skb->sp)) { ++ if (unlikely(skb_ext_exist(skb, SKB_EXT_SEC_PATH))) { + ((struct ecm_sfe_ported_ipv4_connection_instance *)feci)->flow_ipsec_state = ECM_SFE_IPSEC_STATE_WAS_DECRYPTED; + ((struct ecm_sfe_ported_ipv4_connection_instance *)feci)->return_ipsec_state = ECM_SFE_IPSEC_STATE_TO_ENCRYPT; + } +--- a/frontends/sfe/ecm_sfe_ported_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv6.c +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1826,7 +1825,7 @@ unsigned int ecm_sfe_ported_ipv6_process + /* + * Deny acceleration for L2TP-over-UDP tunnel + */ +- if ((in_dev->priv_flags & IFF_PPP_L2TPV2) && ppp_is_xmit_locked(in_dev)) { ++ if ((in_dev->priv_flags_qca_ecm & IFF_QCA_ECM_PPP_L2TPV2) && ppp_is_xmit_locked(in_dev)) { + DEBUG_TRACE("Skip packets for L2TP tunnel in skb %p\n", skb); + can_accel = false; + } +@@ -1958,7 +1957,7 @@ unsigned int ecm_sfe_ported_ipv6_process + /* + * Packet has been decrypted by ipsec, mark it in connection. + */ +- if (unlikely(skb->sp)) { ++ if (unlikely(skb_ext_exist(skb, SKB_EXT_SEC_PATH))) { + ((struct ecm_sfe_ported_ipv6_connection_instance *)feci)->flow_ipsec_state = ECM_SFE_IPSEC_STATE_WAS_DECRYPTED; + ((struct ecm_sfe_ported_ipv6_connection_instance *)feci)->return_ipsec_state = ECM_SFE_IPSEC_STATE_TO_ENCRYPT; + } diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/101-Fix_Kern_Panic_on_UDP_CONNTRACK.patch b/root/package/firmware/nss/qca-nss-ecm/patches/101-Fix_Kern_Panic_on_UDP_CONNTRACK.patch new file mode 100644 index 00000000..6633f72b --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/101-Fix_Kern_Panic_on_UDP_CONNTRACK.patch @@ -0,0 +1,60 @@ +diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c +index 1ce4b61..29e70ba 100644 +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -2171,6 +2171,10 @@ sync_conntrack: + + timeouts = nf_ct_timeout_lookup(ct); + ++ /* Copy of udp_get_timeouts in kernel */ ++ if (!timeouts) ++ timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts; ++ + spin_lock_bh(&ct->lock); + ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); +diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c +index 2adc5ec..08253b6 100644 +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -1883,6 +1883,10 @@ sync_conntrack: + + timeouts = nf_ct_timeout_lookup(ct); + ++ /* Copy of udp_get_timeouts in kernel */ ++ if (!timeouts) ++ timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts; ++ + spin_lock_bh(&ct->lock); + ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); +diff --git a/frontends/sfe/ecm_sfe_ipv4.c b/frontends/sfe/ecm_sfe_ipv4.c +index 7cfe4fc..8f525ee 100644 +--- a/frontends/sfe/ecm_sfe_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ipv4.c +@@ -1608,6 +1608,10 @@ sync_conntrack: + + timeouts = nf_ct_timeout_lookup(ct); + ++ /* Copy of udp_get_timeouts in kernel */ ++ if (!timeouts) ++ timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts; ++ + spin_lock_bh(&ct->lock); + ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); +diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c +index dfde309..47c531a 100644 +--- a/frontends/sfe/ecm_sfe_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ipv6.c +@@ -1321,6 +1321,10 @@ sync_conntrack: + + timeouts = nf_ct_timeout_lookup(ct); + ++ /* Copy of udp_get_timeouts in kernel */ ++ if (!timeouts) ++ timeouts = nf_udp_pernet(nf_ct_net(ct))->timeouts; ++ + spin_lock_bh(&ct->lock); + ct->timeout = jiffies + timeouts[UDP_CT_REPLIED]; + spin_unlock_bh(&ct->lock); diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/200-resolve-high-load.patch b/root/package/firmware/nss/qca-nss-ecm/patches/200-resolve-high-load.patch new file mode 100644 index 00000000..2f39d277 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/200-resolve-high-load.patch @@ -0,0 +1,44 @@ +The sync update work queue tasks is calling uninterruptible sleep function, which is +causing high CPU load. Changed to interruptible sleep function. The stats update +task should be interruptible. + +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b.frontends/nss/ecm_nss_ipv4.c +@@ -2411,7 +2411,7 @@ static void ecm_nss_ipv4_stats_sync_req_ + } + spin_unlock_bh(&ecm_nss_ipv4_lock); + +- usleep_range(ECM_NSS_IPV4_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV4_STATS_SYNC_UDELAY); ++ msleep_interruptible(ECM_NSS_IPV4_STATS_SYNC_UDELAY / 1000); + + /* + * If index is 0, we are starting a new round, but if we still have time remain +@@ -2425,7 +2425,7 @@ static void ecm_nss_ipv4_stats_sync_req_ + } + + if (ecm_nss_ipv4_next_req_time > current_jiffies) { +- msleep(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies)); ++ msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies)); + } + ecm_nss_ipv4_roll_check_jiffies = jiffies; + ecm_nss_ipv4_next_req_time = ecm_nss_ipv4_roll_check_jiffies + ECM_NSS_IPV4_STATS_SYNC_PERIOD; +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b.frontends/nss/ecm_nss_ipv6.c +@@ -2128,7 +2128,7 @@ static void ecm_nss_ipv6_stats_sync_req_ + } + spin_unlock_bh(&ecm_nss_ipv6_lock); + +- usleep_range(ECM_NSS_IPV6_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV6_STATS_SYNC_UDELAY); ++ msleep_interruptible(ECM_NSS_IPV6_STATS_SYNC_UDELAY / 1000); + + /* + * If index is 0, we are starting a new round, but if we still have time remain +@@ -2142,7 +2142,7 @@ static void ecm_nss_ipv6_stats_sync_req_ + } + + if (ecm_nss_ipv6_next_req_time > current_jiffies) { +- msleep(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies)); ++ msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies)); + } + ecm_nss_ipv6_roll_check_jiffies = jiffies; + ecm_nss_ipv6_next_req_time = ecm_nss_ipv6_roll_check_jiffies + ECM_NSS_IPV6_STATS_SYNC_PERIOD; diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/203-rework-nfct-notification.patch b/root/package/firmware/nss/qca-nss-ecm/patches/203-rework-nfct-notification.patch new file mode 100644 index 00000000..a0e09c1f --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/203-rework-nfct-notification.patch @@ -0,0 +1,20 @@ +--- a/ecm_conntrack_notifier.c ++++ b/ecm_conntrack_notifier.c +@@ -411,7 +411,7 @@ int ecm_conntrack_notifier_init(struct d + /* + * Eventing subsystem is available so we register a notifier hook to get fast notifications of expired connections + */ +- result = nf_conntrack_register_notifier(&init_net, &ecm_conntrack_notifier); ++ result = nf_conntrack_register_chain_notifier(&init_net, &ecm_conntrack_notifier); + if (result < 0) { + DEBUG_ERROR("Can't register nf notifier hook.\n"); + debugfs_remove_recursive(ecm_conntrack_notifier_dentry); +@@ -430,7 +430,7 @@ void ecm_conntrack_notifier_exit(void) + { + DEBUG_INFO("ECM Conntrack Notifier exit\n"); + #ifdef CONFIG_NF_CONNTRACK_EVENTS +- nf_conntrack_unregister_notifier(&init_net, &ecm_conntrack_notifier); ++ nf_conntrack_unregister_chain_notifier(&init_net, &ecm_conntrack_notifier); + #endif + /* + * Remove the debugfs files recursively. diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/400-Check-TCP_UDP-conntrack-state-earlier.patch b/root/package/firmware/nss/qca-nss-ecm/patches/400-Check-TCP_UDP-conntrack-state-earlier.patch new file mode 100644 index 00000000..b7882c1b --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/400-Check-TCP_UDP-conntrack-state-earlier.patch @@ -0,0 +1,236 @@ +From 90cace88a342e77ee8ca1e961cf7b7a7930d4c89 Mon Sep 17 00:00:00 2001 +From: Murat Sezgin +Date: Mon, 9 Mar 2020 12:51:03 -0700 +Subject: [qca-nss-ecm] Check TCP/UDP conntrack state earlier + +Check the conntrack state before processing the flow +and adding it to the database. The unconfirmed +connections can be changed after the confirmation. + +Changed the TCP tracker connection state matrix to set the +state of the connection as ESTABLISHED when any of the src or +dest side is set as ESTABLISHED. With this change ECM will not +handle the SYN and SYN-ACK packets of the TCP handshake. Only the +ACK and FIN flaged packets will be used during the creation and +closing the connection respectively. + +Signed-off-by: Murat Sezgin +Change-Id: I3e0a58d604df4c6a85478ca9c05f24d50cd8c894 +--- + ecm_classifier_default.c | 36 ++++++++---------------------------- + ecm_tracker_tcp.c | 4 ++-- + frontends/nss/ecm_nss_ported_ipv4.c | 17 +++++++++++++++++ + frontends/nss/ecm_nss_ported_ipv6.c | 17 +++++++++++++++++ + frontends/sfe/ecm_sfe_ported_ipv4.c | 17 +++++++++++++++++ + frontends/sfe/ecm_sfe_ported_ipv6.c | 17 +++++++++++++++++ + 6 files changed, 78 insertions(+), 30 deletions(-) + +diff --git a/ecm_classifier_default.c b/ecm_classifier_default.c +index 22c4bec..d04cdfa 100644 +--- a/ecm_classifier_default.c ++++ b/ecm_classifier_default.c +@@ -1,6 +1,6 @@ + /* + ************************************************************************** +- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2014-2016, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. +@@ -285,12 +285,12 @@ static void ecm_classifier_default_process(struct ecm_classifier_instance *aci, + } + + /* +- * Check the TCP connection state. ++ * Check the TCP connection state, when the ct is NULL. ++ * ct valid case was already checked in the ecm_nss{sfe}_ported_ipv4{6}_process functions. + * If we are not established then we deny acceleration. +- * Take lead from conntrack if exists. + */ + ct = nf_ct_get(skb, &ctinfo); +- if (ct == NULL) { ++ if (!ct) { + DEBUG_TRACE("%p: No Conntrack found for packet, using ECM tracker state\n", cdii); + if (unlikely(prevailing_state != ECM_TRACKER_CONNECTION_STATE_ESTABLISHED)) { + cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO; +@@ -298,29 +298,10 @@ static void ecm_classifier_default_process(struct ecm_classifier_instance *aci, + } + } else { + /* +- * Unconfirmed connection may be dropped by Linux at the final step, +- * So we don't allow acceleration for the unconfirmed connections. +- */ +- if (!nf_ct_is_confirmed(ct)) { +- DEBUG_TRACE("%p: Unconfirmed connection\n", ct); +- cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO; +- goto return_response; +- } +- +- /* +- * Don't try to manage a non-established connection. +- */ +- if (!test_bit(IPS_ASSURED_BIT, &ct->status)) { +- DEBUG_TRACE("%p: Non-established connection\n", ct); +- cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO; +- goto return_response; +- } +- +- /* +- * If the connection is shutting down do not manage it. +- * state can not be SYN_SENT, SYN_RECV because connection is assured +- * Not managed states: FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE. +- */ ++ * If the connection is shutting down do not manage it. ++ * state can not be SYN_SENT, SYN_RECV because connection is assured ++ * Not managed states: FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE. ++ */ + spin_lock_bh(&ct->lock); + if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) { + spin_unlock_bh(&ct->lock); +@@ -333,7 +314,6 @@ static void ecm_classifier_default_process(struct ecm_classifier_instance *aci, + + return_response: + ; +- + /* + * Return the process response + */ +diff --git a/ecm_tracker_tcp.c b/ecm_tracker_tcp.c +index f073c36..e5b327a 100644 +--- a/ecm_tracker_tcp.c ++++ b/ecm_tracker_tcp.c +@@ -257,9 +257,9 @@ static DEFINE_SPINLOCK(ecm_tracker_tcp_lock); /* Global lock for the tracker gl + */ + static ecm_tracker_connection_state_t ecm_tracker_tcp_connection_state_matrix[ECM_TRACKER_SENDER_STATE_MAX][ECM_TRACKER_SENDER_STATE_MAX] = + { /* Unknown Establishing Established Closing Closed Fault */ +- /* Unknown */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT}, ++ /* Unknown */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT}, + /* Establishing */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT}, +- /* Established */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_FAULT}, ++ /* Established */ {ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_ESTABLISHING, ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_FAULT}, + /* Closing */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_FAULT}, + /* Closed */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSING, ECM_TRACKER_CONNECTION_STATE_CLOSED, ECM_TRACKER_CONNECTION_STATE_FAULT}, + /* Fault */ {ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT, ECM_TRACKER_CONNECTION_STATE_FAULT}, +diff --git a/frontends/nss/ecm_nss_ported_ipv4.c b/frontends/nss/ecm_nss_ported_ipv4.c +index 1435ec0..34c056f 100644 +--- a/frontends/nss/ecm_nss_ported_ipv4.c ++++ b/frontends/nss/ecm_nss_ported_ipv4.c +@@ -2002,8 +2002,25 @@ unsigned int ecm_nss_ported_ipv4_process(struct net_device *out_dev, struct net_ + int protocol = (int)orig_tuple->dst.protonum; + __be16 *layer4hdr = NULL; + ++ /* ++ * Unconfirmed connection may be dropped by Linux at the final step, ++ * So we don't allow acceleration for the unconfirmed connections. ++ */ ++ if (likely(ct) && !nf_ct_is_confirmed(ct)) { ++ DEBUG_WARN("%p: Unconfirmed connection\n", ct); ++ return NF_ACCEPT; ++ } ++ + if (protocol == IPPROTO_TCP) { + /* ++ * Don't try to manage a non-established connection. ++ */ ++ if (likely(ct) && !test_bit(IPS_ASSURED_BIT, &ct->status)) { ++ DEBUG_WARN("%p: Non-established TCP connection\n", ct); ++ return NF_ACCEPT; ++ } ++ ++ /* + * Extract TCP header to obtain port information + */ + tcp_hdr = ecm_tracker_tcp_check_header_and_read(skb, iph, &tcp_hdr_buff); +diff --git a/frontends/nss/ecm_nss_ported_ipv6.c b/frontends/nss/ecm_nss_ported_ipv6.c +index 4c154a6..bd6349b 100644 +--- a/frontends/nss/ecm_nss_ported_ipv6.c ++++ b/frontends/nss/ecm_nss_ported_ipv6.c +@@ -1914,8 +1914,25 @@ unsigned int ecm_nss_ported_ipv6_process(struct net_device *out_dev, + int protocol = (int)orig_tuple->dst.protonum; + __be16 *layer4hdr = NULL; + ++ /* ++ * Unconfirmed connection may be dropped by Linux at the final step, ++ * So we don't allow acceleration for the unconfirmed connections. ++ */ ++ if (likely(ct) && !nf_ct_is_confirmed(ct)) { ++ DEBUG_WARN("%p: Unconfirmed connection\n", ct); ++ return NF_ACCEPT; ++ } ++ + if (protocol == IPPROTO_TCP) { + /* ++ * Don't try to manage a non-established connection. ++ */ ++ if (likely(ct) && !test_bit(IPS_ASSURED_BIT, &ct->status)) { ++ DEBUG_WARN("%p: Non-established TCP connection\n", ct); ++ return NF_ACCEPT; ++ } ++ ++ /* + * Extract TCP header to obtain port information + */ + tcp_hdr = ecm_tracker_tcp_check_header_and_read(skb, iph, &tcp_hdr_buff); +diff --git a/frontends/sfe/ecm_sfe_ported_ipv4.c b/frontends/sfe/ecm_sfe_ported_ipv4.c +index e034cde..df1ce57 100644 +--- a/frontends/sfe/ecm_sfe_ported_ipv4.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv4.c +@@ -1805,8 +1805,25 @@ unsigned int ecm_sfe_ported_ipv4_process(struct net_device *out_dev, struct net_ + int protocol = (int)orig_tuple->dst.protonum; + __be16 *layer4hdr = NULL; + ++ /* ++ * Unconfirmed connection may be dropped by Linux at the final step, ++ * So we don't allow acceleration for the unconfirmed connections. ++ */ ++ if (likely(ct) && !nf_ct_is_confirmed(ct)) { ++ DEBUG_WARN("%p: Unconfirmed connection\n", ct); ++ return NF_ACCEPT; ++ } ++ + if (protocol == IPPROTO_TCP) { + /* ++ * Don't try to manage a non-established connection. ++ */ ++ if (likely(ct) && !test_bit(IPS_ASSURED_BIT, &ct->status)) { ++ DEBUG_WARN("%p: Non-established TCP connection\n", ct); ++ return NF_ACCEPT; ++ } ++ ++ /* + * Extract TCP header to obtain port information + */ + tcp_hdr = ecm_tracker_tcp_check_header_and_read(skb, iph, &tcp_hdr_buff); +diff --git a/frontends/sfe/ecm_sfe_ported_ipv6.c b/frontends/sfe/ecm_sfe_ported_ipv6.c +index 6ac05ad..657a1c7 100644 +--- a/frontends/sfe/ecm_sfe_ported_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ported_ipv6.c +@@ -1746,8 +1746,25 @@ unsigned int ecm_sfe_ported_ipv6_process(struct net_device *out_dev, + int protocol = (int)orig_tuple->dst.protonum; + __be16 *layer4hdr = NULL; + ++ /* ++ * Unconfirmed connection may be dropped by Linux at the final step, ++ * So we don't allow acceleration for the unconfirmed connections. ++ */ ++ if (likely(ct) && !nf_ct_is_confirmed(ct)) { ++ DEBUG_WARN("%p: Unconfirmed connection\n", ct); ++ return NF_ACCEPT; ++ } ++ + if (protocol == IPPROTO_TCP) { + /* ++ * Don't try to manage a non-established connection. ++ */ ++ if (likely(ct) && !test_bit(IPS_ASSURED_BIT, &ct->status)) { ++ DEBUG_WARN("%p: Non-established TCP connection\n", ct); ++ return NF_ACCEPT; ++ } ++ ++ /* + * Extract TCP header to obtain port information + */ + tcp_hdr = ecm_tracker_tcp_check_header_and_read(skb, iph, &tcp_hdr_buff); +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-NSS-stats-request-roll-over-issue.patch b/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-NSS-stats-request-roll-over-issue.patch new file mode 100644 index 00000000..217054bb --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-NSS-stats-request-roll-over-issue.patch @@ -0,0 +1,52 @@ +From 9ad19ffdcfdf77baf3abd4fcc933fd3dc8e791a5 Mon Sep 17 00:00:00 2001 +From: Murat Sezgin +Date: Sat, 20 Jun 2020 09:41:01 -0700 +Subject: [qca-nss-ecm] Fix NSS stats request roll over issue + +Use the correct timer API to check the next request time +when jiffies wrap happens. + +Signed-off-by: Murat Sezgin +Change-Id: I18646d28df7e17daeff2986dfe4bd73866d47668 +--- + frontends/nss/ecm_nss_ipv4.c | 4 ++-- + frontends/nss/ecm_nss_ipv6.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c +index 3eaf5d8..80e1aee 100644 +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -2421,10 +2421,10 @@ static void ecm_nss_ipv4_stats_sync_req_work(struct work_struct *work) + current_jiffies = jiffies; + + if (time_is_after_jiffies(ecm_nss_ipv4_roll_check_jiffies)) { +- ecm_nss_ipv4_next_req_time = 0; ++ ecm_nss_ipv4_next_req_time = jiffies + ECM_NSS_IPV4_STATS_SYNC_PERIOD; + } + +- if (ecm_nss_ipv4_next_req_time > current_jiffies) { ++ if (time_after(ecm_nss_ipv4_next_req_time, current_jiffies)) { + msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv4_next_req_time - current_jiffies)); + } + ecm_nss_ipv4_roll_check_jiffies = jiffies; +diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c +index 288dc55..483421e 100644 +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -2135,10 +2135,10 @@ static void ecm_nss_ipv6_stats_sync_req_work(struct work_struct *work) + current_jiffies = jiffies; + + if (time_is_after_jiffies(ecm_nss_ipv6_roll_check_jiffies)) { +- ecm_nss_ipv6_next_req_time = 0; ++ ecm_nss_ipv6_next_req_time = jiffies + ECM_NSS_IPV6_STATS_SYNC_PERIOD; + } + +- if (ecm_nss_ipv6_next_req_time > current_jiffies) { ++ if (time_after(ecm_nss_ipv6_next_req_time, current_jiffies)) { + msleep_interruptible(jiffies_to_msecs(ecm_nss_ipv6_next_req_time - current_jiffies)); + } + ecm_nss_ipv6_roll_check_jiffies = jiffies; +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-for-ref-leak-during-multicast.patch b/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-for-ref-leak-during-multicast.patch new file mode 100644 index 00000000..e1df653b --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-for-ref-leak-during-multicast.patch @@ -0,0 +1,112 @@ +From 4b41703a181b7187d9ff8cb744eb96d09997387c Mon Sep 17 00:00:00 2001 +From: Suman Ghosh +Date: Wed, 19 Feb 2020 15:09:19 +0530 +Subject: [qca-nss-ecm] Fix for ref leak during multicast 'to' hierarchy + creation + +Change-Id: I89df9dbe5ea054cf3b87d55ce68a751cb1d6c24f +Signed-off-by: Suman Ghosh +--- + ecm_interface.c | 34 ++++++++++++++++++++++++++++++---- + 1 file changed, 30 insertions(+), 4 deletions(-) + +diff --git a/ecm_interface.c b/ecm_interface.c +index 4f7a886..2a0ca5b 100644 +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -3885,13 +3885,13 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + dest_dev = dev_get_by_index(&init_net, *dst_if_index); + if (!dest_dev) { + if (!src_dev_is_bridge) { +- int i; +- + /* + * If already constructed any interface heirarchies before hitting + * this error condition then Deref all interface heirarchies. + */ + if (valid_if > 0) { ++ int i; ++ + for (i = 0; i < valid_if; i++) { + ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i); + ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces); +@@ -3902,11 +3902,14 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + /* + * If valid netdev not found, Return 0 + */ ++ if (br_dev_src) { ++ dev_put(br_dev_src); ++ } ++ + return 0; + } + + dest_dev = br_dev_src; +- + } + + dest_dev_type = dest_dev->type; +@@ -3945,6 +3948,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + } + } + ++ if (br_dev_src && (dest_dev != br_dev_src)) { ++ dev_put(br_dev_src); ++ } ++ + dev_put(dest_dev); + return 0; + } +@@ -3972,6 +3979,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]); + } + ++ if (br_dev_src && (dest_dev != br_dev_src)) { ++ dev_put(br_dev_src); ++ } ++ + dev_put(dest_dev); + dev_put(mc_br_slave_dev); + return 0; +@@ -3997,6 +4008,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + } + } + ++ if (br_dev_src && (dest_dev != br_dev_src)) { ++ dev_put(br_dev_src); ++ } ++ + dev_put(dest_dev); + dev_put(mc_br_slave_dev); + return 0; +@@ -4032,6 +4047,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + } + } + ++ if (br_dev_src && (dest_dev != br_dev_src)) { ++ dev_put(br_dev_src); ++ } ++ + dev_put(dest_dev); + return 0; + } +@@ -4042,8 +4061,15 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + valid_if++; + } + +- dev_put(dest_dev); ++ if (dest_dev != br_dev_src) { ++ dev_put(dest_dev); ++ } + } ++ ++ if (br_dev_src) { ++ dev_put(br_dev_src); ++ } ++ + return total_ii_count; + } + EXPORT_SYMBOL(ecm_interface_multicast_heirarchy_construct_routed); +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-neighbour-solicitation-send-function.patch b/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-neighbour-solicitation-send-function.patch new file mode 100644 index 00000000..7d32d6fd --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/401-Fix-neighbour-solicitation-send-function.patch @@ -0,0 +1,33 @@ +From 72e3ae508906553e7bc982bf3c0d99bb1cbe9008 Mon Sep 17 00:00:00 2001 +From: Murat Sezgin +Date: Wed, 20 Nov 2019 16:23:06 -0800 +Subject: [qca-nss-ecm] Fix neighbour solicitation send function. + +dst_ops->neigh_lookup function pointer is set to the +ip6_neigh_lookup function. This function returns an +error pointer with the ERR_PTR() macro. So, we should +check the return value of this function pointer with +the IS_ERR() macro. + +Change-Id: I188a6e53278faaa68f1854524f612efc1f7451fe +Signed-off-by: Murat Sezgin +--- + ecm_interface.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ecm_interface.c b/ecm_interface.c +index 3f8554b..36509f0 100644 +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -1100,7 +1100,7 @@ void ecm_interface_send_neighbour_solicitation(struct net_device *dev, ip_addr_t + #else + neigh = rt6i->dst.ops->neigh_lookup(&rt6i->dst, NULL, &dst_addr); + #endif +- if (neigh == NULL) { ++ if (IS_ERR(neigh)) { + DEBUG_TRACE("Neighbour lookup failure for destination IPv6 address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr)); + dst_release(&rt6i->dst); + return; +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/402-Reference-leak-during-multicast_PPPoE-bridge.patch b/root/package/firmware/nss/qca-nss-ecm/patches/402-Reference-leak-during-multicast_PPPoE-bridge.patch new file mode 100644 index 00000000..97ce7a7e --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/402-Reference-leak-during-multicast_PPPoE-bridge.patch @@ -0,0 +1,260 @@ +From 7c0610828b835b2aab96dd50ec841a3a28689112 Mon Sep 17 00:00:00 2001 +From: Suman Ghosh +Date: Mon, 16 Mar 2020 15:22:18 +0530 +Subject: [qca-nss-ecm] Reference leak during multicast + PPPoE bridge + +Signed-off-by: Suman Ghosh +Change-Id: I4472035f1bbb087e637169762ae2648c0fda792a +--- + ecm_interface.c | 136 +++++++++++++++++++++++++------------------------------- + 1 file changed, 60 insertions(+), 76 deletions(-) + +diff --git a/ecm_interface.c b/ecm_interface.c +index 1614336..c0d2357 100644 +--- a/ecm_interface.c ++++ b/ecm_interface.c +@@ -3796,6 +3796,25 @@ fail: + } + + /* ++ * ecm_interface_hierarchy_delete() ++ * Delete hierarchy of the requested interfaces. ++ */ ++static inline void ecm_interface_hierarchy_delete(struct ecm_db_iface_instance *interfaces, ++ uint32_t *interface_first_base, ++ int valid_if) ++{ ++ struct ecm_db_iface_instance *to_list_single[ECM_DB_IFACE_HEIRARCHY_MAX]; ++ struct ecm_db_iface_instance *ifaces; ++ int i; ++ ++ for (i = 0; i < valid_if; i++) { ++ ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i); ++ ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces); ++ ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]); ++ } ++} ++ ++/* + * ecm_interface_multicast_heirarchy_construct_routed() + * Create destination interface heirarchy for a routed multicast connectiona + * +@@ -3816,7 +3835,6 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + uint32_t *interface_first_base, bool mfc_update, + __be16 *layer4hdr, struct sk_buff *skb) + { +- struct ecm_db_iface_instance *to_list_single[ECM_DB_IFACE_HEIRARCHY_MAX]; + struct ecm_db_iface_instance *ifaces; + struct net_device *dest_dev = NULL; + struct net_device *br_dev_src = NULL; +@@ -3829,7 +3847,7 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + int if_index; + int ii_cnt; + int total_ii_count = 0; +- bool src_dev_is_bridge = false; ++ bool src_dev_is_bridge = false, dest_dev_is_br_dev_src = false; + + DEBUG_TRACE("Construct interface heirarchy for dest_addr: " ECM_IP_ADDR_DOT_FMT " src_addr: " ECM_IP_ADDR_DOT_FMT "total destination ifs %d\n", + ECM_IP_ADDR_TO_DOT(packet_dest_addr), ECM_IP_ADDR_TO_DOT(packet_src_addr), max_if); +@@ -3876,6 +3894,7 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + continue; + } + ++ dest_dev_is_br_dev_src = false; + dest_dev = dev_get_by_index(&init_net, *dst_if_index); + if (!dest_dev) { + if (!src_dev_is_bridge) { +@@ -3884,26 +3903,23 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + * this error condition then Deref all interface heirarchies. + */ + if (valid_if > 0) { +- int i; +- +- for (i = 0; i < valid_if; i++) { +- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i); +- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces); +- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]); +- } ++ ecm_interface_hierarchy_delete(interfaces, interface_first_base, valid_if); + } + +- /* +- * If valid netdev not found, Return 0 +- */ +- if (br_dev_src) { +- dev_put(br_dev_src); +- } +- +- return 0; ++ goto fail1; + } + + dest_dev = br_dev_src; ++ ++ /* ++ * In some cases when WAN interface is added to bridge and traffic is downstream, ++ * the bridge device is part of the destination list from MFC, and at the same time ++ * 'src_dev_is_bridge' will be true as well. In such cases we will need to release ++ * the hold on the bridge device separately for dest_dev and br_dev_src. ++ * Setting this flag to true indicates that this is not the case, ++ * and that releasing the hold once is enough ++ */ ++ dest_dev_is_br_dev_src = true; + } + + dest_dev_type = dest_dev->type; +@@ -3927,7 +3943,6 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + } + + if ((if_num < 0) || (if_num > ECM_DB_MULTICAST_IF_MAX)) { +- int i; + DEBUG_WARN("MCS is not ready\n"); + + /* +@@ -3935,19 +3950,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + * this error condition then Deref all interface heirarchies. + */ + if (valid_if > 0) { +- for (i = 0; i < valid_if; i++) { +- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i); +- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces); +- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]); +- } ++ ecm_interface_hierarchy_delete(interfaces, interface_first_base, valid_if); + } + +- if (br_dev_src && (dest_dev != br_dev_src)) { +- dev_put(br_dev_src); +- } +- +- dev_put(dest_dev); +- return 0; ++ goto fail2; + } + + if (in_dev && !mfc_update) { +@@ -3955,34 +3961,20 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + } + + for (br_if = 0; br_if < if_num; br_if++) { ++ int total_if = valid_if + br_if; ++ + mc_br_slave_dev = dev_get_by_index(&init_net, mc_dst_if_index[br_if]); + if (!mc_br_slave_dev) { + continue; + } + +- if ((valid_if + br_if) > ECM_DB_MULTICAST_IF_MAX) { +- int i; +- +- /* +- * If already constructed any interface heirarchies before hitting +- * this error condition then Deref all interface heirarchies. +- */ +- for (i = 0; i < (valid_if + br_if); i++) { +- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i); +- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces); +- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]); +- } +- +- if (br_dev_src && (dest_dev != br_dev_src)) { +- dev_put(br_dev_src); +- } +- +- dev_put(dest_dev); ++ if (total_if > ECM_DB_MULTICAST_IF_MAX) { ++ ecm_interface_hierarchy_delete(interfaces, interface_first_base, total_if); + dev_put(mc_br_slave_dev); +- return 0; ++ goto fail2; + } + +- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, valid_if + br_if); ++ ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, total_if); + /* + * Construct a single interface heirarchy of a multicast dev. + */ +@@ -3993,25 +3985,15 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + * If already constructed any interface heirarchies before hitting + * this error condition then Deref all interface heirarchies. + */ +- if ((valid_if + br_if) > 0) { +- int i; +- for (i = 0; i < (valid_if + br_if); i++) { +- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i); +- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces); +- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]); +- } +- } +- +- if (br_dev_src && (dest_dev != br_dev_src)) { +- dev_put(br_dev_src); ++ if (total_if > 0) { ++ ecm_interface_hierarchy_delete(interfaces, interface_first_base, total_if); + } + +- dev_put(dest_dev); + dev_put(mc_br_slave_dev); +- return 0; ++ goto fail2; + } + +- interface_first = ecm_db_multicast_if_first_get_at_index(interface_first_base, (valid_if + br_if)); ++ interface_first = ecm_db_multicast_if_first_get_at_index(interface_first_base, total_if); + *interface_first = ii_cnt; + total_ii_count += ii_cnt; + dev_put(mc_br_slave_dev); +@@ -4033,20 +4015,10 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + * this error condition then Deref all interface heirarchies. + */ + if (valid_if > 0) { +- int i; +- for (i = 0; i < valid_if; i++) { +- ifaces = ecm_db_multicast_if_heirarchy_get(interfaces, i); +- ecm_db_multicast_copy_if_heirarchy(to_list_single, ifaces); +- ecm_db_connection_interfaces_deref(to_list_single, interface_first_base[i]); +- } +- } +- +- if (br_dev_src && (dest_dev != br_dev_src)) { +- dev_put(br_dev_src); ++ ecm_interface_hierarchy_delete(interfaces, interface_first_base, valid_if); + } + +- dev_put(dest_dev); +- return 0; ++ goto fail2; + } + + interface_first = ecm_db_multicast_if_first_get_at_index(interface_first_base, valid_if); +@@ -4055,7 +4027,7 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + valid_if++; + } + +- if (dest_dev != br_dev_src) { ++ if (!dest_dev_is_br_dev_src) { + dev_put(dest_dev); + } + } +@@ -4065,6 +4037,18 @@ int32_t ecm_interface_multicast_heirarchy_construct_routed(struct ecm_front_end_ + } + + return total_ii_count; ++ ++fail2: ++ if (!dest_dev_is_br_dev_src) { ++ dev_put(dest_dev); ++ } ++ ++fail1: ++ if (br_dev_src) { ++ dev_put(br_dev_src); ++ } ++ ++ return 0; + } + EXPORT_SYMBOL(ecm_interface_multicast_heirarchy_construct_routed); + +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/403-Access-global-accelerated-count-under-lock.patch b/root/package/firmware/nss/qca-nss-ecm/patches/403-Access-global-accelerated-count-under-lock.patch new file mode 100644 index 00000000..d458e113 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/403-Access-global-accelerated-count-under-lock.patch @@ -0,0 +1,59 @@ +From 65a49ebd1bd12b9952dfa214de0a2da43ba2abed Mon Sep 17 00:00:00 2001 +From: Bhaskar Valaboju +Date: Tue, 13 Aug 2019 14:21:03 +0530 +Subject: [qca-nss-ecm]: Access global ipv4/ipv6 accelerated count under lock + +Flow accelerated count maintained as global variables are accessed +in multiple kernel contexts. These counters are updated under lock, +but read without lock. Read is in kernel thread context (workqueue) +and sometimes it is taking stale entry (0) and doesn't change. +Lock is added to read correct value. + +Change-Id: I74cf27fe5097c6ae7dfcc06319762a8a322d79a3 +Signed-off-by: Bhaskar Valaboju +--- + frontends/nss/ecm_nss_ipv4.c | 3 +++ + frontends/nss/ecm_nss_ipv6.c | 3 +++ + 2 files changed, 6 insertions(+) + +(limited to 'frontends') + +diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c +index afd660e..4e66cdf 100644 +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -2288,10 +2288,13 @@ static void ecm_nss_ipv4_stats_sync_req_work(struct work_struct *work) + int retry = 3; + unsigned long int current_jiffies; + ++ spin_lock_bh(&ecm_nss_ipv4_lock); + if (ecm_nss_ipv4_accelerated_count == 0) { ++ spin_unlock_bh(&ecm_nss_ipv4_lock); + DEBUG_TRACE("There is no accelerated IPv4 connection\n"); + goto reschedule; + } ++ spin_unlock_bh(&ecm_nss_ipv4_lock); + + usleep_range(ECM_NSS_IPV4_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV4_STATS_SYNC_UDELAY); + +diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c +index 1f7f51e..55849e7 100644 +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -1998,10 +1998,13 @@ static void ecm_nss_ipv6_stats_sync_req_work(struct work_struct *work) + int retry = 3; + unsigned long int current_jiffies; + ++ spin_lock_bh(&ecm_nss_ipv6_lock); + if (ecm_nss_ipv6_accelerated_count == 0) { ++ spin_unlock_bh(&ecm_nss_ipv6_lock); + DEBUG_TRACE("There is no accelerated IPv6 connection\n"); + goto reschedule; + } ++ spin_unlock_bh(&ecm_nss_ipv6_lock); + + usleep_range(ECM_NSS_IPV6_STATS_SYNC_UDELAY - 100, ECM_NSS_IPV6_STATS_SYNC_UDELAY); + +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/403-Fix-IPv6-neighbor-solicitation-request.patch b/root/package/firmware/nss/qca-nss-ecm/patches/403-Fix-IPv6-neighbor-solicitation-request.patch new file mode 100644 index 00000000..7639b88a --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/403-Fix-IPv6-neighbor-solicitation-request.patch @@ -0,0 +1,83 @@ +From b96002061178f399c1e58a9ad821e5096a64f788 Mon Sep 17 00:00:00 2001 +From: Murat Sezgin +Date: Mon, 23 Mar 2020 10:59:39 -0700 +Subject: [qca-nss-ecm] Fix IPv6 neighbor solicitation request + +Send the solicitation request to the GW address, when +a GW address is found, while establishing the node instance. + +Signed-off-by: Murat Sezgin +Change-Id: I2187569bcfd05b0d091cf8c79171ee3c41c39cb9 +--- + frontends/nss/ecm_nss_ipv6.c | 7 ++++--- + frontends/nss/ecm_nss_multicast_ipv6.c | 9 +++++++++ + frontends/sfe/ecm_sfe_ipv6.c | 7 ++++--- + 3 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c +index c7dd37f..9011e18 100644 +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -527,13 +527,14 @@ struct ecm_db_node_instance *ecm_nss_ipv6_node_establish_and_ref(struct ecm_fron + struct net_device *master; + master = ecm_interface_get_and_hold_dev_master(dev); + DEBUG_ASSERT(master, "Expected a master\n"); +- ecm_interface_send_neighbour_solicitation(master, addr); ++ ecm_interface_send_neighbour_solicitation(master, gw_addr); + dev_put(master); + } else { +- ecm_interface_send_neighbour_solicitation(dev, addr); ++ ecm_interface_send_neighbour_solicitation(dev, gw_addr); + } + +- DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr)); ++ DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT " gw: " ECM_IP_ADDR_OCTAL_FMT "\n", ++ ECM_IP_ADDR_TO_OCTAL(addr), ECM_IP_ADDR_TO_OCTAL(gw_addr)); + return NULL; + } + done: +diff --git a/frontends/nss/ecm_nss_multicast_ipv6.c b/frontends/nss/ecm_nss_multicast_ipv6.c +index a361eec..38fde95 100644 +--- a/frontends/nss/ecm_nss_multicast_ipv6.c ++++ b/frontends/nss/ecm_nss_multicast_ipv6.c +@@ -2558,6 +2558,15 @@ static struct ecm_db_node_instance *ecm_nss_multicast_ipv6_node_establish_and_re + #endif + if (!ecm_interface_mac_addr_get(addr, node_addr, &on_link, gw_addr)) { + DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr)); ++ ++ /* ++ * If there is a gw_addr found during the lookup, use that address ++ * for neighbour solicitation request. ++ */ ++ if (!ECM_IP_ADDR_IS_NULL(gw_addr)) { ++ ECM_IP_ADDR_COPY(addr, gw_addr); ++ } ++ + if (ecm_front_end_is_bridge_port(dev)) { + struct net_device *master; + master = ecm_interface_get_and_hold_dev_master(dev); +diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c +index 3fd5d46..51a9ccb 100644 +--- a/frontends/sfe/ecm_sfe_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ipv6.c +@@ -256,13 +256,14 @@ struct ecm_db_node_instance *ecm_sfe_ipv6_node_establish_and_ref(struct ecm_fron + struct net_device *master; + master = ecm_interface_get_and_hold_dev_master(dev); + DEBUG_ASSERT(master, "Expected a master\n"); +- ecm_interface_send_neighbour_solicitation(master, addr); ++ ecm_interface_send_neighbour_solicitation(master, gw_addr); + dev_put(master); + } else { +- ecm_interface_send_neighbour_solicitation(dev, addr); ++ ecm_interface_send_neighbour_solicitation(dev, gw_addr); + } + +- DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(addr)); ++ DEBUG_TRACE("Failed to obtain mac for host " ECM_IP_ADDR_OCTAL_FMT " gw: " ECM_IP_ADDR_OCTAL_FMT "\n", ++ ECM_IP_ADDR_TO_OCTAL(addr), ECM_IP_ADDR_TO_OCTAL(gw_addr)); + return NULL; + } + done: +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/404-IPv6-solicitation-fix-with-zero-gateway-address.patch b/root/package/firmware/nss/qca-nss-ecm/patches/404-IPv6-solicitation-fix-with-zero-gateway-address.patch new file mode 100644 index 00000000..bdedff44 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/404-IPv6-solicitation-fix-with-zero-gateway-address.patch @@ -0,0 +1,63 @@ +From 5b51ae2f1eca61c6f68e40a05333da5a362ff327 Mon Sep 17 00:00:00 2001 +From: Murat Sezgin +Date: Mon, 13 Apr 2020 09:01:48 -0700 +Subject: [qca-nss-ecm] IPv6 solicitation fix with zero gateway address + +The ECM function can find a zero gateway address for +a host IP address. In this case, we need to use the +host IP address while sending the solicitation request. + +Signed-off-by: Murat Sezgin +Change-Id: I1979834088ddfe1843566f51f64348f79e2df0fc +--- + frontends/nss/ecm_nss_ipv6.c | 11 ++++++++++- + frontends/sfe/ecm_sfe_ipv6.c | 11 ++++++++++- + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c +index a05781b..9eb591c 100644 +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -516,7 +516,16 @@ struct ecm_db_node_instance *ecm_nss_ipv6_node_establish_and_ref(struct ecm_fron + return NULL; + } + +- DEBUG_TRACE("Have a gw address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(gw_addr)); ++ /* ++ * The found gateway address can be all zeros, ++ * so in this case use the host address. ++ */ ++ if (ECM_IP_ADDR_IS_NULL(gw_addr)) { ++ DEBUG_TRACE("GW address is found as zeros, so use host IP\n"); ++ ECM_IP_ADDR_COPY(gw_addr, addr); ++ } else { ++ DEBUG_TRACE("Have a gw address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(gw_addr)); ++ } + + if (ecm_interface_mac_addr_get_no_route(dev, gw_addr, node_addr)) { + DEBUG_TRACE("Found the mac address for gateway\n"); +diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c +index 51a9ccb..e609df7 100644 +--- a/frontends/sfe/ecm_sfe_ipv6.c ++++ b/frontends/sfe/ecm_sfe_ipv6.c +@@ -245,7 +245,16 @@ struct ecm_db_node_instance *ecm_sfe_ipv6_node_establish_and_ref(struct ecm_fron + return NULL; + } + +- DEBUG_TRACE("Have a gw address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(gw_addr)); ++ /* ++ * The found gateway address can be all zeros, ++ * so in this case use the host address. ++ */ ++ if (ECM_IP_ADDR_IS_NULL(gw_addr)) { ++ DEBUG_TRACE("GW address is found as zeros, so use host IP\n"); ++ ECM_IP_ADDR_COPY(gw_addr, addr); ++ } else { ++ DEBUG_TRACE("Have a gw address " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(gw_addr)); ++ } + + if (ecm_interface_mac_addr_get_no_route(dev, gw_addr, node_addr)) { + DEBUG_TRACE("Found the mac address for gateway\n"); +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-ecm/patches/405-Allow-egress-on-same-port-when-bridge-hairpin-is-enabled.patch b/root/package/firmware/nss/qca-nss-ecm/patches/405-Allow-egress-on-same-port-when-bridge-hairpin-is-enabled.patch new file mode 100644 index 00000000..a236fb75 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-ecm/patches/405-Allow-egress-on-same-port-when-bridge-hairpin-is-enabled.patch @@ -0,0 +1,126 @@ +From e23eabd570eabde1d1fc803127a97fd101642467 Mon Sep 17 00:00:00 2001 +From: Varsha Mishra +Date: Fri, 12 Jun 2020 01:06:58 +0530 +Subject: [qca-nss-ecm] Allow egress on same port when bridge hairpin is + enabled. + +When bridge hairpin is enabled, allow egress on same port. Wi-Fi intrabss +frames are getting exceptioned to stack. Bridge gets to make the decision +whether these frames need to be forwarded or dropped. + +Signed-off-by: Varsha Mishra +Change-Id: Ibdd72264d8887330ba0297ed12cbcfc390065bff +--- + frontends/nss/ecm_nss_ipv4.c | 28 ++++++++++++++++++++++------ + frontends/nss/ecm_nss_ipv6.c | 28 ++++++++++++++++++++++------ + 2 files changed, 44 insertions(+), 12 deletions(-) + +diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c +index 60f799b..51c9ebf 100644 +--- a/frontends/nss/ecm_nss_ipv4.c ++++ b/frontends/nss/ecm_nss_ipv4.c +@@ -1756,7 +1756,9 @@ static unsigned int ecm_nss_ipv4_bridge_post_routing_hook(void *priv, + * Case 2: + * For routed packets the skb will have the src mac matching the bridge mac. + * Case 3: +- * If the packet was not local (case 1) or routed (case 2) then we process. ++ * If the packet was not local (case 1) or routed (case 2) then ++ * we process. There is an exception to case 2: when hairpin mode ++ * is enabled, we process. + */ + + /* +@@ -1768,14 +1770,28 @@ static unsigned int ecm_nss_ipv4_bridge_post_routing_hook(void *priv, + dev_put(bridge); + return NF_ACCEPT; + } ++ ++ /* ++ * This flag needs to be checked in slave port(eth0/ath0) ++ * and not on master interface(br-lan). Hairpin flag can be ++ * enabled/disabled for ports individually. ++ */ + if (in == out) { +- DEBUG_TRACE("skb: %p, bridge: %p (%s), port bounce on %p (%s)\n", skb, bridge, bridge->name, out, out->name); +- dev_put(in); +- dev_put(bridge); +- return NF_ACCEPT; ++ if (!br_is_hairpin_enabled(in)) { ++ DEBUG_TRACE("skb: %p, bridge: %p (%s), ignoring" ++ "the packet, hairpin not enabled" ++ "on port %p (%s)\n", skb, bridge, ++ bridge->name, out, out->name); ++ dev_put(in); ++ dev_put(bridge); ++ return NF_ACCEPT; ++ } ++ DEBUG_TRACE("skb: %p, bridge: %p (%s), hairpin enabled on port" ++ "%p (%s)\n", skb, bridge, bridge->name, out, out->name); + } ++ ++ /* ++ * Case 2: Routed trafffic would be handled by the INET post routing. ++ */ + if (!ecm_mac_addr_equal(skb_eth_hdr->h_source, bridge->dev_addr)) { +- /* +- * Case 2: Routed trafffic would be handled by the INET post routing. +- */ + DEBUG_TRACE("skb: %p, Ignoring routed packet to bridge: %p (%s)\n", skb, bridge, bridge->name); + goto skip_ipv4_bridge_flow; + } +diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c +index 6ad425e..160c94c 100644 +--- a/frontends/nss/ecm_nss_ipv6.c ++++ b/frontends/nss/ecm_nss_ipv6.c +@@ -1498,7 +1498,9 @@ static unsigned int ecm_nss_ipv6_bridge_post_routing_hook(void *priv, + * Case 2: + * For routed packets the skb will have the src mac matching the bridge mac. + * Case 3: +- * If the packet was not local (case 1) or routed (case 2) then we process. ++ * If the packet was not local (case 1) or routed (case 2) then ++ * we process. There is an exception to case 2: when hairpin mode ++ * is enabled, we process. + */ + + /* +@@ -1510,14 +1512,28 @@ static unsigned int ecm_nss_ipv6_bridge_post_routing_hook(void *priv, + dev_put(bridge); + return NF_ACCEPT; + } ++ ++ /* ++ * This flag needs to be checked in slave port(eth0/ath0) ++ * and not on master interface(br-lan). Hairpin flag can be ++ * enabled/disabled for ports individually. ++ */ + if (in == out) { +- DEBUG_TRACE("skb: %p, bridge: %p (%s), port bounce on %p (%s)\n", skb, bridge, bridge->name, out, out->name); +- dev_put(in); +- dev_put(bridge); +- return NF_ACCEPT; ++ if (!br_is_hairpin_enabled(in)) { ++ DEBUG_TRACE("skb: %p, bridge: %p (%s), ignoring" ++ "the packet, hairpin not enabled" ++ "on port %p (%s)\n", skb, bridge, ++ bridge->name, out, out->name); ++ dev_put(in); ++ dev_put(bridge); ++ return NF_ACCEPT; ++ } ++ DEBUG_TRACE("skb: %p, bridge: %p (%s), hairpin enabled on port" ++ "%p (%s)\n", skb, bridge, bridge->name, out, out->name); + } ++ ++ /* ++ * Case 2: Routed trafffic would be handled by the INET post routing. ++ */ + if (!ecm_mac_addr_equal(skb_eth_hdr->h_source, bridge->dev_addr)) { +- /* +- * Case 2: Routed trafffic would be handled by the INET post routing. +- */ + DEBUG_TRACE("skb: %p, Ignoring routed packet to bridge: %p (%s)\n", skb, bridge, bridge->name); + goto skip_ipv6_bridge_flow; + } +-- +cgit v1.1 + diff --git a/root/package/firmware/nss/qca-nss-gmac/Makefile b/root/package/firmware/nss/qca-nss-gmac/Makefile new file mode 100644 index 00000000..6e00c7a1 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-gmac/Makefile @@ -0,0 +1,47 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-nss-gmac +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-gmac +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=9b74deef2816d91e58926e6fab7a6ff931eb3b22 +PKG_MIRROR_HASH:=a1939caa638414323e60f7d29f797ea831c6036e424b8e7bd6cf2d3d874de064 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-nss-gmac + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_ipq806x||TARGET_ipq_ipq806x @LINUX_5_4 + TITLE:=Kernel driver for NSS gmac + FILES:=$(PKG_BUILD_DIR)/ipq806x/qca-nss-gmac.ko + AUTOLOAD:=$(call AutoLoad,31,qca-nss-gmac) +endef + +define KernelPackage/qca-nss-gmac/Description +This package contains a NSS driver for QCA chipset +endef + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-gmac + $(CP) $(PKG_BUILD_DIR)/ipq806x/exports/* $(1)/usr/include/qca-nss-gmac/ +endef + +EXTRA_CFLAGS+= \ + -DCONFIG_NSS_DEBUG_LEVEL=4 \ + -I$(PKG_BUILD_DIR)/nss_hal/include \ + -I$(PKG_BUILD_DIR)/nss_hal/$(BOARD) + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-gmac)) diff --git a/root/package/firmware/nss/qca-nss-gmac/patches/100-kernel-5.4-support.patch b/root/package/firmware/nss/qca-nss-gmac/patches/100-kernel-5.4-support.patch new file mode 100644 index 00000000..f3b91abc --- /dev/null +++ b/root/package/firmware/nss/qca-nss-gmac/patches/100-kernel-5.4-support.patch @@ -0,0 +1,279 @@ +--- a/ipq806x/nss_gmac_ctrl.c ++++ b/ipq806x/nss_gmac_ctrl.c +@@ -322,16 +322,15 @@ void nss_gmac_tx_rx_desc_init(struct nss + * (for example "ifconfig eth0"). + * @param[in] pointer to net_device structure. + * @param[in] pointer to net_device_stats64 structure. +- * @return Returns pointer to net_device_stats64 structure. + */ +-struct rtnl_link_stats64 *nss_gmac_get_stats64(struct net_device *netdev, ++void nss_gmac_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) + { + struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev); + BUG_ON(gmacdev == NULL); + + if (!gmacdev->data_plane_ops) +- return stats; ++ return; + + spin_lock_bh(&gmacdev->stats_lock); + gmacdev->data_plane_ops->get_stats(gmacdev->data_plane_ctx, &gmacdev->nss_stats); +@@ -354,8 +353,6 @@ struct rtnl_link_stats64 *nss_gmac_get_s + stats->tx_fifo_errors = gmacdev->nss_stats.tx_underflow_errors; + stats->tx_window_errors = gmacdev->nss_stats.tx_late_collision_errors; + spin_unlock_bh(&gmacdev->stats_lock); +- +- return stats; + } + + +@@ -439,7 +436,7 @@ static int nss_gmac_mtnp_show(struct dev + static int nss_gmac_tstamp_show(struct device *dev, struct device_attribute *attr, char *buf) + { + struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(to_net_dev(dev)); +- struct timeval tv; ++ struct timespec64 ts64; + uint32_t ret, timeout; + uint32_t ts_hi, ts_lo; + +@@ -459,11 +456,12 @@ static int nss_gmac_tstamp_show(struct d + return -1; + } + +- do_gettimeofday(&tv); ++ ktime_get_real_ts64(&ts64); + + ret = snprintf( + buf, PAGE_SIZE, +- "sec:%u nsec:%u time-of-day: %12d.%06d \n", ts_hi, ts_lo, (int)tv.tv_sec, (int)tv.tv_usec); ++ "sec:%u nsec:%u time-of-day: %12d.%06d \n", \ ++ ts_hi, ts_lo, (int)ts64.tv_sec, (int)(ts64.tv_nsec / NSEC_PER_USEC)); + + return ret; + } +@@ -951,7 +949,7 @@ static const struct net_device_ops nss_g + * @param[in] pointer to advertised features + * @return void + */ +-static void nss_gmac_update_features(uint32_t *supp, uint32_t *adv) ++static void nss_gmac_update_features(long unsigned int *supp, long unsigned int *adv) + { + *supp |= NSS_GMAC_SUPPORTED_FEATURES; + *adv |= NSS_GMAC_ADVERTISED_FEATURES; +@@ -1409,8 +1407,8 @@ static int32_t nss_gmac_probe(struct pla + goto nss_gmac_phy_attach_fail; + } + +- nss_gmac_update_features(&(gmacdev->phydev->supported), +- &(gmacdev->phydev->advertising)); ++ nss_gmac_update_features(gmacdev->phydev->supported, ++ gmacdev->phydev->advertising); + gmacdev->phydev->irq = PHY_POLL; + netdev_dbg(netdev, "PHY %s attach OK\n", phy_id); + +@@ -1440,6 +1438,8 @@ static int32_t nss_gmac_probe(struct pla + netdev_dbg(netdev, "%s MII_PHYSID2 - 0x%04x\n", netdev->name, + nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_PHYSID2)); + } else if (gmacdev->phy_base != NSS_GMAC_NO_MDIO_PHY) { ++ SET_NETDEV_DEV(netdev, gmacdev->miibus->parent); ++ + /* + * Issue a phy_attach for the interface connected to a switch + */ +--- a/ipq806x/nss_gmac_ethtool.c ++++ b/ipq806x/nss_gmac_ethtool.c +@@ -143,9 +143,9 @@ static const struct nss_gmac_ethtool_sta + /** + * @brief Array of strings describing private flag names + */ +-static const char *gmac_strings_priv_flags[] = { +- "linkpoll", +- "tstamp", ++static const char *gmac_strings_priv_flags[][ETH_GSTRING_LEN] = { ++ {"linkpoll"}, ++ {"tstamp"}, + }; + + #define NSS_GMAC_STATS_LEN ARRAY_SIZE(gmac_gstrings_stats) +@@ -292,6 +292,7 @@ static int nss_gmac_set_pauseparam(struc + { + struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev); + struct phy_device *phydev; ++ long unsigned int *advertising; + + BUG_ON(gmacdev == NULL); + BUG_ON(gmacdev->netdev != netdev); +@@ -327,14 +328,15 @@ static int nss_gmac_set_pauseparam(struc + phydev = gmacdev->phydev; + + /* Update flow control advertisment */ +- phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause); ++ advertising = phydev->advertising; ++ *advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause); + + if (gmacdev->pause & FLOW_CTRL_RX) +- phydev->advertising |= ++ *advertising |= + (ADVERTISED_Pause | ADVERTISED_Asym_Pause); + + if (gmacdev->pause & FLOW_CTRL_TX) +- phydev->advertising |= ADVERTISED_Asym_Pause; ++ *advertising |= ADVERTISED_Asym_Pause; + + genphy_config_aneg(gmacdev->phydev); + +@@ -396,12 +398,13 @@ static uint32_t nss_gmac_get_msglevel(st + * @param[in] pointer to struct net_device. + * @param[in] pointer to struct ethtool_cmd. + */ +-static int32_t nss_gmac_get_settings(struct net_device *netdev, +- struct ethtool_cmd *ecmd) ++static int nss_gmac_get_settings(struct net_device *netdev, ++ struct ethtool_link_ksettings *elk) + { + struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev); + struct phy_device *phydev = NULL; + uint16_t phyreg; ++ u32 lp_advertising = 0; + + BUG_ON(gmacdev == NULL); + +@@ -413,10 +416,10 @@ static int32_t nss_gmac_get_settings(str + */ + if (!test_bit(__NSS_GMAC_LINKPOLL, &gmacdev->flags)) { + if (gmacdev->forced_speed != SPEED_UNKNOWN) { +- ethtool_cmd_speed_set(ecmd, gmacdev->forced_speed); +- ecmd->duplex = gmacdev->forced_duplex; +- ecmd->mdio_support = 0; +- ecmd->lp_advertising = 0; ++ elk->base.speed = gmacdev->forced_speed; ++ elk->base.duplex = gmacdev->forced_duplex; ++ elk->base.mdio_support = 0; ++ ethtool_convert_legacy_u32_to_link_mode(elk->link_modes.lp_advertising, 0); + return 0; + } else { + /* Non-link polled interfaced must have a forced +@@ -429,63 +429,59 @@ static int32_t nss_gmac_get_settings(struct net_device *netdev, + + /* update PHY status */ + if (phydev->is_c45 == true) { +- ecmd->mdio_support = ETH_MDIO_SUPPORTS_C45; ++ elk->base.mdio_support = ETH_MDIO_SUPPORTS_C45; + } else { + if (genphy_read_status(phydev) != 0) { + return -EIO; + } +- ecmd->mdio_support = ETH_MDIO_SUPPORTS_C22; ++ elk->base.mdio_support = ETH_MDIO_SUPPORTS_C22; + } + + /* Populate capabilities advertised by self */ +- ecmd->advertising = phydev->advertising; ++ bitmap_copy(elk->link_modes.advertising, phydev->advertising, __ETHTOOL_LINK_MODE_MASK_NBITS); + +- ecmd->autoneg = phydev->autoneg; +- +- if (gmacdev->link_state == LINKDOWN) { +- ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); +- ecmd->duplex = DUPLEX_UNKNOWN; +- } else { +- ethtool_cmd_speed_set(ecmd, phydev->speed); +- ecmd->duplex = phydev->duplex; +- } +- +- ecmd->port = PORT_TP; +- ecmd->phy_address = gmacdev->phy_base; +- ecmd->transceiver = XCVR_EXTERNAL; ++ elk->base.autoneg = phydev->autoneg; ++ elk->base.speed = phydev->speed; ++ elk->base.duplex = phydev->duplex; ++ elk->base.port = PORT_TP; ++ elk->base.phy_address = gmacdev->phy_base; ++ elk->base.transceiver = XCVR_EXTERNAL; + + /* Populate supported capabilities */ +- ecmd->supported = phydev->supported; ++ bitmap_copy(elk->link_modes.supported, phydev->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + + if (phydev->is_c45 == true) + return 0; + + /* Populate capabilities advertised by link partner */ ++ ethtool_convert_link_mode_to_legacy_u32(&lp_advertising, elk->link_modes.lp_advertising); + phyreg = nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_LPA); + if (phyreg & LPA_10HALF) +- ecmd->lp_advertising |= ADVERTISED_10baseT_Half; ++ lp_advertising |= ADVERTISED_10baseT_Half; + + if (phyreg & LPA_10FULL) +- ecmd->lp_advertising |= ADVERTISED_10baseT_Full; ++ lp_advertising |= ADVERTISED_10baseT_Full; + + if (phyreg & LPA_100HALF) +- ecmd->lp_advertising |= ADVERTISED_100baseT_Half; ++ lp_advertising |= ADVERTISED_100baseT_Half; + + if (phyreg & LPA_100FULL) +- ecmd->lp_advertising |= ADVERTISED_100baseT_Full; ++ lp_advertising |= ADVERTISED_100baseT_Full; + + if (phyreg & LPA_PAUSE_CAP) +- ecmd->lp_advertising |= ADVERTISED_Pause; ++ lp_advertising |= ADVERTISED_Pause; + + if (phyreg & LPA_PAUSE_ASYM) +- ecmd->lp_advertising |= ADVERTISED_Asym_Pause; ++ lp_advertising |= ADVERTISED_Asym_Pause; + + phyreg = nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_STAT1000); + if (phyreg & LPA_1000HALF) +- ecmd->lp_advertising |= ADVERTISED_1000baseT_Half; ++ lp_advertising |= ADVERTISED_1000baseT_Half; + + if (phyreg & LPA_1000FULL) +- ecmd->lp_advertising |= ADVERTISED_1000baseT_Full; ++ lp_advertising |= ADVERTISED_1000baseT_Full; ++ ++ ethtool_convert_legacy_u32_to_link_mode(elk->link_modes.lp_advertising, lp_advertising); + + return 0; + } +@@ -489,8 +495,8 @@ static int32_t nss_gmac_get_settings(str + * @param[in] pointer to struct net_device. + * @param[in] pointer to struct ethtool_cmd. + */ +-static int32_t nss_gmac_set_settings(struct net_device *netdev, +- struct ethtool_cmd *ecmd) ++static int nss_gmac_set_settings(struct net_device *netdev, ++ const struct ethtool_link_ksettings *elk) + { + struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev); + struct phy_device *phydev = NULL; +@@ -512,13 +518,13 @@ static int32_t nss_gmac_set_settings(str + return -EPERM; + } + +- if (ecmd->autoneg == AUTONEG_ENABLE) { ++ if (elk->base.autoneg == AUTONEG_ENABLE) { + set_bit(__NSS_GMAC_AUTONEG, &gmacdev->flags); + } else { + clear_bit(__NSS_GMAC_AUTONEG, &gmacdev->flags); + } + +- return phy_ethtool_sset(phydev, ecmd); ++ return phy_ethtool_ksettings_set(phydev, elk); + } + + /** +@@ -580,8 +586,8 @@ struct ethtool_ops nss_gmac_ethtool_ops + .set_pauseparam = &nss_gmac_set_pauseparam, + .nway_reset = &nss_gmac_nway_reset, + .get_wol = &nss_gmac_get_wol, +- .get_settings = &nss_gmac_get_settings, +- .set_settings = &nss_gmac_set_settings, ++ .get_link_ksettings = &nss_gmac_get_settings, ++ .set_link_ksettings = &nss_gmac_set_settings, + .get_strings = &nss_gmac_get_strings, + .get_sset_count = &nss_gmac_get_strset_count, + .get_ethtool_stats = &nss_gmac_get_ethtool_stats, diff --git a/root/package/firmware/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch b/root/package/firmware/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch new file mode 100644 index 00000000..0b1ff063 --- /dev/null +++ b/root/package/firmware/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch @@ -0,0 +1,11 @@ +--- a/ipq806x/nss_gmac_ctrl.c ++++ b/ipq806x/nss_gmac_ctrl.c +@@ -992,7 +992,7 @@ static int32_t nss_gmac_of_get_pdata(str + return -EFAULT; + } + maddr = (uint8_t *)of_get_mac_address(np); +- if (maddr) ++ if (!IS_ERR_OR_NULL(maddr)) + memcpy(gmaccfg->mac_addr, maddr, ETH_ALEN); + + if (of_address_to_resource(np, 0, &memres_devtree) != 0) diff --git a/root/package/firmware/nss/qca-nss-gmac/patches/200-work-around-interface-close-warning.patch b/root/package/firmware/nss/qca-nss-gmac/patches/200-work-around-interface-close-warning.patch new file mode 100644 index 00000000..7cb6d6fa --- /dev/null +++ b/root/package/firmware/nss/qca-nss-gmac/patches/200-work-around-interface-close-warning.patch @@ -0,0 +1,15 @@ +--- a/ipq806x/nss_gmac_tx_rx_offload.c ++++ b/ipq806x/nss_gmac_tx_rx_offload.c +@@ -1027,8 +1027,10 @@ int nss_gmac_close(struct net_device *ne + nss_gmac_disable_interrupt_all(gmacdev); + gmacdev->data_plane_ops->link_state(gmacdev->data_plane_ctx, 0); + +- if (!IS_ERR(gmacdev->phydev)) +- phy_stop(gmacdev->phydev); ++ if (!IS_ERR(gmacdev->phydev)) { ++ if (test_bit(__NSS_GMAC_LINKPOLL, &gmacdev->flags)) ++ phy_stop(gmacdev->phydev); ++ } + + clear_bit(__NSS_GMAC_UP, &gmacdev->flags); + clear_bit(__NSS_GMAC_CLOSING, &gmacdev->flags); diff --git a/root/package/firmware/nss/qca-rfs/Makefile b/root/package/firmware/nss/qca-rfs/Makefile new file mode 100644 index 00000000..7831e4d3 --- /dev/null +++ b/root/package/firmware/nss/qca-rfs/Makefile @@ -0,0 +1,51 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-rfs +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/qca-rfs +PKG_SOURCE_DATE:=2021-03-17 +PKG_SOURCE_VERSION:=75197c386f477c7b3a6f02489d9903a9409fd5cc +PKG_MIRROR_HASH:=90f1c3ec2e984cf8efa79c85d715ebd8a21e347ab57adbd9695de23e64eea1ec + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-rfs + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Support + DEPENDS:=@TARGET_ipq40xx +kmod-ipt-conntrack + TITLE:=Kernel module for QCA Receiving Flow Steering + FILES:=$(PKG_BUILD_DIR)/qrfs.ko + KCONFIG:=\ + CONFIG_NF_CONNTRACK_EVENTS=y \ + CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y + AUTOLOAD:=$(call AutoLoad,29,qrfs) +endef + +define KernelPackage/qca-rfs/Description +QCA-RFS is a kernel module for ESS Receive Flow Steering. +endef + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + modules +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-rfs + $(CP) -rf $(PKG_BUILD_DIR)/rfs_dev.h $(1)/usr/include/qca-rfs +endef + +define KernelPackage/qca-rfs/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qrfs.init $(1)/etc/init.d/qrfs +endef + +$(eval $(call KernelPackage,qca-rfs)) diff --git a/root/package/firmware/nss/qca-rfs/files/qrfs.init b/root/package/firmware/nss/qca-rfs/files/qrfs.init new file mode 100755 index 00000000..f3f8a38c --- /dev/null +++ b/root/package/firmware/nss/qca-rfs/files/qrfs.init @@ -0,0 +1,27 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2015 The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +START=70 + +start() { + echo "1" > /proc/qrfs/enable + ip neigh flush all +} + +stop() { + echo "0" > /proc/qrfs/enable +} diff --git a/root/package/firmware/nss/qca-rfs/patches/100-add-kernel-5.4-support.patch b/root/package/firmware/nss/qca-rfs/patches/100-add-kernel-5.4-support.patch new file mode 100644 index 00000000..b7b2db55 --- /dev/null +++ b/root/package/firmware/nss/qca-rfs/patches/100-add-kernel-5.4-support.patch @@ -0,0 +1,57 @@ +--- a/rfs_cm.c ++++ b/rfs_cm.c +@@ -462,14 +462,6 @@ static int rfs_cm_conntrack_event(unsign + } + + /* +- * If this is an untracked connection then we can't have any state either. +- */ +- if (unlikely(ct == &nf_conntrack_untracked)) { +- RFS_TRACE("ignoring untracked conn\n"); +- return NOTIFY_DONE; +- } +- +- /* + * Ignore anything other than IPv4 connections. + */ + if (unlikely(nf_ct_l3num(ct) != AF_INET)) { +--- a/rfs_rule.c ++++ b/rfs_rule.c +@@ -702,7 +702,7 @@ int rfs_rule_init(void) + + RFS_DEBUG("RFS Rule init\n"); + spin_lock_init(&rr->hash_lock); +- memset(&rr->hash, 0, RFS_RULE_HASH_SIZE); ++ memset(&rr->hash, 0, sizeof(rr->hash)); + + rr->proc_rule = proc_create("rule", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, + rfs_proc_entry, &rule_proc_fops); +@@ -717,7 +717,7 @@ void rfs_rule_exit(void) + struct rfs_rule *rr = &__rr; + + RFS_DEBUG("RFS Rule exit\n"); +- if (rr->proc_rule); ++ if (rr->proc_rule) + remove_proc_entry("rule", rfs_proc_entry); + rfs_rule_destroy_all(); + } +--- a/rfs_wxt.c ++++ b/rfs_wxt.c +@@ -422,7 +422,7 @@ static int rfs_wxt_rx(struct socket *soc + #else + iov_iter_init(&msg.msg_iter, READ, &iov, 1, len); + #endif +- size = sock_recvmsg(sock, &msg, len, msg.msg_flags); ++ size = sock_recvmsg(sock, &msg, msg.msg_flags); + set_fs(oldfs); + + return size; +@@ -510,7 +510,7 @@ int rfs_wxt_stop(void) + } + + RFS_DEBUG("kill rfs_wxt thread"); +- force_sig(SIGKILL, __rwn.thread); ++ send_sig(SIGKILL, __rwn.thread, 1); + if (__rwn.thread) + err = kthread_stop(__rwn.thread); + __rwn.thread = NULL; diff --git a/root/package/firmware/nss/qca-rfs/patches/200-rework-nfct-notification.patch b/root/package/firmware/nss/qca-rfs/patches/200-rework-nfct-notification.patch new file mode 100644 index 00000000..81e608c0 --- /dev/null +++ b/root/package/firmware/nss/qca-rfs/patches/200-rework-nfct-notification.patch @@ -0,0 +1,20 @@ +--- a/rfs_cm.c ++++ b/rfs_cm.c +@@ -709,7 +709,7 @@ int rfs_cm_start(void) + + RFS_DEBUG("RFS cm start\n"); + #ifdef CONFIG_NF_CONNTRACK_EVENTS +- ret = nf_conntrack_register_notifier(&init_net, &rfs_cm_conntrack_notifier); ++ ret = nf_conntrack_register_chain_notifier(&init_net, &rfs_cm_conntrack_notifier); + if (ret < 0) { + RFS_ERROR("can't register nf notifier hook: %d\n", ret); + return -1; +@@ -740,7 +740,7 @@ int rfs_cm_stop(void) + #endif + + #ifdef CONFIG_NF_CONNTRACK_EVENTS +- nf_conntrack_unregister_notifier(&init_net, &rfs_cm_conntrack_notifier); ++ nf_conntrack_unregister_chain_notifier(&init_net, &rfs_cm_conntrack_notifier); + #endif + + rfs_cm_connection_destroy_all(); diff --git a/root/package/firmware/nss/qca-ssdk-shell/Makefile b/root/package/firmware/nss/qca-ssdk-shell/Makefile new file mode 100644 index 00000000..90e2c2e6 --- /dev/null +++ b/root/package/firmware/nss/qca-ssdk-shell/Makefile @@ -0,0 +1,48 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-ssdk-shell +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/ssdk-shell +PKG_SOURCE_DATE:=2021-01-27 +PKG_SOURCE_VERSION:=5661366d471a78314bc7010f985ad8cc15be832a +PKG_MIRROR_HASH:=73111e09e896f0abbe3ee1c358aea7ec14fe5e668ce8753b8968e03c78f9599b + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define Package/qca-ssdk-shell + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Shell application for QCA SSDK + DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_ipq807x) +endef + +define Package/qca-ssdk-shell/Description + This package contains a qca-ssdk shell application for QCA chipset +endef + +ifndef CONFIG_TOOLCHAIN_BIN_PATH +CONFIG_TOOLCHAIN_BIN_PATH=$(TOOLCHAIN_DIR)/bin +endif + +QCASSDK_CONFIG_OPTS+= \ + TOOL_PATH=$(CONFIG_TOOLCHAIN_BIN_PATH) \ + SYS_PATH=$(LINUX_DIR) \ + TOOLPREFIX=$(TARGET_CROSS) \ + KVER=$(LINUX_VERSION) \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + ARCH=$(LINUX_KARCH) + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) $(strip $(QCASSDK_CONFIG_OPTS)) +endef + +define Package/qca-ssdk-shell/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/build/bin/ssdk_sh $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,qca-ssdk-shell)) diff --git a/root/package/firmware/nss/qca-ssdk/Makefile b/root/package/firmware/nss/qca-ssdk/Makefile new file mode 100644 index 00000000..3bb9d8ba --- /dev/null +++ b/root/package/firmware/nss/qca-ssdk/Makefile @@ -0,0 +1,125 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-ssdk +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://source.codeaurora.org/quic/qsdk/oss/lklm/qca-ssdk +PKG_SOURCE_DATE:=2021-04-28 +PKG_SOURCE_VERSION:=c9bc3bc34eaaac78083573524097356e2dcc1b66 +PKG_MIRROR_HASH:=29db78529be32427b8b96fcbfec22a016a243676781ec96d9d65b810944fa405 + +LOCAL_VARIANT=$(patsubst qca-ssdk-%,%,$(patsubst qca-ssdk-%,%,$(BUILD_VARIANT))) + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-ssdk/default-nohnat + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for QCA SSDK + FILES:=$(PKG_BUILD_DIR)/build/bin/qca-ssdk.ko + AUTOLOAD:=$(call AutoLoad,30,qca-ssdk) + PROVIDES:=qca-ssdk +endef + +define KernelPackage/qca-ssdk-nohnat +$(call KernelPackage/qca-ssdk/default-nohnat) + DEPENDS:=@(TARGET_ipq806x||TARGET_ipq807x) + VARIANT:=nohnat +endef + +define KernelPackage/qca-ssdk-nohnat/Description +This package contains a qca-ssdk driver for QCA chipset +endef + +define KernelPackage/qca-ssdk-hnat +$(call KernelPackage/qca-ssdk/default-nohnat) + DEPENDS:=@TARGET_ipq40xx +kmod-ipt-extra +kmod-ipt-filter \ + +kmod-ppp +TARGET_ipq40xx:kmod-qca-rfs + TITLE+= (hnat) + VARIANT:=hnat +endef + +define KernelPackage/qca-ssdk-hnat/Description +This package contains a qca-ssdk-hnat driver for QCA chipset +endef + +ifdef CONFIG_TOOLCHAIN_BIN_PATH +TOOLCHAIN_BIN_PATH=$(CONFIG_TOOLCHAIN_BIN_PATH) +else +TOOLCHAIN_BIN_PATH=$(TOOLCHAIN_DIR)/bin +endif + +QCASSDK_CONFIG_OPTS+= \ + $(KERNEL_MAKE_FLAGS) \ + KVER=$(LINUX_VERSION) \ + SYS_PATH=$(LINUX_DIR) \ + GCC_VERSION=$(GCC_VERSION) \ + TOOLPREFIX=$(TARGET_CROSS) \ + TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \ + TARGET_SUFFIX=$(CONFIG_TARGET_SUFFIX) \ + EXTRA_CFLAGS=-I$(STAGING_DIR)/usr/include + +ifeq ($(LOCAL_VARIANT),hnat) + QCASSDK_CONFIG_OPTS+= HNAT_FEATURE=enable +ifeq ($(BOARD),ipq40xx) + QCASSDK_CONFIG_OPTS+= RFS_FEATURE=enable +endif +endif + +ifeq ($(BOARD),ipq60xx) + QCASSDK_CONFIG_OPTS+= CHIP_TYPE=CPPE +else ifeq ($(BOARD),ipq807x) + QCASSDK_CONFIG_OPTS+= CHIP_TYPE=HPPE +else + QCASSDK_CONFIG_OPTS+= HK_CHIP=enable +endif + +ifneq (, $(findstring $(BOARD), ipq60xx ipq807x)) + QCASSDK_CONFIG_OPTS+= PTP_FEATURE=disable SWCONFIG_FEATURE=disable +endif + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) $(strip $(QCASSDK_CONFIG_OPTS)) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/api + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/ref + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/fal + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/sal + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/init + $(CP) -rf $(PKG_BUILD_DIR)/include/api/sw_ioctl.h $(1)/usr/include/qca-ssdk/api + if [ -f $(PKG_BUILD_DIR)/include/ref/ref_vsi.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_vsi.h $(1)/usr/include/qca-ssdk/ref/; \ + fi + if [ -f $(PKG_BUILD_DIR)/include/ref/ref_fdb.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_fdb.h $(1)/usr/include/qca-ssdk/ref/; \ + fi + if [ -f $(PKG_BUILD_DIR)/include/ref/ref_port_ctrl.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_port_ctrl.h $(1)/usr/include/qca-ssdk/ref/; \ + fi + if [ -f $(PKG_BUILD_DIR)/include/init/ssdk_init.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/init/ssdk_init.h $(1)/usr/include/qca-ssdk/init/; \ + fi + $(CP) -rf $(PKG_BUILD_DIR)/include/fal $(1)/usr/include/qca-ssdk + $(CP) -rf $(PKG_BUILD_DIR)/include/common/*.h $(1)/usr/include/qca-ssdk + $(CP) -rf $(PKG_BUILD_DIR)/include/sal/os/linux/*.h $(1)/usr/include/qca-ssdk + $(CP) -rf $(PKG_BUILD_DIR)/include/sal/os/*.h $(1)/usr/include/qca-ssdk +endef + +define KernelPackage/qca-ssdk-nohnat/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-ssdk $(1)/etc/init.d/qca-ssdk +endef + +define KernelPackage/qca-ssdk-hnat/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-ssdk $(1)/etc/init.d/qca-ssdk +endef + +$(eval $(call KernelPackage,qca-ssdk-nohnat)) +$(eval $(call KernelPackage,qca-ssdk-hnat)) diff --git a/root/package/firmware/nss/qca-ssdk/files/qca-ssdk b/root/package/firmware/nss/qca-ssdk/files/qca-ssdk new file mode 100755 index 00000000..389279c0 --- /dev/null +++ b/root/package/firmware/nss/qca-ssdk/files/qca-ssdk @@ -0,0 +1,206 @@ +#!/bin/sh /etc/rc.common +# Copyright (c) 2018, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +START=16 + +#!/bin/sh +ruletype="ip4 ip6" +side="wan lan" +qwan="1 3 2 0 5 7 6 4" +qlan="0 1 2 3 4 5 6 7" + +function create_war_acl_rules(){ + for lw in $side + do + #echo $lw + if [ "$lw" == "wan" ];then + listid=254 + queue=$qwan + portmap=0x20 + else + listid=255 + queue=$qlan + portmap=0x1e + fi + #echo $queue + #echo "creating list $listid" + ssdk_sh acl list create $listid 255 + ruleid=0 + for rt in $ruletype + do + for qid in $queue + do + cmd="ssdk_sh acl rule add $listid $ruleid 1 n 0 0" + #echo $cmd + if [ "$rt" == "ip4" ];then + cmd="$cmd ip4 n n n n n n n n n n n n n n n n n n n n n n n n n n n n n" + #echo $cmd + else + cmd="$cmd ip6 n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n" + #echo $cmd + fi + if [ $ruleid -le 3 ];then + #non-zero dscp + cmd="$cmd y 0x0 0xff" + elif [ $ruleid -le 7 ];then + #zero dscp + cmd="$cmd n" + elif [ $ruleid -le 11 ];then + #non-zero dscp + cmd="$cmd y 0x0 0xff" + else + #zero dscp + cmd="$cmd n" + fi + p=$((ruleid/2)) + cmd="$cmd y mask $((ruleid%2)) 0x1 y mask $((p%2)) 0x1 n n n n n n n n n n n n n n n y n n n n n n n y $qid n n 0 0 n n n n n n n n n n n n n n n n n n n n 0" + #echo $cmd + $cmd + ruleid=`expr $ruleid + 1` + done + done + ssdk_sh acl list bind $listid 0 1 $portmap + done +} + +function create_war_cosmap(){ + ssdk_sh cosmap pri2q set 0 0 + ssdk_sh cosmap pri2q set 1 0 + ssdk_sh cosmap pri2q set 2 0 + ssdk_sh cosmap pri2q set 3 0 + ssdk_sh cosmap pri2q set 4 1 + ssdk_sh cosmap pri2q set 5 1 + ssdk_sh cosmap pri2q set 6 1 + ssdk_sh cosmap pri2q set 7 1 + ssdk_sh cosmap pri2ehq set 0 0 + ssdk_sh cosmap pri2ehq set 1 0 + ssdk_sh cosmap pri2ehq set 2 0 + ssdk_sh cosmap pri2ehq set 3 0 + ssdk_sh cosmap pri2ehq set 4 1 + ssdk_sh cosmap pri2ehq set 5 1 + ssdk_sh cosmap pri2ehq set 6 1 + ssdk_sh cosmap pri2ehq set 7 1 +} + +function create_acl_byp_egstp_rules(){ + ssdk_sh debug module_func set servcode 0xf 0x0 0x0 + ssdk_sh servcode config set 1 n 0 0xfffefc7f 0xffbdff 0 0 0 0 0 0 + ssdk_sh debug module_func set servcode 0x0 0x0 0x0 + ssdk_sh acl list create 56 48 + ssdk_sh acl rule add 56 0 1 n 0 0 mac n n n n n y 01-80-c2-00-00-00 ff-ff-ff-ff-ff-ff n n n n n n n n n n n n n n n n n n n n n n n y n n n n n n n n n n 0 0 n n n n n n n n n n n n n y n n n n n n n n n n n n y n n n n n n n n n n n n 0 + ssdk_sh acl rule add 56 1 1 n 0 0 mac n n n n n n n yes 0x8809 0xffff n n n n n n n n n n n n n n n n n n n n n y n n n n n n n n n n 0 0 n n n n n n n n n n n n n y n n n n n n n n n n n n y n n n n n n n n n n n n 0 + ssdk_sh acl rule add 56 2 1 n 0 0 mac n n n n n n n yes 0x888e 0xffff n n n n n n n n n n n n n n n n n n n n n y n n n n n n n n n n 0 0 n n n n n n n n n n n n n y n n n n n n n n n n n n y n n n n n n n n n n n n 0 + ssdk_sh acl list bind 56 0 2 1 +} + +function delete_war_acl_rules(){ + for lw in $side + do + #echo $lw + if [ "$lw" == "wan" ];then + listid=254 + queue=$qwan + portmap=0x20 + else + listid=255 + queue=$qlan + portmap=0x1e + fi + ssdk_sh acl list unbind $listid 0 1 $portmap + for rt in $ruletype + do + for qid in $queue + do + cmd="ssdk_sh acl rule del $listid 0 1" + echo $cmd + $cmd + done + done + #echo "deleting list $listid" + ssdk_sh acl list destroy $listid + done +} + +function delete_war_cosmap(){ + ssdk_sh cosmap pri2q set 0 0 + ssdk_sh cosmap pri2q set 1 0 + ssdk_sh cosmap pri2q set 2 1 + ssdk_sh cosmap pri2q set 3 1 + ssdk_sh cosmap pri2q set 4 2 + ssdk_sh cosmap pri2q set 5 2 + ssdk_sh cosmap pri2q set 6 3 + ssdk_sh cosmap pri2q set 7 3 + ssdk_sh cosmap pri2ehq set 0 1 + ssdk_sh cosmap pri2ehq set 1 0 + ssdk_sh cosmap pri2ehq set 2 2 + ssdk_sh cosmap pri2ehq set 3 2 + ssdk_sh cosmap pri2ehq set 4 3 + ssdk_sh cosmap pri2ehq set 5 3 + ssdk_sh cosmap pri2ehq set 6 4 + ssdk_sh cosmap pri2ehq set 7 5 +} + +function delete_acl_byp_egstp_rules(){ + ssdk_sh debug module_func set servcode 0xf 0x0 0x0 + ssdk_sh servcode config set 1 n 0 0xfffefcff 0xffbfff 0 0 0 0 0 0 + ssdk_sh debug module_func set servcode 0x0 0x0 0x0 + ssdk_sh acl list unbind 56 0 2 1 + ssdk_sh acl rule del 56 0 1 + ssdk_sh acl rule del 56 1 1 + ssdk_sh acl rule del 56 2 1 + ssdk_sh acl list destroy 56 +} + +function edma_war_config_add(){ + create_war_cosmap + ssdk_sh acl status set enable + create_war_acl_rules +} + +function edma_war_config_del(){ + delete_war_acl_rules + delete_war_cosmap +} + +start() { + chip_ver=`ssdk_sh debug reg get 0 4 | grep Data | tr -d 'SSDK Init OK![Data]:'` + #The following commands should be uncommented to enable EDMA WAR + if [ "$chip_ver" = "0x1401" ]; then + #edma_war_config_add + echo '' + fi + #The following commands should be uncommented to add acl egress stp bypass rules + if [ "$chip_ver" = "0x1500" ] || [ "$chip_ver" = "0x1501" ]; then + #create_acl_byp_egstp_rules + echo '' + fi + echo starting +} + +stop() { + chip_ver=`ssdk_sh debug reg get 0 4 | grep Data | tr -d 'SSDK Init OK![Data]:'` + #The following commands should be uncommented to disable EDMA WAR + if [ "$chip_ver" = "0x1401" ]; then + #edma_war_config_del + echo '' + fi + #The following commands should be uncommented to delete acl egress stp bypass rules + if [ "$chip_ver" = "0x1500" ] || [ "$chip_ver" = "0x1501" ]; then + #delete_acl_byp_egstp_rules + echo '' + fi + echo stoping +} diff --git a/root/package/firmware/nss/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10.patch b/root/package/firmware/nss/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10.patch new file mode 100644 index 00000000..1ee44fa9 --- /dev/null +++ b/root/package/firmware/nss/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10.patch @@ -0,0 +1,56 @@ +From 472c0c8132784608312c80c4b02c03ea7c132235 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 12 May 2021 13:41:12 +0200 +Subject: [PATCH] SSDK: config: add kernel 5.10 + +This is purely to identify it and be able to set +flags correctly. + +Signed-off-by: Robert Marko +--- + config | 6 +++++- + make/linux_opt.mk | 4 ++-- + 2 files changed, 7 insertions(+), 3 deletions(-) + +--- a/config ++++ b/config +@@ -22,6 +22,10 @@ ifeq ($(KVER),$(filter 5.4%,$(KVER))) + OS_VER=5_4 + endif + ++ifeq ($(KVER),$(filter 5.10%,$(KVER))) ++OS_VER=5_10 ++endif ++ + ifeq ($(KVER), 3.4.0) + OS_VER=3_4 + endif +@@ -123,7 +127,7 @@ endif + endif + + ifeq ($(ARCH), arm64) +-ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4%,$(KVER))) ++ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.10%,$(KVER))) + CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -Werror -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large + endif + endif +--- a/make/linux_opt.mk ++++ b/make/linux_opt.mk +@@ -388,7 +388,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) + KASAN_SHADOW_SCALE_SHIFT := 3 + endif + +- ifeq (5_4, $(OS_VER)) ++ ifeq ($(OS_VER),$(filter 5_4 5_10, $(OS_VER))) + ifeq ($(ARCH), arm64) + KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) + endif +@@ -419,7 +419,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) + + endif + +- ifeq ($(OS_VER),$(filter 4_4 5_4, $(OS_VER))) ++ ifeq ($(OS_VER),$(filter 4_4 5_4 5_10, $(OS_VER))) + MODULE_CFLAG += -DKVER34 + MODULE_CFLAG += -DKVER32 + MODULE_CFLAG += -DLNX26_22 diff --git a/root/package/firmware/nss/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch b/root/package/firmware/nss/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch new file mode 100644 index 00000000..b293ad29 --- /dev/null +++ b/root/package/firmware/nss/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch @@ -0,0 +1,102 @@ +From 784f2cfdfaf3bdf44917924e157049230a0ef5f8 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 12 May 2021 13:45:45 +0200 +Subject: [PATCH] SSDK: replace ioremap_nocache with ioremap + +ioremap_nocache was dropped upstream, simply use the +generic variety. + +Signed-off-by: Robert Marko +--- + src/init/ssdk_clk.c | 10 +++++----- + src/init/ssdk_init.c | 2 +- + src/init/ssdk_plat.c | 6 +++--- + 3 files changed, 9 insertions(+), 9 deletions(-) + +--- a/src/init/ssdk_clk.c ++++ b/src/init/ssdk_clk.c +@@ -623,7 +623,7 @@ ssdk_mp_tcsr_get(a_uint32_t tcsr_offset, + { + void __iomem *tcsr_base = NULL; + +- tcsr_base = ioremap_nocache(TCSR_ETH_ADDR, TCSR_ETH_SIZE); ++ tcsr_base = ioremap(TCSR_ETH_ADDR, TCSR_ETH_SIZE); + if (!tcsr_base) + { + SSDK_ERROR("Failed to map tcsr eth address!\n"); +@@ -640,7 +640,7 @@ ssdk_mp_tcsr_set(a_uint32_t tcsr_offset, + { + void __iomem *tcsr_base = NULL; + +- tcsr_base = ioremap_nocache(TCSR_ETH_ADDR, TCSR_ETH_SIZE); ++ tcsr_base = ioremap(TCSR_ETH_ADDR, TCSR_ETH_SIZE); + if (!tcsr_base) + { + SSDK_ERROR("Failed to map tcsr eth address!\n"); +@@ -688,7 +688,7 @@ ssdk_mp_cmnblk_stable_check(void) + a_uint32_t reg_val; + int i, loops = 20; + +- pll_lock = ioremap_nocache(CMN_PLL_LOCKED_ADDR, CMN_PLL_LOCKED_SIZE); ++ pll_lock = ioremap(CMN_PLL_LOCKED_ADDR, CMN_PLL_LOCKED_SIZE); + if (!pll_lock) { + SSDK_ERROR("Failed to map CMN PLL LOCK register!\n"); + return A_FALSE; +@@ -745,7 +745,7 @@ static void ssdk_cmnblk_pll_src_set(enum + void __iomem *cmn_pll_src_base = NULL; + a_uint32_t reg_val; + +- cmn_pll_src_base = ioremap_nocache(CMN_BLK_PLL_SRC_ADDR, CMN_BLK_SIZE); ++ cmn_pll_src_base = ioremap(CMN_BLK_PLL_SRC_ADDR, CMN_BLK_SIZE); + if (!cmn_pll_src_base) { + SSDK_ERROR("Failed to map cmn pll source address!\n"); + return; +@@ -766,7 +766,7 @@ static void ssdk_cmnblk_init(enum cmnblk + void __iomem *gcc_pll_base = NULL; + a_uint32_t reg_val; + +- gcc_pll_base = ioremap_nocache(CMN_BLK_ADDR, CMN_BLK_SIZE); ++ gcc_pll_base = ioremap(CMN_BLK_ADDR, CMN_BLK_SIZE); + if (!gcc_pll_base) { + SSDK_ERROR("Failed to map gcc pll address!\n"); + return; +--- a/src/init/ssdk_init.c ++++ b/src/init/ssdk_init.c +@@ -2770,7 +2770,7 @@ static int ssdk_dess_mac_mode_init(a_uin + (a_uint8_t *)®_value, 4); + mdelay(10); + /*softreset psgmii, fixme*/ +- gcc_addr = ioremap_nocache(0x1812000, 0x200); ++ gcc_addr = ioremap(0x1812000, 0x200); + if (!gcc_addr) { + SSDK_ERROR("gcc map fail!\n"); + return 0; +--- a/src/init/ssdk_plat.c ++++ b/src/init/ssdk_plat.c +@@ -1312,7 +1312,7 @@ ssdk_plat_init(ssdk_init_cfg *cfg, a_uin + reg_mode = ssdk_uniphy_reg_access_mode_get(dev_id); + if(reg_mode == HSL_REG_LOCAL_BUS) { + ssdk_uniphy_reg_map_info_get(dev_id, &map); +- qca_phy_priv_global[dev_id]->uniphy_hw_addr = ioremap_nocache(map.base_addr, ++ qca_phy_priv_global[dev_id]->uniphy_hw_addr = ioremap(map.base_addr, + map.size); + if (!qca_phy_priv_global[dev_id]->uniphy_hw_addr) { + SSDK_ERROR("%s ioremap fail.", __func__); +@@ -1327,7 +1327,7 @@ ssdk_plat_init(ssdk_init_cfg *cfg, a_uin + reg_mode = ssdk_switch_reg_access_mode_get(dev_id); + if(reg_mode == HSL_REG_LOCAL_BUS) { + ssdk_switch_reg_map_info_get(dev_id, &map); +- qca_phy_priv_global[dev_id]->hw_addr = ioremap_nocache(map.base_addr, ++ qca_phy_priv_global[dev_id]->hw_addr = ioremap(map.base_addr, + map.size); + if (!qca_phy_priv_global[dev_id]->hw_addr) { + SSDK_ERROR("%s ioremap fail.", __func__); +@@ -1358,7 +1358,7 @@ ssdk_plat_init(ssdk_init_cfg *cfg, a_uin + return -1; + } + +- qca_phy_priv_global[dev_id]->psgmii_hw_addr = ioremap_nocache(map.base_addr, ++ qca_phy_priv_global[dev_id]->psgmii_hw_addr = ioremap(map.base_addr, + map.size); + if (!qca_phy_priv_global[dev_id]->psgmii_hw_addr) { + SSDK_ERROR("%s ioremap fail.", __func__); diff --git a/root/package/firmware/nss/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch b/root/package/firmware/nss/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch new file mode 100644 index 00000000..3bcbcccf --- /dev/null +++ b/root/package/firmware/nss/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch @@ -0,0 +1,40 @@ +From b6190ca46287d01a895c7cc14de30410c09ff1b8 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 12 May 2021 17:15:46 +0200 +Subject: [PATCH] SSDK: platform: use of_mdio_find_bus() to get MDIO bus + +Kernel has a generic of_mdio_find_bus() which can get the appropriate +MDIO bus based on the DT node. +So, drop the getting MDIO from platform data, which no longer works +in 5.4 and later and use of_mdio_find_bus(). + +Signed-off-by: Baruch Siach +Signed-off-by: Robert Marko +--- + src/init/ssdk_plat.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/src/init/ssdk_plat.c ++++ b/src/init/ssdk_plat.c +@@ -551,7 +551,6 @@ static int miibus_get(a_uint32_t dev_id) + struct device_node *mdio_node = NULL; + struct device_node *switch_node = NULL; + struct platform_device *mdio_plat = NULL; +- struct ipq40xx_mdio_data *mdio_data = NULL; + struct qca_phy_priv *priv; + hsl_reg_mode reg_mode = HSL_REG_LOCAL_BUS; + priv = qca_phy_priv_global[dev_id]; +@@ -584,12 +583,7 @@ static int miibus_get(a_uint32_t dev_id) + + if(reg_mode == HSL_REG_LOCAL_BUS) + { +- mdio_data = dev_get_drvdata(&mdio_plat->dev); +- if (!mdio_data) { +- SSDK_ERROR("cannot get mdio_data reference from device data\n"); +- return 1; +- } +- priv->miibus = mdio_data->mii_bus; ++ priv->miibus = of_mdio_find_bus(mdio_node); + } + else + priv->miibus = dev_get_drvdata(&mdio_plat->dev); diff --git a/root/package/firmware/nss/qca-ssdk/patches/0005-add-kernel-5.4-support.patch b/root/package/firmware/nss/qca-ssdk/patches/0005-add-kernel-5.4-support.patch new file mode 100644 index 00000000..6b08b05a --- /dev/null +++ b/root/package/firmware/nss/qca-ssdk/patches/0005-add-kernel-5.4-support.patch @@ -0,0 +1,108 @@ +--- a/app/nathelper/linux/lib/nat_helper_dt.c ++++ b/app/nathelper/linux/lib/nat_helper_dt.c +@@ -721,7 +721,7 @@ napt_ct_counter_sync(a_uint32_t hw_index) + } + + if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) { +- ct->timeout.expires += delta_jiffies; ++ ct->timeout += delta_jiffies; + } + + if((cct != NULL) && (napt_hw_get_by_index(&napt, hw_index) == 0)) +@@ -770,7 +770,7 @@ napt_ct_timer_update(a_uint32_t hw_index) + } + + if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) { +- ct->timeout.expires += delta_jiffies; ++ ct->timeout += delta_jiffies; + } + + return 0; +--- a/app/nathelper/linux/napt_helper.c ++++ b/app/nathelper/linux/napt_helper.c +@@ -64,11 +64,6 @@ napt_ct_aging_disable(uint32_t ct_addr) + } + + ct = (struct nf_conn *)ct_addr; +- +- if (timer_pending(&ct->timeout)) +- { +- del_timer(&ct->timeout); +- } + } + + int +@@ -85,7 +80,7 @@ napt_ct_aging_is_enable(uint32_t ct_addr) + + ct = (struct nf_conn *)ct_addr; + +- return timer_pending(&(((struct nf_conn *)ct)->timeout)); ++ return (nf_ct_is_expired(ct)); + } + + void +@@ -111,18 +106,17 @@ napt_ct_aging_enable(uint32_t ct_addr) + l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; + protonum = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; + +- ct->timeout.expires = jiffies+10*HZ; ++ ct->timeout = jiffies+10*HZ; + + if ((l3num == AF_INET) && (protonum == IPPROTO_TCP)) + { + if (ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED) + { +- ct->timeout.expires = jiffies+(5*24*60*60*HZ); ++ ct->timeout = jiffies+(5*24*60*60*HZ); + } + } + + HNAT_PRINTK(" ct:[%x] add timeout again\n", ct_addr); +- add_timer(&ct->timeout); + } + + void +@@ -339,7 +333,6 @@ napt_ct_list_unlock(void) + uint32_t + napt_ct_list_iterate(uint32_t *hash, uint32_t *iterate) + { +- struct net *net = &init_net; + struct nf_conntrack_tuple_hash *h = NULL; + struct nf_conn *ct = NULL; + struct hlist_nulls_node *pos = (struct hlist_nulls_node *) (*iterate); +@@ -349,7 +342,7 @@ napt_ct_list_iterate(uint32_t *hash, uint32_t *iterate) + if(pos == 0) + { + /*get head for list*/ +- pos = rcu_dereference((&net->ct.hash[*hash])->first); ++ pos = rcu_dereference(hlist_nulls_first_rcu(&nf_conntrack_hash[*hash])); + } + + hlist_nulls_for_each_entry_from(h, pos, hnnode) +--- a/app/nathelper/linux/nat_ipt_helper.c ++++ b/app/nathelper/linux/nat_ipt_helper.c +@@ -534,10 +534,10 @@ nat_ipt_data_init(void) + memset(&old_replace, 0, sizeof (old_replace)); + + /*record ipt rule(SNAT) sequence for hw nat*/ +- memset(hw_nat_ipt_seq, 0, NAT_HW_NUM); ++ memset(hw_nat_ipt_seq, 0, sizeof(hw_nat_ipt_seq)); + + /*record ipt rule(SNAT) pubip index for hw nat*/ +- memset(hw_nat_pip_idx, 0, NAT_HW_NUM); ++ memset(hw_nat_pip_idx, 0, sizeof(hw_nat_pip_idx)); + } + + static void +--- a/make/linux_opt.mk ++++ b/make/linux_opt.mk +@@ -449,9 +449,6 @@ ifeq (KSLIB, $(MODULE_TYPE)) + else ifeq ($(ARCH), arm) + MODULE_INC += -I$(SYS_PATH) \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \ +- -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/7.5.0/include/ \ +- -I$(TOOL_PATH)/../../lib/armv7a-vfp-neon-rdk-linux-gnueabi/gcc/arm-rdk-linux-gnueabi/4.8.4/include/ \ +- -I$(TOOL_PATH)/../../lib/arm-rdk-linux-musleabi/gcc/arm-rdk-linux-musleabi/6.4.0/include/ \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source \ + -I$(SYS_PATH)/source/include \ diff --git a/root/package/firmware/nss/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch b/root/package/firmware/nss/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch new file mode 100644 index 00000000..8e802fe2 --- /dev/null +++ b/root/package/firmware/nss/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch @@ -0,0 +1,11 @@ +--- a/src/init/ssdk_plat.c ++++ b/src/init/ssdk_plat.c +@@ -568,7 +568,7 @@ static int miibus_get(a_uint32_t dev_id) + if(reg_mode == HSL_REG_LOCAL_BUS) + mdio_node = of_find_compatible_node(NULL, NULL, "qcom,ipq40xx-mdio"); + else +- mdio_node = of_find_compatible_node(NULL, NULL, "virtual,mdio-gpio"); ++ mdio_node = of_find_compatible_node(NULL, NULL, "qcom,ipq8064-mdio"); + + if (!mdio_node) { + SSDK_ERROR("No MDIO node found in DTS!\n"); diff --git a/root/target/linux/generic/hack-5.4/601-netfilter-export-udp_get_timeouts-function.patch b/root/target/linux/generic/hack-5.4/601-netfilter-export-udp_get_timeouts-function.patch new file mode 100644 index 00000000..3c28843a --- /dev/null +++ b/root/target/linux/generic/hack-5.4/601-netfilter-export-udp_get_timeouts-function.patch @@ -0,0 +1,42 @@ +From ba041eb8000e4a8f556ca641335894f7e7429dbb Mon Sep 17 00:00:00 2001 +From: Ailick <277498654@qq.com> +Date: Sat, 21 Aug 2021 17:12:22 +0800 +Subject: [PATCH] net: patch linux kernel to support shortcut-fe-cm + +--- + nf_conntrack_proto_udp.c | 3 ++- + nf_conntrack_timeout.h | 2 + + 1 file changed, 2 insertion(+) + +diff --git a/include/net/netfilter/nf_conntrack_timeout.h b/include/net/netfilter/nf_conntrack_timeout.h +index 6dd7239..e1f6d69 100644 +--- a/include/net/netfilter/nf_conntrack_timeout.h ++++ b/include/net/netfilter/nf_conntrack_timeout.h +@@ -123,5 +123,7 @@ static inline void nf_ct_destroy_timeout(struct nf_conn *ct) + extern struct nf_ct_timeout *(*nf_ct_timeout_find_get_hook)(struct net *net, const char *name); + extern void (*nf_ct_timeout_put_hook)(struct nf_ct_timeout *timeout); + #endif ++ ++extern unsigned int *udp_get_timeouts(struct net *net); + + #endif /* _NF_CONNTRACK_TIMEOUT_H */ +diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c +index 7365b43..2238d55 100644 +--- a/net/netfilter/nf_conntrack_proto_udp.c ++++ b/net/netfilter/nf_conntrack_proto_udp.c +@@ -29,10 +29,11 @@ static const unsigned int udp_timeouts[UDP_CT_MAX] = { + [UDP_CT_REPLIED] = 120*HZ, + }; + +-static unsigned int *udp_get_timeouts(struct net *net) ++unsigned int *udp_get_timeouts(struct net *net) + { + return nf_udp_pernet(net)->timeouts; + } ++EXPORT_SYMBOL(udp_get_timeouts); + + static void udp_error_log(const struct sk_buff *skb, + const struct nf_hook_state *state, +-- +2.17.1 +