From 8bad26fbd3bbaa5ade15e4f04a8f36a2780432f5 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Fri, 8 Dec 2023 23:29:29 +0800 Subject: [PATCH] package: support qualcommax target --- package/kernel/linux/modules/netsupport.mk | 2 +- package/kernel/linux/modules/usb.mk | 2 +- .../patches/200-nss-qdisc-support.patch | 11 - package/qca/firmware/nss-firmware/Makefile | 70 - package/qca/nss/nss-ifb/Makefile | 49 - package/qca/nss/nss-ifb/README.md | 45 - package/qca/nss/nss-ifb/src/Makefile | 3 - package/qca/nss/nss-ifb/src/nss_ifb.c | 304 ---- package/qca/nss/qca-nss-cfi/Makefile | 99 -- .../patches/0001-compile-only-cryptoapi.patch | 30 - .../patches/0002-wip-support-5.4.patch | 78 - .../0003-Convert-ablkcipher-to-skcipher.patch | 707 --------- package/qca/nss/qca-nss-clients-64/Makefile | 97 -- .../qca-nss-clients-64/files/qca-nss-ipsec | 214 --- .../files/qca-nss-mirred.init | 28 - .../files/qca-nss-ovpn.init | 69 - package/qca/nss/qca-nss-clients/Makefile | 469 ------ .../nss/qca-nss-clients/files/qca-nss-ipsec | 92 -- .../qca-nss-clients/files/qca-nss-mirred.init | 28 - .../qca-nss-clients/files/qca-nss-ovpn.init | 69 - .../100-kernel-5.4-support-qdisc.patch | 1145 --------------- .../patches/101-kernel-5.4-support-gre.patch | 106 -- .../102-kernel-5.4-support-ipsec.patch | 29 - .../patches/103-kernel-5.4-support-dtls.patch | 11 - .../patches/104-kernel-5.4-support-l2tp.patch | 64 - .../patches/200-qdisc-fix-compile-error.patch | 14 - .../202-vlanmgr-fix-compile-error.patch | 48 - package/qca/nss/qca-nss-crypto/Makefile | 74 - .../patches/100-kernel-5.4-support.patch | 42 - .../200-fix-NULL-pointer-exception.patch | 57 - ...-phy-mode-code-compatible-with-newer.patch | 48 - ...03-Drop-_nocache-variants-of-ioremap.patch | 48 - .../0006-NSS-DP-fix-of_get_mac_address.patch | 46 - ...07-NSS-DP-implement-ethernet-IOCTL-s.patch | 29 - ...dev-remove-the-transaction-structure.patch | 48 - ...09-switchdev-use-new-switchdev-flags.patch | 54 - ...fusing-printing-of-registered-netdev.patch | 41 - package/qca/nss/qca-nss-drv-64/Makefile | 119 -- .../nss/qca-nss-drv-64/files/qca-nss-drv.conf | 6 - .../qca-nss-drv-64/files/qca-nss-drv.debug | 26 - .../qca-nss-drv-64/files/qca-nss-drv.hotplug | 70 - .../nss/qca-nss-drv-64/files/qca-nss-drv.init | 50 - .../qca-nss-drv-64/files/qca-nss-drv.sysctl | 4 - ...ore-add-5.10-kernel-to-version-check.patch | 25 - ...replace-ioremap_nocache-with-ioremap.patch | 164 --- ...0003-DMA-Fix-NULL-pointer-exceptions.patch | 49 - ...-nss-drv-add-support-for-kernel-5.15.patch | 73 - ...dard-skb_skip_tc_classify-instead-of.patch | 29 - package/qca/nss/qca-nss-drv/Makefile | 125 -- .../files/nss-firmware/LICENSE.TXT | 45 - .../qca-nss-drv/files/nss-firmware/NOTICE.TXT | 217 --- .../qca-nss-drv/files/nss-firmware/README.md | 10 - .../files/nss-firmware/qca-nss0-retail.bin | Bin 536324 -> 0 bytes .../files/nss-firmware/qca-nss1-retail.bin | Bin 218224 -> 0 bytes .../nss/qca-nss-drv/files/qca-nss-drv.conf | 6 - .../nss/qca-nss-drv/files/qca-nss-drv.debug | 26 - .../nss/qca-nss-drv/files/qca-nss-drv.hotplug | 70 - .../nss/qca-nss-drv/files/qca-nss-drv.init | 50 - .../nss/qca-nss-drv/files/qca-nss-drv.sysctl | 4 - .../patches/100-kernel-5.4-support.patch | 107 -- ...ol-fab-scaling-from-package-Makefile.patch | 38 - .../200-fix-NULL-pointer-exception.patch | 11 - ...1-Fix-Kernel-Panic-dma-with-NULL-dev.patch | 82 -- .../400-Exported-set-nexthop-function.patch | 47 - package/qca/nss/qca-nss-ecm-64/Makefile | 96 -- .../qca/nss/qca-nss-ecm-64/files/ecm_dump.sh | 95 -- .../nss/qca-nss-ecm-64/files/on-demand-down | 6 - .../qca-nss-ecm-64/files/qca-nss-ecm.defaults | 28 - .../qca-nss-ecm-64/files/qca-nss-ecm.firewall | 18 - .../nss/qca-nss-ecm-64/files/qca-nss-ecm.init | 137 -- .../qca-nss-ecm-64/files/qca-nss-ecm.sysctl | 2 - .../nss/qca-nss-ecm-64/files/qca-nss-ecm.uci | 2 - ...de-componentize-the-module-even-more.patch | 335 ----- .../patches/002-kernel-5.10-support.patch | 831 ----------- .../003-rework-nfct-notification.patch | 25 - .../patches/004-More-compile-fixes.patch | 58 - .../patches/005-resolve-high-load.patch | 61 - ...terface-switch-to-kernel_recvmsg-api.patch | 40 - ...ide-rework-notifier-changes-for-5.15.patch | 72 - ...se-of-static-be_liberal-and-no_windo.patch | 156 -- ...tagram-drop-static-for-EXPORT_SYMBOL.patch | 55 - ...dp_get_timeouts-and-use-standard-ups.patch | 74 - ...-ecm-fix-a-memcpy-overflow-in-ecm_db.patch | 67 - package/qca/nss/qca-nss-ecm/Makefile | 278 ---- package/qca/nss/qca-nss-ecm/files/ecm_dump.sh | 95 -- .../qca/nss/qca-nss-ecm/files/on-demand-down | 6 - .../qca-nss-ecm/files/qca-nss-ecm.defaults | 28 - .../qca-nss-ecm/files/qca-nss-ecm.firewall | 18 - .../nss/qca-nss-ecm/files/qca-nss-ecm.init | 133 -- .../nss/qca-nss-ecm/files/qca-nss-ecm.sysctl | 2 - .../qca/nss/qca-nss-ecm/files/qca-nss-ecm.uci | 2 - .../patches/001-Drop_SFE_from_ecm.patch | 12 - .../patches/100-kernel-5.4-support.patch | 1276 ----------------- .../101-Fix_Kern_Panic_on_UDP_CONNTRACK.patch | 60 - .../patches/200-resolve-high-load.patch | 44 - .../203-rework-nfct-notification.patch | 20 - ...heck-TCP_UDP-conntrack-state-earlier.patch | 236 --- ...ix-NSS-stats-request-roll-over-issue.patch | 52 - ...01-Fix-for-ref-leak-during-multicast.patch | 112 -- ...neighbour-solicitation-send-function.patch | 33 - ...e-leak-during-multicast_PPPoE-bridge.patch | 260 ---- ...-global-accelerated-count-under-lock.patch | 59 - ...x-IPv6-neighbor-solicitation-request.patch | 83 -- ...tation-fix-with-zero-gateway-address.patch | 63 - ...-port-when-bridge-hairpin-is-enabled.patch | 126 -- package/qca/nss/qca-nss-gmac/Makefile | 47 - .../patches/100-kernel-5.4-support.patch | 279 ---- .../patches/101-nss-gmac-test-ptr.patch | 25 - ...-work-around-interface-close-warning.patch | 15 - package/qca/qca-mcs/Makefile | 54 - package/qca/{nss => }/qca-nss-dp/Makefile | 35 +- ...dp-Drop-_nocache-variants-of-ioremap.patch | 48 + ...ort-newer-kernels-time-stamping-API.patch} | 9 +- .../0003-EDMA-Fix-NAPI-packet-counting.patch} | 4 +- ...Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch} | 6 +- ...s-dp-adapt-to-netif_napi_add-changes.patch | 46 + ...a-phy-handle-property-to-connect-to-.patch | 180 +++ ...-dp-edma-v1-use-NAPI-GRO-by-default.patch} | 15 +- ...p-allow-setting-netdev-name-from-DTS.patch | 50 + ...09-nss-dp-switchdev-fix-FDB-roaming.patch} | 61 +- package/qca/qca-rfs/Makefile | 51 - package/qca/qca-rfs/files/qrfs.init | 27 - .../patches/100-add-kernel-5.4-support.patch | 57 - .../200-rework-nfct-notification.patch | 20 - package/qca/qca-ssdk-shell/Makefile | 48 - package/qca/qca-ssdk/Makefile | 102 +- package/qca/qca-ssdk/files/qca-ssdk | 206 --- ...001-SSDK-config-add-kernel-5.10-5.15.patch | 46 - ...7x-add-a-LED-quirk-for-Xiaomi-AX9000.patch | 67 + ...replace-ioremap_nocache-with-ioremap.patch | 87 -- ...7x-add-a-LED-quirk-for-Xiaomi-AX3600.patch | 29 + ...use-of_mdio_find_bus-to-get-MDIO-bus.patch | 24 - .../patches/0005-add-kernel-5.4-support.patch | 108 -- .../0006-fix-mdio-probe-on-ipq806x.patch | 11 - ...0007-SSDK-dts-fix-of_get_mac_address.patch | 27 - ...09-qca8081-convert-to-5.11-IRQ-model.patch | 70 - ...010-QSDK-config-Avoid-Werror-heroics.patch | 30 - ...mpilation-error-for-parse_uci_option.patch | 22 - .../shortcut-fe/fast-classifier/Makefile | 3 - .../shortcut-fe/fast-classifier/src/Makefile | 0 .../fast-classifier/src/fast-classifier.c | 0 .../fast-classifier/src/fast-classifier.h | 0 .../fast-classifier/src/nl_classifier_test.c | 0 .../fast-classifier/src/userspace_example.c | 0 .../shortcut-fe/shortcut-fe/Makefile | 6 +- .../shortcut-fe/files/etc/init.d/shortcut-fe | 0 .../shortcut-fe/files/usr/bin/sfe_dump | 0 .../shortcut-fe/shortcut-fe/src/Kconfig | 0 .../shortcut-fe/shortcut-fe/src/Makefile | 0 .../shortcut-fe/shortcut-fe/src/sfe.h | 0 .../shortcut-fe/src/sfe_backport.h | 0 .../shortcut-fe/shortcut-fe/src/sfe_cm.c | 0 .../shortcut-fe/shortcut-fe/src/sfe_cm.h | 0 .../shortcut-fe/shortcut-fe/src/sfe_ipv4.c | 0 .../shortcut-fe/shortcut-fe/src/sfe_ipv6.c | 0 .../shortcut-fe/simulated-driver/Makefile | 2 +- 156 files changed, 516 insertions(+), 12380 deletions(-) delete mode 100644 package/lean/shortcut-fe/simulated-driver/patches/200-nss-qdisc-support.patch delete mode 100644 package/qca/firmware/nss-firmware/Makefile delete mode 100644 package/qca/nss/nss-ifb/Makefile delete mode 100644 package/qca/nss/nss-ifb/README.md delete mode 100644 package/qca/nss/nss-ifb/src/Makefile delete mode 100644 package/qca/nss/nss-ifb/src/nss_ifb.c delete mode 100644 package/qca/nss/qca-nss-cfi/Makefile delete mode 100644 package/qca/nss/qca-nss-cfi/patches/0001-compile-only-cryptoapi.patch delete mode 100644 package/qca/nss/qca-nss-cfi/patches/0002-wip-support-5.4.patch delete mode 100644 package/qca/nss/qca-nss-cfi/patches/0003-Convert-ablkcipher-to-skcipher.patch delete mode 100644 package/qca/nss/qca-nss-clients-64/Makefile delete mode 100755 package/qca/nss/qca-nss-clients-64/files/qca-nss-ipsec delete mode 100644 package/qca/nss/qca-nss-clients-64/files/qca-nss-mirred.init delete mode 100644 package/qca/nss/qca-nss-clients-64/files/qca-nss-ovpn.init delete mode 100644 package/qca/nss/qca-nss-clients/Makefile delete mode 100644 package/qca/nss/qca-nss-clients/files/qca-nss-ipsec delete mode 100644 package/qca/nss/qca-nss-clients/files/qca-nss-mirred.init delete mode 100644 package/qca/nss/qca-nss-clients/files/qca-nss-ovpn.init delete mode 100644 package/qca/nss/qca-nss-clients/patches/100-kernel-5.4-support-qdisc.patch delete mode 100644 package/qca/nss/qca-nss-clients/patches/101-kernel-5.4-support-gre.patch delete mode 100644 package/qca/nss/qca-nss-clients/patches/102-kernel-5.4-support-ipsec.patch delete mode 100644 package/qca/nss/qca-nss-clients/patches/103-kernel-5.4-support-dtls.patch delete mode 100644 package/qca/nss/qca-nss-clients/patches/104-kernel-5.4-support-l2tp.patch delete mode 100644 package/qca/nss/qca-nss-clients/patches/200-qdisc-fix-compile-error.patch delete mode 100644 package/qca/nss/qca-nss-clients/patches/202-vlanmgr-fix-compile-error.patch delete mode 100644 package/qca/nss/qca-nss-crypto/Makefile delete mode 100644 package/qca/nss/qca-nss-crypto/patches/100-kernel-5.4-support.patch delete mode 100644 package/qca/nss/qca-nss-crypto/patches/200-fix-NULL-pointer-exception.patch delete mode 100644 package/qca/nss/qca-nss-dp/patches/0002-nss_dp_main-make-phy-mode-code-compatible-with-newer.patch delete mode 100644 package/qca/nss/qca-nss-dp/patches/0003-Drop-_nocache-variants-of-ioremap.patch delete mode 100644 package/qca/nss/qca-nss-dp/patches/0006-NSS-DP-fix-of_get_mac_address.patch delete mode 100644 package/qca/nss/qca-nss-dp/patches/0007-NSS-DP-implement-ethernet-IOCTL-s.patch delete mode 100644 package/qca/nss/qca-nss-dp/patches/0008-switchdev-remove-the-transaction-structure.patch delete mode 100644 package/qca/nss/qca-nss-dp/patches/0009-switchdev-use-new-switchdev-flags.patch delete mode 100644 package/qca/nss/qca-nss-dp/patches/0011-treewide-fix-confusing-printing-of-registered-netdev.patch delete mode 100644 package/qca/nss/qca-nss-drv-64/Makefile delete mode 100644 package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.conf delete mode 100644 package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.debug delete mode 100644 package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.hotplug delete mode 100644 package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.init delete mode 100644 package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.sysctl delete mode 100644 package/qca/nss/qca-nss-drv-64/patches/0001-core-add-5.10-kernel-to-version-check.patch delete mode 100644 package/qca/nss/qca-nss-drv-64/patches/0002-nss-drv-replace-ioremap_nocache-with-ioremap.patch delete mode 100644 package/qca/nss/qca-nss-drv-64/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch delete mode 100644 package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-add-support-for-kernel-5.15.patch delete mode 100644 package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-use-standard-skb_skip_tc_classify-instead-of.patch delete mode 100644 package/qca/nss/qca-nss-drv/Makefile delete mode 100644 package/qca/nss/qca-nss-drv/files/nss-firmware/LICENSE.TXT delete mode 100644 package/qca/nss/qca-nss-drv/files/nss-firmware/NOTICE.TXT delete mode 100644 package/qca/nss/qca-nss-drv/files/nss-firmware/README.md delete mode 100644 package/qca/nss/qca-nss-drv/files/nss-firmware/qca-nss0-retail.bin delete mode 100644 package/qca/nss/qca-nss-drv/files/nss-firmware/qca-nss1-retail.bin delete mode 100644 package/qca/nss/qca-nss-drv/files/qca-nss-drv.conf delete mode 100644 package/qca/nss/qca-nss-drv/files/qca-nss-drv.debug delete mode 100644 package/qca/nss/qca-nss-drv/files/qca-nss-drv.hotplug delete mode 100644 package/qca/nss/qca-nss-drv/files/qca-nss-drv.init delete mode 100644 package/qca/nss/qca-nss-drv/files/qca-nss-drv.sysctl delete mode 100644 package/qca/nss/qca-nss-drv/patches/100-kernel-5.4-support.patch delete mode 100644 package/qca/nss/qca-nss-drv/patches/101-nss-drv-Control-fab-scaling-from-package-Makefile.patch delete mode 100644 package/qca/nss/qca-nss-drv/patches/200-fix-NULL-pointer-exception.patch delete mode 100644 package/qca/nss/qca-nss-drv/patches/201-Fix-Kernel-Panic-dma-with-NULL-dev.patch delete mode 100644 package/qca/nss/qca-nss-drv/patches/400-Exported-set-nexthop-function.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/Makefile delete mode 100644 package/qca/nss/qca-nss-ecm-64/files/ecm_dump.sh delete mode 100644 package/qca/nss/qca-nss-ecm-64/files/on-demand-down delete mode 100644 package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.defaults delete mode 100644 package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.firewall delete mode 100644 package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.init delete mode 100644 package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.sysctl delete mode 100644 package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.uci delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/001-treewide-componentize-the-module-even-more.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/002-kernel-5.10-support.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/003-rework-nfct-notification.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/004-More-compile-fixes.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/005-resolve-high-load.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/006-ecm_interface-switch-to-kernel_recvmsg-api.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/007-treewide-rework-notifier-changes-for-5.15.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/008-frontends-drop-use-of-static-be_liberal-and-no_windo.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/009-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/010-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch delete mode 100644 package/qca/nss/qca-nss-ecm-64/patches/901-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch delete mode 100644 package/qca/nss/qca-nss-ecm/Makefile delete mode 100644 package/qca/nss/qca-nss-ecm/files/ecm_dump.sh delete mode 100644 package/qca/nss/qca-nss-ecm/files/on-demand-down delete mode 100644 package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.defaults delete mode 100644 package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.firewall delete mode 100644 package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.init delete mode 100644 package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.sysctl delete mode 100644 package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.uci delete mode 100644 package/qca/nss/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/100-kernel-5.4-support.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/101-Fix_Kern_Panic_on_UDP_CONNTRACK.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/200-resolve-high-load.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/203-rework-nfct-notification.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/400-Check-TCP_UDP-conntrack-state-earlier.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/401-Fix-NSS-stats-request-roll-over-issue.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/401-Fix-for-ref-leak-during-multicast.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/401-Fix-neighbour-solicitation-send-function.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/402-Reference-leak-during-multicast_PPPoE-bridge.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/403-Access-global-accelerated-count-under-lock.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/403-Fix-IPv6-neighbor-solicitation-request.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/404-IPv6-solicitation-fix-with-zero-gateway-address.patch delete mode 100644 package/qca/nss/qca-nss-ecm/patches/405-Allow-egress-on-same-port-when-bridge-hairpin-is-enabled.patch delete mode 100644 package/qca/nss/qca-nss-gmac/Makefile delete mode 100644 package/qca/nss/qca-nss-gmac/patches/100-kernel-5.4-support.patch delete mode 100644 package/qca/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch delete mode 100644 package/qca/nss/qca-nss-gmac/patches/200-work-around-interface-close-warning.patch delete mode 100644 package/qca/qca-mcs/Makefile rename package/qca/{nss => }/qca-nss-dp/Makefile (50%) create mode 100644 package/qca/qca-nss-dp/patches/0001-nss-dp-Drop-_nocache-variants-of-ioremap.patch rename package/qca/{nss/qca-nss-dp/patches/0001-edma_tx_rx-support-newer-kernels-time-stamping-API.patch => qca-nss-dp/patches/0002-edma_tx_rx-support-newer-kernels-time-stamping-API.patch} (82%) rename package/qca/{nss/qca-nss-dp/patches/0004-EDMA-Fix-NAPI-packet-counting.patch => qca-nss-dp/patches/0003-EDMA-Fix-NAPI-packet-counting.patch} (88%) rename package/qca/{nss/qca-nss-dp/patches/0005-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch => qca-nss-dp/patches/0004-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch} (87%) create mode 100644 package/qca/qca-nss-dp/patches/0005-nss-dp-adapt-to-netif_napi_add-changes.patch create mode 100644 package/qca/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch rename package/qca/{nss/qca-nss-dp/patches/0014-nss-dp-edma-v1-use-NAPI-GRO-by-default.patch => qca-nss-dp/patches/0007-nss-dp-edma-v1-use-NAPI-GRO-by-default.patch} (76%) create mode 100644 package/qca/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch rename package/qca/{nss/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch => qca-nss-dp/patches/0009-nss-dp-switchdev-fix-FDB-roaming.patch} (65%) delete mode 100644 package/qca/qca-rfs/Makefile delete mode 100755 package/qca/qca-rfs/files/qrfs.init delete mode 100644 package/qca/qca-rfs/patches/100-add-kernel-5.4-support.patch delete mode 100644 package/qca/qca-rfs/patches/200-rework-nfct-notification.patch delete mode 100644 package/qca/qca-ssdk-shell/Makefile delete mode 100755 package/qca/qca-ssdk/files/qca-ssdk delete mode 100644 package/qca/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10-5.15.patch create mode 100644 package/qca/qca-ssdk/patches/0001-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch delete mode 100644 package/qca/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch create mode 100644 package/qca/qca-ssdk/patches/0002-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch delete mode 100644 package/qca/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch delete mode 100644 package/qca/qca-ssdk/patches/0005-add-kernel-5.4-support.patch delete mode 100644 package/qca/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch delete mode 100644 package/qca/qca-ssdk/patches/0007-SSDK-dts-fix-of_get_mac_address.patch delete mode 100644 package/qca/qca-ssdk/patches/0009-qca8081-convert-to-5.11-IRQ-model.patch delete mode 100644 package/qca/qca-ssdk/patches/0010-QSDK-config-Avoid-Werror-heroics.patch delete mode 100644 package/qca/qca-ssdk/patches/0012-include-fix-compilation-error-for-parse_uci_option.patch rename package/{lean => qca}/shortcut-fe/fast-classifier/Makefile (92%) rename package/{lean => qca}/shortcut-fe/fast-classifier/src/Makefile (100%) rename package/{lean => qca}/shortcut-fe/fast-classifier/src/fast-classifier.c (100%) rename package/{lean => qca}/shortcut-fe/fast-classifier/src/fast-classifier.h (100%) rename package/{lean => qca}/shortcut-fe/fast-classifier/src/nl_classifier_test.c (100%) rename package/{lean => qca}/shortcut-fe/fast-classifier/src/userspace_example.c (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/Makefile (89%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/files/etc/init.d/shortcut-fe (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/files/usr/bin/sfe_dump (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/src/Kconfig (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/src/Makefile (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/src/sfe.h (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/src/sfe_backport.h (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/src/sfe_cm.c (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/src/sfe_cm.h (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/src/sfe_ipv4.c (100%) rename package/{lean => qca}/shortcut-fe/shortcut-fe/src/sfe_ipv6.c (100%) rename package/{lean => qca}/shortcut-fe/simulated-driver/Makefile (97%) diff --git a/package/kernel/linux/modules/netsupport.mk b/package/kernel/linux/modules/netsupport.mk index 0a64cc319..4e97df296 100644 --- a/package/kernel/linux/modules/netsupport.mk +++ b/package/kernel/linux/modules/netsupport.mk @@ -1559,7 +1559,7 @@ $(eval $(call KernelPackage,qrtr-tun)) define KernelPackage/qrtr-smd SUBMENU:=$(NETWORK_SUPPORT_MENU) TITLE:=SMD IPC Router channels - DEPENDS:=+kmod-qrtr @(TARGET_ipq60xx||TARGET_ipq807x) + DEPENDS:=+kmod-qrtr @TARGET_qualcommax KCONFIG:=CONFIG_QRTR_SMD FILES:= $(LINUX_DIR)/net/qrtr/qrtr-smd.ko AUTOLOAD:=$(call AutoProbe,qrtr-smd) diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk index b1ae500c0..c49df2560 100644 --- a/package/kernel/linux/modules/usb.mk +++ b/package/kernel/linux/modules/usb.mk @@ -494,7 +494,7 @@ $(eval $(call KernelPackage,usb-dwc3)) define KernelPackage/usb-dwc3-qcom TITLE:=DWC3 Qualcomm USB driver - DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_ipq807x||TARGET_ipq60xx) +kmod-usb-dwc3 + DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_qualcommax) +kmod-usb-dwc3 KCONFIG:= CONFIG_USB_DWC3_QCOM FILES:= $(LINUX_DIR)/drivers/usb/dwc3/dwc3-qcom.ko AUTOLOAD:=$(call AutoLoad,53,dwc3-qcom,1) diff --git a/package/lean/shortcut-fe/simulated-driver/patches/200-nss-qdisc-support.patch b/package/lean/shortcut-fe/simulated-driver/patches/200-nss-qdisc-support.patch deleted file mode 100644 index 638ad8a84..000000000 --- a/package/lean/shortcut-fe/simulated-driver/patches/200-nss-qdisc-support.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- ./simulated-driver/sfe_drv.c.orig 2020-06-16 12:49:47.680153371 +0800 -+++ ./simulated-driver/sfe_drv.c 2020-06-16 12:50:18.540153371 +0800 -@@ -1167,7 +1167,7 @@ int sfe_drv_recv(struct sk_buff *skb) - * If ingress Qdisc configured, and packet not processed by ingress Qdisc yet - * We can not accelerate this packet. - */ -- if (dev->ingress_queue && !(skb->tc_verd & TC_NCLS)) { -+ if (dev->ingress_queue && !(skb->tc_verd_qca_nss & TC_NCLS)) { - return 0; - } - #endif diff --git a/package/qca/firmware/nss-firmware/Makefile b/package/qca/firmware/nss-firmware/Makefile deleted file mode 100644 index 6ea4a57c0..000000000 --- a/package/qca/firmware/nss-firmware/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (C) 2021 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=nss-firmware -PKG_SOURCE_DATE:=2021-03-12 -PKG_SOURCE_VERSION:=73f378d6be21a9c20a69b77000dbb54a537006a9 -PKG_MIRROR_HASH:=0c21afe29002754edf2983bc9e8543dddd722e75bd12e961e300e99a310d1f62 -PKG_RELEASE:=$(AUTORELEASE) - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/quic/qca-sdk-nss-fw.git - -PKG_LICENSE_FILES:=LICENSE.md - -PKG_MAINTAINER:=Robert Marko - -include $(INCLUDE_DIR)/package.mk - -VERSION_PATH=$(PKG_BUILD_DIR)/QCA_Networking_2020.SPF_11.3/CS - -define Package/nss-firmware-default - SECTION:=firmware - CATEGORY:=Firmware - URL:=$(PKG_SOURCE_URL) - DEPENDS:=@(TARGET_ipq807x||TARGET_ipq60xx) -endef - -define Package/nss-firmware-ipq6018 -$(Package/nss-firmware-default) - TITLE:=NSS firmware for IPQ6018 devices - NSS_ARCHIVE:=$(VERSION_PATH)/IPQ6018.ATH.11.3/BIN-NSS.CP.11.3-9-R.tar.bz2 -endef - -define Package/nss-firmware-ipq8074 -$(Package/nss-firmware-default) - TITLE:=NSS firmware for IPQ8074 devices - NSS_ARCHIVE:=$(VERSION_PATH)/IPQ8074.ATH.11.3/BIN-NSS.HK.11.3-9-R.tar.bz2 -endef - -define Build/Compile - -endef - -define Package/nss-firmware-ipq6018/install - $(TAR) -C $(PKG_BUILD_DIR) -xf $(NSS_ARCHIVE) - $(INSTALL_DIR) $(1)/lib/firmware/ - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/BIN-NSS.CP.11.3-9-R/retail_router0.bin \ - $(1)/lib/firmware/qca-nss0-retail.bin -endef - -define Package/nss-firmware-ipq8074/install - $(TAR) -C $(PKG_BUILD_DIR) -xf $(NSS_ARCHIVE) - $(INSTALL_DIR) $(1)/lib/firmware/ - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/BIN-NSS.HK.11.3-9-R/retail_router0.bin \ - $(1)/lib/firmware/qca-nss0-retail.bin - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/BIN-NSS.HK.11.3-9-R/retail_router1.bin \ - $(1)/lib/firmware/qca-nss1-retail.bin -endef - -$(eval $(call BuildPackage,nss-firmware-ipq6018)) -$(eval $(call BuildPackage,nss-firmware-ipq8074)) diff --git a/package/qca/nss/nss-ifb/Makefile b/package/qca/nss/nss-ifb/Makefile deleted file mode 100644 index 6b7f0b480..000000000 --- a/package/qca/nss/nss-ifb/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# -# 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/package/qca/nss/nss-ifb/README.md b/package/qca/nss/nss-ifb/README.md deleted file mode 100644 index a0af7a5eb..000000000 --- a/package/qca/nss/nss-ifb/README.md +++ /dev/null @@ -1,45 +0,0 @@ -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/package/qca/nss/nss-ifb/src/Makefile b/package/qca/nss/nss-ifb/src/Makefile deleted file mode 100644 index 332b9b4ed..000000000 --- a/package/qca/nss/nss-ifb/src/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-m += nss-ifb.o - -nss-ifb-objs := nss_ifb.o diff --git a/package/qca/nss/nss-ifb/src/nss_ifb.c b/package/qca/nss/nss-ifb/src/nss_ifb.c deleted file mode 100644 index 18c017fe0..000000000 --- a/package/qca/nss/nss-ifb/src/nss_ifb.c +++ /dev/null @@ -1,304 +0,0 @@ -// 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/package/qca/nss/qca-nss-cfi/Makefile b/package/qca/nss/qca-nss-cfi/Makefile deleted file mode 100644 index 6371686ed..000000000 --- a/package/qca/nss/qca-nss-cfi/Makefile +++ /dev/null @@ -1,99 +0,0 @@ -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=qca-nss-cfi -PKG_RELEASE:=2 - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-cfi.git -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/package/qca/nss/qca-nss-cfi/patches/0001-compile-only-cryptoapi.patch b/package/qca/nss/qca-nss-cfi/patches/0001-compile-only-cryptoapi.patch deleted file mode 100644 index 00968f5fe..000000000 --- a/package/qca/nss/qca-nss-cfi/patches/0001-compile-only-cryptoapi.patch +++ /dev/null @@ -1,30 +0,0 @@ -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/package/qca/nss/qca-nss-cfi/patches/0002-wip-support-5.4.patch b/package/qca/nss/qca-nss-cfi/patches/0002-wip-support-5.4.patch deleted file mode 100644 index d68fc939b..000000000 --- a/package/qca/nss/qca-nss-cfi/patches/0002-wip-support-5.4.patch +++ /dev/null @@ -1,78 +0,0 @@ -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/package/qca/nss/qca-nss-cfi/patches/0003-Convert-ablkcipher-to-skcipher.patch b/package/qca/nss/qca-nss-cfi/patches/0003-Convert-ablkcipher-to-skcipher.patch deleted file mode 100644 index b4520a3d6..000000000 --- a/package/qca/nss/qca-nss-cfi/patches/0003-Convert-ablkcipher-to-skcipher.patch +++ /dev/null @@ -1,707 +0,0 @@ -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/package/qca/nss/qca-nss-clients-64/Makefile b/package/qca/nss/qca-nss-clients-64/Makefile deleted file mode 100644 index 03bbcd152..000000000 --- a/package/qca/nss/qca-nss-clients-64/Makefile +++ /dev/null @@ -1,97 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-nss-clients-64 -PKG_RELEASE:=$(AUTORELEASE) - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-clients.git -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_ipq60xx||TARGET_ipq807x) +kmod-qca-nss-drv-64 +kmod-ppp +kmod-pppoe +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-64/Description -Kernel modules for NSS connection manager - Support for PPPoE -endef - -define KernelPackage/qca-nss-drv-bridge-mgr-64 - SECTION:=kernel - CATEGORY:=Kernel modules - SUBMENU:=Network Devices - TITLE:=Kernel driver for NSS bridge manager - DEPENDS:=@(LINUX_5_10||LINUX_5_15) @(TARGET_ipq60xx||TARGET_ipq807x) +kmod-qca-nss-drv-64 +kmod-qca-nss-drv-vlan-mgr-64 - 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-64/Description -Kernel modules for NSS bridge manager -endef - -define KernelPackage/qca-nss-drv-vlan-mgr-64 - SECTION:=kernel - CATEGORY:=Kernel modules - SUBMENU:=Network Devices - TITLE:=Kernel driver for NSS vlan manager - DEPENDS:=@(LINUX_5_10||LINUX_5_15) @(TARGET_ipq60xx||TARGET_ipq807x) +kmod-qca-nss-drv-64 +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-64/Description -Kernel modules for NSS vlan manager -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 - -ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-bridge-mgr-64),) -NSS_CLIENTS_MAKE_OPTS+=bridge-mgr=y -endif - -ifneq ($(CONFIG_PACKAGE_kmod-qca-nss-drv-vlan-mgr-64),) -NSS_CLIENTS_MAKE_OPTS+=vlan-mgr=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)) -$(eval $(call KernelPackage,qca-nss-drv-bridge-mgr-64)) -$(eval $(call KernelPackage,qca-nss-drv-vlan-mgr-64)) diff --git a/package/qca/nss/qca-nss-clients-64/files/qca-nss-ipsec b/package/qca/nss/qca-nss-clients-64/files/qca-nss-ipsec deleted file mode 100755 index 5f682c8e9..000000000 --- a/package/qca/nss/qca-nss-clients-64/files/qca-nss-ipsec +++ /dev/null @@ -1,214 +0,0 @@ -#!/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/package/qca/nss/qca-nss-clients-64/files/qca-nss-mirred.init b/package/qca/nss/qca-nss-clients-64/files/qca-nss-mirred.init deleted file mode 100644 index 1f931f090..000000000 --- a/package/qca/nss/qca-nss-clients-64/files/qca-nss-mirred.init +++ /dev/null @@ -1,28 +0,0 @@ -#!/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/package/qca/nss/qca-nss-clients-64/files/qca-nss-ovpn.init b/package/qca/nss/qca-nss-clients-64/files/qca-nss-ovpn.init deleted file mode 100644 index 622e295ee..000000000 --- a/package/qca/nss/qca-nss-clients-64/files/qca-nss-ovpn.init +++ /dev/null @@ -1,69 +0,0 @@ -#!/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/package/qca/nss/qca-nss-clients/Makefile b/package/qca/nss/qca-nss-clients/Makefile deleted file mode 100644 index b27b49db8..000000000 --- a/package/qca/nss/qca-nss-clients/Makefile +++ /dev/null @@ -1,469 +0,0 @@ -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=qca-nss-clients -PKG_RELEASE:=2 - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-clients.git -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/package/qca/nss/qca-nss-clients/files/qca-nss-ipsec b/package/qca/nss/qca-nss-clients/files/qca-nss-ipsec deleted file mode 100644 index bb202e8e7..000000000 --- a/package/qca/nss/qca-nss-clients/files/qca-nss-ipsec +++ /dev/null @@ -1,92 +0,0 @@ -#!/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/package/qca/nss/qca-nss-clients/files/qca-nss-mirred.init b/package/qca/nss/qca-nss-clients/files/qca-nss-mirred.init deleted file mode 100644 index 1f931f090..000000000 --- a/package/qca/nss/qca-nss-clients/files/qca-nss-mirred.init +++ /dev/null @@ -1,28 +0,0 @@ -#!/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/package/qca/nss/qca-nss-clients/files/qca-nss-ovpn.init b/package/qca/nss/qca-nss-clients/files/qca-nss-ovpn.init deleted file mode 100644 index 622e295ee..000000000 --- a/package/qca/nss/qca-nss-clients/files/qca-nss-ovpn.init +++ /dev/null @@ -1,69 +0,0 @@ -#!/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/package/qca/nss/qca-nss-clients/patches/100-kernel-5.4-support-qdisc.patch b/package/qca/nss/qca-nss-clients/patches/100-kernel-5.4-support-qdisc.patch deleted file mode 100644 index 0ec8d766e..000000000 --- a/package/qca/nss/qca-nss-clients/patches/100-kernel-5.4-support-qdisc.patch +++ /dev/null @@ -1,1145 +0,0 @@ ---- 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/package/qca/nss/qca-nss-clients/patches/101-kernel-5.4-support-gre.patch b/package/qca/nss/qca-nss-clients/patches/101-kernel-5.4-support-gre.patch deleted file mode 100644 index 705ceabe6..000000000 --- a/package/qca/nss/qca-nss-clients/patches/101-kernel-5.4-support-gre.patch +++ /dev/null @@ -1,106 +0,0 @@ -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/package/qca/nss/qca-nss-clients/patches/102-kernel-5.4-support-ipsec.patch b/package/qca/nss/qca-nss-clients/patches/102-kernel-5.4-support-ipsec.patch deleted file mode 100644 index de43b4d01..000000000 --- a/package/qca/nss/qca-nss-clients/patches/102-kernel-5.4-support-ipsec.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- 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/package/qca/nss/qca-nss-clients/patches/103-kernel-5.4-support-dtls.patch b/package/qca/nss/qca-nss-clients/patches/103-kernel-5.4-support-dtls.patch deleted file mode 100644 index ae9c91470..000000000 --- a/package/qca/nss/qca-nss-clients/patches/103-kernel-5.4-support-dtls.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- 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/package/qca/nss/qca-nss-clients/patches/104-kernel-5.4-support-l2tp.patch b/package/qca/nss/qca-nss-clients/patches/104-kernel-5.4-support-l2tp.patch deleted file mode 100644 index c637235cc..000000000 --- a/package/qca/nss/qca-nss-clients/patches/104-kernel-5.4-support-l2tp.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- 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/package/qca/nss/qca-nss-clients/patches/200-qdisc-fix-compile-error.patch b/package/qca/nss/qca-nss-clients/patches/200-qdisc-fix-compile-error.patch deleted file mode 100644 index 4e147489b..000000000 --- a/package/qca/nss/qca-nss-clients/patches/200-qdisc-fix-compile-error.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- 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/package/qca/nss/qca-nss-clients/patches/202-vlanmgr-fix-compile-error.patch b/package/qca/nss/qca-nss-clients/patches/202-vlanmgr-fix-compile-error.patch deleted file mode 100644 index 53af31924..000000000 --- a/package/qca/nss/qca-nss-clients/patches/202-vlanmgr-fix-compile-error.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- 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/package/qca/nss/qca-nss-crypto/Makefile b/package/qca/nss/qca-nss-crypto/Makefile deleted file mode 100644 index 87e928b47..000000000 --- a/package/qca/nss/qca-nss-crypto/Makefile +++ /dev/null @@ -1,74 +0,0 @@ -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=qca-nss-crypto -PKG_RELEASE:=1 - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-crypto.git -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/package/qca/nss/qca-nss-crypto/patches/100-kernel-5.4-support.patch b/package/qca/nss/qca-nss-crypto/patches/100-kernel-5.4-support.patch deleted file mode 100644 index b9ef6191e..000000000 --- a/package/qca/nss/qca-nss-crypto/patches/100-kernel-5.4-support.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- 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/package/qca/nss/qca-nss-crypto/patches/200-fix-NULL-pointer-exception.patch b/package/qca/nss/qca-nss-crypto/patches/200-fix-NULL-pointer-exception.patch deleted file mode 100644 index 6bd95109a..000000000 --- a/package/qca/nss/qca-nss-crypto/patches/200-fix-NULL-pointer-exception.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- 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/package/qca/nss/qca-nss-dp/patches/0002-nss_dp_main-make-phy-mode-code-compatible-with-newer.patch b/package/qca/nss/qca-nss-dp/patches/0002-nss_dp_main-make-phy-mode-code-compatible-with-newer.patch deleted file mode 100644 index 04adad86f..000000000 --- a/package/qca/nss/qca-nss-dp/patches/0002-nss_dp_main-make-phy-mode-code-compatible-with-newer.patch +++ /dev/null @@ -1,48 +0,0 @@ -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 -@@ -22,7 +22,7 @@ - #include - #include - #include --#include -+#include - #include - - #include "nss_dp_api_if.h" -@@ -99,7 +99,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 -@@ -584,7 +584,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/package/qca/nss/qca-nss-dp/patches/0003-Drop-_nocache-variants-of-ioremap.patch b/package/qca/nss/qca-nss-dp/patches/0003-Drop-_nocache-variants-of-ioremap.patch deleted file mode 100644 index 18bd85c8c..000000000 --- a/package/qca/nss/qca-nss-dp/patches/0003-Drop-_nocache-variants-of-ioremap.patch +++ /dev/null @@ -1,48 +0,0 @@ -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/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 2 +- - hal/gmac_ops/qcom/qcom_if.c | 2 +- - hal/gmac_ops/syn/xgmac/syn_if.c | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - ---- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c -+++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c -@@ -279,7 +279,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_ops/qcom/qcom_if.c -+++ b/hal/gmac_ops/qcom/qcom_if.c -@@ -418,7 +418,7 @@ static void *qcom_init(struct nss_gmac_h - 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_ops/syn/xgmac/syn_if.c -+++ b/hal/gmac_ops/syn/xgmac/syn_if.c -@@ -432,7 +432,7 @@ static void *syn_init(struct nss_gmac_ha - - /* 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/package/qca/nss/qca-nss-dp/patches/0006-NSS-DP-fix-of_get_mac_address.patch b/package/qca/nss/qca-nss-dp/patches/0006-NSS-DP-fix-of_get_mac_address.patch deleted file mode 100644 index 1d7b49129..000000000 --- a/package/qca/nss/qca-nss-dp/patches/0006-NSS-DP-fix-of_get_mac_address.patch +++ /dev/null @@ -1,46 +0,0 @@ -From cadeb62a42296563141d6954eec58e34ef86778d Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 13 Aug 2021 20:12:08 +0200 -Subject: [PATCH] NSS-DP: fix of_get_mac_address() - -Recently OpenWrt backported the updated of_get_mac_address() -function which returns and error code instead. - -So, patch the SSDK to use it and fix the compilation error. - -Signed-off-by: Robert Marko ---- - nss_dp_main.c | 13 ++++--------- - 1 file changed, 4 insertions(+), 9 deletions(-) - ---- a/nss_dp_main.c -+++ b/nss_dp_main.c -@@ -555,9 +555,10 @@ static int32_t nss_dp_of_get_pdata(struc - struct net_device *netdev, - struct nss_gmac_hal_platform_data *hal_pdata) - { -- uint8_t *maddr; -+ u8 maddr[ETH_ALEN]; - struct nss_dp_dev *dp_priv; - struct resource memres_devtree = {0}; -+ int ret; - - dp_priv = netdev_priv(netdev); - -@@ -600,14 +601,8 @@ static int32_t nss_dp_of_get_pdata(struc - of_property_read_u32(np, "qcom,forced-speed", &dp_priv->forced_speed); - of_property_read_u32(np, "qcom,forced-duplex", &dp_priv->forced_duplex); - -- maddr = (uint8_t *)of_get_mac_address(np); --#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0)) -- if (IS_ERR((void *)maddr)) { -- maddr = NULL; -- } --#endif -- -- if (maddr && is_valid_ether_addr(maddr)) { -+ ret = of_get_mac_address(np, maddr); -+ if (!ret && is_valid_ether_addr(maddr)) { - ether_addr_copy(netdev->dev_addr, maddr); - } else { - random_ether_addr(netdev->dev_addr); diff --git a/package/qca/nss/qca-nss-dp/patches/0007-NSS-DP-implement-ethernet-IOCTL-s.patch b/package/qca/nss/qca-nss-dp/patches/0007-NSS-DP-implement-ethernet-IOCTL-s.patch deleted file mode 100644 index 824f18634..000000000 --- a/package/qca/nss/qca-nss-dp/patches/0007-NSS-DP-implement-ethernet-IOCTL-s.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 5da62ba19f554bf437752a44360fb5ae9f1a7f5e Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 8 Mar 2022 10:48:32 +0100 -Subject: [PATCH] NSS-DP: implement ethernet IOCTL-s - -Since kernel 5.15 ethernet/PHY related IOCTL-s have been split from the -generic IOCTL netdev op. -So, implement the new op instead of the generic one which is considered -for private IOCTL-s only now for 5.15+. - -Signed-off-by: Robert Marko ---- - nss_dp_main.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/nss_dp_main.c -+++ b/nss_dp_main.c -@@ -532,7 +532,11 @@ static const struct net_device_ops nss_d - .ndo_set_mac_address = nss_dp_set_mac_address, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = nss_dp_change_mtu, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) - .ndo_do_ioctl = nss_dp_do_ioctl, -+#else -+ .ndo_eth_ioctl = nss_dp_do_ioctl, -+#endif - - #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) - .ndo_bridge_setlink = switchdev_port_bridge_setlink, diff --git a/package/qca/nss/qca-nss-dp/patches/0008-switchdev-remove-the-transaction-structure.patch b/package/qca/nss/qca-nss-dp/patches/0008-switchdev-remove-the-transaction-structure.patch deleted file mode 100644 index 220be961a..000000000 --- a/package/qca/nss/qca-nss-dp/patches/0008-switchdev-remove-the-transaction-structure.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c9afdcdd2642485a6476906be9da2e811090fc7a Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 18 Mar 2022 18:06:03 +0100 -Subject: [PATCH] switchdev: remove the transaction structure - -Since 5.12 there is no transaction structure anymore, so drop it for -5.12 and newer. - -Signed-off-by: Robert Marko ---- - nss_dp_switchdev.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/nss_dp_switchdev.c -+++ b/nss_dp_switchdev.c -@@ -279,13 +279,19 @@ void nss_dp_switchdev_setup(struct net_d - * Sets attributes - */ - static int nss_dp_port_attr_set(struct net_device *dev, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) - const struct switchdev_attr *attr, - struct switchdev_trans *trans) -+#else -+ const struct switchdev_attr *attr) -+#endif - { - struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev); - -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) - if (switchdev_trans_ph_prepare(trans)) - return 0; -+#endif - - switch (attr->id) { - case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: -@@ -309,8 +315,12 @@ static int nss_dp_switchdev_port_attr_se - { - int err; - -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) - err = nss_dp_port_attr_set(netdev, port_attr_info->attr, - port_attr_info->trans); -+#else -+ err = nss_dp_port_attr_set(netdev, port_attr_info->attr); -+#endif - - port_attr_info->handled = true; - return notifier_from_errno(err); diff --git a/package/qca/nss/qca-nss-dp/patches/0009-switchdev-use-new-switchdev-flags.patch b/package/qca/nss/qca-nss-dp/patches/0009-switchdev-use-new-switchdev-flags.patch deleted file mode 100644 index bac21b1b1..000000000 --- a/package/qca/nss/qca-nss-dp/patches/0009-switchdev-use-new-switchdev-flags.patch +++ /dev/null @@ -1,54 +0,0 @@ -From f95868d54301c0f54e968ec9d978c9caa02ee425 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 18 Mar 2022 18:24:18 +0100 -Subject: [PATCH] switchdev: use new switchdev flags - -Since kernel 5.12 switched utilizes a new way of setting the flags by -using a dedicated structure with flags and mask. - -So fix using kernels 5.12 and later. - -Signed-off-by: Robert Marko ---- - include/nss_dp_dev.h | 7 +++++++ - nss_dp_switchdev.c | 2 +- - 2 files changed, 8 insertions(+), 1 deletion(-) - ---- a/include/nss_dp_dev.h -+++ b/include/nss_dp_dev.h -@@ -24,6 +24,9 @@ - #include - #include - #include -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) -+#include -+#endif - - #include "nss_dp_api_if.h" - #include "nss_dp_hal_if.h" -@@ -126,7 +129,11 @@ struct nss_dp_dev { - /* switchdev related attributes */ - #ifdef CONFIG_NET_SWITCHDEV - u8 stp_state; /* STP state of this physical port */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) - unsigned long brport_flags; /* bridge port flags */ -+#else -+ struct switchdev_brport_flags brport_flags; /* bridge port flags */ -+#endif - #endif - uint32_t rx_page_mode; /* page mode for Rx processing */ - uint32_t rx_jumbo_mru; /* Jumbo mru value for Rx processing */ ---- a/nss_dp_switchdev.c -+++ b/nss_dp_switchdev.c -@@ -296,7 +296,11 @@ static int nss_dp_port_attr_set(struct n - switch (attr->id) { - case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: - dp_priv->brport_flags = attr->u.brport_flags; -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)) - netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags); -+#else -+ netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags.val); -+#endif - return 0; - case SWITCHDEV_ATTR_ID_PORT_STP_STATE: - return nss_dp_stp_state_set(dp_priv, attr->u.stp_state); diff --git a/package/qca/nss/qca-nss-dp/patches/0011-treewide-fix-confusing-printing-of-registered-netdev.patch b/package/qca/nss/qca-nss-dp/patches/0011-treewide-fix-confusing-printing-of-registered-netdev.patch deleted file mode 100644 index 726ca304d..000000000 --- a/package/qca/nss/qca-nss-dp/patches/0011-treewide-fix-confusing-printing-of-registered-netdev.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7e4ae2d6285095794d73d2f2ce61404f61d4e633 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 17 May 2022 15:55:36 +0200 -Subject: [PATCH 11/11] treewide: fix confusing printing of registered netdev - -Net core implementation changed and now printing the netdev name cause -confusing printing if done before register_netdev. Move the old printing -to dbg and add an additional info log right after register_netdev to -give the user some info on correct nss-dp probe. - -Signed-off-by: Ansuel Smith ---- - hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 4 ++-- - nss_dp_main.c | 3 +++ - 2 files changed, 5 insertions(+), 2 deletions(-) - ---- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c -+++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c -@@ -822,8 +822,8 @@ static int edma_register_netdevice(struc - return -EINVAL; - } - -- netdev_info(netdev, "nss_dp_edma: Registering netdev %s(qcom-id:%d) with EDMA\n", -- netdev->name, macid); -+ netdev_dbg(netdev, "nss_dp_edma: Registering netdev %s(qcom-id:%d) with EDMA\n", -+ netdev->name, macid); - - /* - * We expect 'macid' to correspond to ports numbers on ---- a/nss_dp_main.c -+++ b/nss_dp_main.c -@@ -875,6 +875,9 @@ static int32_t nss_dp_probe(struct platf - goto phy_setup_fail; - } - -+ netdev_info(netdev, "Registered netdev %s(qcom-id:%d)\n", -+ netdev->name, port_id); -+ - dp_global_ctx.nss_dp[dp_priv->macid - 1] = dp_priv; - dp_global_ctx.slowproto_acl_bm = 0; - diff --git a/package/qca/nss/qca-nss-drv-64/Makefile b/package/qca/nss/qca-nss-drv-64/Makefile deleted file mode 100644 index 85f73b04c..000000000 --- a/package/qca/nss/qca-nss-drv-64/Makefile +++ /dev/null @@ -1,119 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-nss-drv-64 -PKG_RELEASE:=$(AUTORELEASE) - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-drv.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2022-01-24 -PKG_SOURCE_VERSION:=4f1b8e51105bb71ebd0bb07c1ec0d8b6e5d0913e -PKG_MIRROR_HASH:=4d32e072fb019d43adce8b1bc58c11a424aba31c3baa2d0b802141baa73d53e7 - -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 -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/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.conf b/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.conf deleted file mode 100644 index a8a1fbf40..000000000 --- a/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.conf +++ /dev/null @@ -1,6 +0,0 @@ -config nss_firmware 'qca_nss_0' - -config nss_firmware 'qca_nss_1' - -config general - option enable_rps '1' diff --git a/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.debug b/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.debug deleted file mode 100644 index 5d435c3a7..000000000 --- a/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.debug +++ /dev/null @@ -1,26 +0,0 @@ -#!/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/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.hotplug b/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.hotplug deleted file mode 100644 index 1e4813838..000000000 --- a/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.hotplug +++ /dev/null @@ -1,70 +0,0 @@ -#!/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/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.init b/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.init deleted file mode 100644 index de12cb6d1..000000000 --- a/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.init +++ /dev/null @@ -1,50 +0,0 @@ -#!/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/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.sysctl b/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.sysctl deleted file mode 100644 index fc36c33eb..000000000 --- a/package/qca/nss/qca-nss-drv-64/files/qca-nss-drv.sysctl +++ /dev/null @@ -1,4 +0,0 @@ -# Default Number of connection configuration -dev.nss.ipv4cfg.ipv4_conn=4096 -dev.nss.ipv6cfg.ipv6_conn=4096 - diff --git a/package/qca/nss/qca-nss-drv-64/patches/0001-core-add-5.10-kernel-to-version-check.patch b/package/qca/nss/qca-nss-drv-64/patches/0001-core-add-5.10-kernel-to-version-check.patch deleted file mode 100644 index 3fea9b5ce..000000000 --- a/package/qca/nss/qca-nss-drv-64/patches/0001-core-add-5.10-kernel-to-version-check.patch +++ /dev/null @@ -1,25 +0,0 @@ -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/package/qca/nss/qca-nss-drv-64/patches/0002-nss-drv-replace-ioremap_nocache-with-ioremap.patch b/package/qca/nss/qca-nss-drv-64/patches/0002-nss-drv-replace-ioremap_nocache-with-ioremap.patch deleted file mode 100644 index 77155750c..000000000 --- a/package/qca/nss/qca-nss-drv-64/patches/0002-nss-drv-replace-ioremap_nocache-with-ioremap.patch +++ /dev/null @@ -1,164 +0,0 @@ -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/package/qca/nss/qca-nss-drv-64/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch b/package/qca/nss/qca-nss-drv-64/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch deleted file mode 100644 index 0c13a7887..000000000 --- a/package/qca/nss/qca-nss-drv-64/patches/0003-DMA-Fix-NULL-pointer-exceptions.patch +++ /dev/null @@ -1,49 +0,0 @@ -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/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-add-support-for-kernel-5.15.patch b/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-add-support-for-kernel-5.15.patch deleted file mode 100644 index dfebd0d6f..000000000 --- a/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-add-support-for-kernel-5.15.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 6e65f6daecb09463688eaea0a234018a728196b8 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 5 Apr 2022 18:10:57 +0200 -Subject: [PATCH 5/8] nss-drv: add support for kernel 5.15 - -- Fix coredump panic notifier include change. -- Fix skb ZEROCOPY flag. -- Add skb reuse support for 5.15 kernel version. - -Signed-off-by: Ansuel Smith ---- - nss_core.c | 5 +++-- - nss_coredump.c | 4 ++++ - nss_hal/nss_hal.c | 1 + - 3 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/nss_core.c b/nss_core.c -index f9e6014..8cd1d4b 100644 ---- a/nss_core.c -+++ b/nss_core.c -@@ -53,7 +53,8 @@ - (((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, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)))))) -+(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)))) || \ -+(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)))))) - #error "Check skb recycle code in this file to match Linux version" - #endif - -@@ -2623,7 +2624,11 @@ static inline bool nss_core_skb_can_reuse(struct nss_ctx_instance *nss_ctx, - if (unlikely(irqs_disabled())) - return false; - -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) - if (unlikely(skb_shinfo(nbuf)->tx_flags & SKBTX_DEV_ZEROCOPY)) -+#else -+ if (unlikely(skb_shinfo(nbuf)->flags & SKBFL_ZEROCOPY_ENABLE)) -+#endif - return false; - - if (unlikely(skb_is_nonlinear(nbuf))) -diff --git a/nss_coredump.c b/nss_coredump.c -index ecad659..3ecef7e 100644 ---- a/nss_coredump.c -+++ b/nss_coredump.c -@@ -23,7 +23,11 @@ - #include "nss_hal.h" - #include "nss_log.h" - #include -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0)) - #include /* for panic_notifier_list */ -+#else -+#include -+#endif - #include /* for time */ - #include "nss_tx_rx_common.h" - -diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c -index 57974c1..d8c703b 100644 ---- a/nss_hal/nss_hal.c -+++ b/nss_hal/nss_hal.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include "nss_hal.h" - #include "nss_arch.h" --- -2.34.1 - diff --git a/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-use-standard-skb_skip_tc_classify-instead-of.patch b/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-use-standard-skb_skip_tc_classify-instead-of.patch deleted file mode 100644 index 73c923d3d..000000000 --- a/package/qca/nss/qca-nss-drv-64/patches/0005-nss-drv-use-standard-skb_skip_tc_classify-instead-of.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 4dd701916186803172a9f35e7e982a953613ad55 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 11 Apr 2022 21:32:41 +0200 -Subject: [PATCH 5/9] nss-drv: use standard skb_skip_tc_classify instead of - custom api - -Use skb_skip_tc_classify to skip classify for packet handled by nss -instead of custom api. - -Signed-off-by: Ansuel Smith ---- - nss_core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/nss_core.c b/nss_core.c -index f9e6014..6ab8038 100644 ---- a/nss_core.c -+++ b/nss_core.c -@@ -1075,7 +1075,7 @@ static inline void nss_core_set_skb_classify(struct sk_buff *nbuf) - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) - nbuf->tc_verd = SET_TC_NCLS_NSS(nbuf->tc_verd); - #else -- skb_set_tc_classify_offload(nbuf); -+ skb_skip_tc_classify(nbuf); - #endif - #endif - } --- -2.34.1 diff --git a/package/qca/nss/qca-nss-drv/Makefile b/package/qca/nss/qca-nss-drv/Makefile deleted file mode 100644 index 9a74bc833..000000000 --- a/package/qca/nss/qca-nss-drv/Makefile +++ /dev/null @@ -1,125 +0,0 @@ -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=qca-nss-drv -PKG_RELEASE:=2 - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-drv.git -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/package/qca/nss/qca-nss-drv/files/nss-firmware/LICENSE.TXT b/package/qca/nss/qca-nss-drv/files/nss-firmware/LICENSE.TXT deleted file mode 100644 index 41631989a..000000000 --- a/package/qca/nss/qca-nss-drv/files/nss-firmware/LICENSE.TXT +++ /dev/null @@ -1,45 +0,0 @@ -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/package/qca/nss/qca-nss-drv/files/nss-firmware/NOTICE.TXT b/package/qca/nss/qca-nss-drv/files/nss-firmware/NOTICE.TXT deleted file mode 100644 index ab54aa019..000000000 --- a/package/qca/nss/qca-nss-drv/files/nss-firmware/NOTICE.TXT +++ /dev/null @@ -1,217 +0,0 @@ -============================================================================= - -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/package/qca/nss/qca-nss-drv/files/nss-firmware/README.md b/package/qca/nss/qca-nss-drv/files/nss-firmware/README.md deleted file mode 100644 index 2d0b47508..000000000 --- a/package/qca/nss/qca-nss-drv/files/nss-firmware/README.md +++ /dev/null @@ -1,10 +0,0 @@ -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/package/qca/nss/qca-nss-drv/files/nss-firmware/qca-nss0-retail.bin b/package/qca/nss/qca-nss-drv/files/nss-firmware/qca-nss0-retail.bin deleted file mode 100644 index 08f6efe6c8d8c476a7b68c8b44e125db75276cef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 536324 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 z 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

4|GJx3IMG;WZSS-@ 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ΠfAA56W)Al)uy*Y5hcMjv&o6EXSJ?Ho3 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

  • 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 diff --git a/package/qca/nss/qca-nss-drv/files/nss-firmware/qca-nss1-retail.bin b/package/qca/nss/qca-nss-drv/files/nss-firmware/qca-nss1-retail.bin deleted file mode 100644 index e79510f34de55c649a7fb48f1ba40c59294bb525..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218224 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 diff --git a/package/qca/nss/qca-nss-drv/files/qca-nss-drv.conf b/package/qca/nss/qca-nss-drv/files/qca-nss-drv.conf deleted file mode 100644 index a8a1fbf40..000000000 --- a/package/qca/nss/qca-nss-drv/files/qca-nss-drv.conf +++ /dev/null @@ -1,6 +0,0 @@ -config nss_firmware 'qca_nss_0' - -config nss_firmware 'qca_nss_1' - -config general - option enable_rps '1' diff --git a/package/qca/nss/qca-nss-drv/files/qca-nss-drv.debug b/package/qca/nss/qca-nss-drv/files/qca-nss-drv.debug deleted file mode 100644 index 5d435c3a7..000000000 --- a/package/qca/nss/qca-nss-drv/files/qca-nss-drv.debug +++ /dev/null @@ -1,26 +0,0 @@ -#!/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/package/qca/nss/qca-nss-drv/files/qca-nss-drv.hotplug b/package/qca/nss/qca-nss-drv/files/qca-nss-drv.hotplug deleted file mode 100644 index 1e4813838..000000000 --- a/package/qca/nss/qca-nss-drv/files/qca-nss-drv.hotplug +++ /dev/null @@ -1,70 +0,0 @@ -#!/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/package/qca/nss/qca-nss-drv/files/qca-nss-drv.init b/package/qca/nss/qca-nss-drv/files/qca-nss-drv.init deleted file mode 100644 index de12cb6d1..000000000 --- a/package/qca/nss/qca-nss-drv/files/qca-nss-drv.init +++ /dev/null @@ -1,50 +0,0 @@ -#!/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/package/qca/nss/qca-nss-drv/files/qca-nss-drv.sysctl b/package/qca/nss/qca-nss-drv/files/qca-nss-drv.sysctl deleted file mode 100644 index fc36c33eb..000000000 --- a/package/qca/nss/qca-nss-drv/files/qca-nss-drv.sysctl +++ /dev/null @@ -1,4 +0,0 @@ -# Default Number of connection configuration -dev.nss.ipv4cfg.ipv4_conn=4096 -dev.nss.ipv6cfg.ipv6_conn=4096 - diff --git a/package/qca/nss/qca-nss-drv/patches/100-kernel-5.4-support.patch b/package/qca/nss/qca-nss-drv/patches/100-kernel-5.4-support.patch deleted file mode 100644 index 4268225c3..000000000 --- a/package/qca/nss/qca-nss-drv/patches/100-kernel-5.4-support.patch +++ /dev/null @@ -1,107 +0,0 @@ -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/package/qca/nss/qca-nss-drv/patches/101-nss-drv-Control-fab-scaling-from-package-Makefile.patch b/package/qca/nss/qca-nss-drv/patches/101-nss-drv-Control-fab-scaling-from-package-Makefile.patch deleted file mode 100644 index b0facc856..000000000 --- a/package/qca/nss/qca-nss-drv/patches/101-nss-drv-Control-fab-scaling-from-package-Makefile.patch +++ /dev/null @@ -1,38 +0,0 @@ -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/package/qca/nss/qca-nss-drv/patches/200-fix-NULL-pointer-exception.patch b/package/qca/nss/qca-nss-drv/patches/200-fix-NULL-pointer-exception.patch deleted file mode 100644 index 3d8bba950..000000000 --- a/package/qca/nss/qca-nss-drv/patches/200-fix-NULL-pointer-exception.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- 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/package/qca/nss/qca-nss-drv/patches/201-Fix-Kernel-Panic-dma-with-NULL-dev.patch b/package/qca/nss/qca-nss-drv/patches/201-Fix-Kernel-Panic-dma-with-NULL-dev.patch deleted file mode 100644 index addfef1bb..000000000 --- a/package/qca/nss/qca-nss-drv/patches/201-Fix-Kernel-Panic-dma-with-NULL-dev.patch +++ /dev/null @@ -1,82 +0,0 @@ -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/package/qca/nss/qca-nss-drv/patches/400-Exported-set-nexthop-function.patch b/package/qca/nss/qca-nss-drv/patches/400-Exported-set-nexthop-function.patch deleted file mode 100644 index 8c0ffe774..000000000 --- a/package/qca/nss/qca-nss-drv/patches/400-Exported-set-nexthop-function.patch +++ /dev/null @@ -1,47 +0,0 @@ -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/package/qca/nss/qca-nss-ecm-64/Makefile b/package/qca/nss/qca-nss-ecm-64/Makefile deleted file mode 100644 index d96509868..000000000 --- a/package/qca/nss/qca-nss-ecm-64/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-nss-ecm-64 -PKG_RELEASE:=$(AUTORELEASE) - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-nss-ecm.git -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 -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/package/qca/nss/qca-nss-ecm-64/files/ecm_dump.sh b/package/qca/nss/qca-nss-ecm-64/files/ecm_dump.sh deleted file mode 100644 index dbf7de753..000000000 --- a/package/qca/nss/qca-nss-ecm-64/files/ecm_dump.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm-64/files/on-demand-down b/package/qca/nss/qca-nss-ecm-64/files/on-demand-down deleted file mode 100644 index 02d708e03..000000000 --- a/package/qca/nss/qca-nss-ecm-64/files/on-demand-down +++ /dev/null @@ -1,6 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.defaults b/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.defaults deleted file mode 100644 index 308e265c9..000000000 --- a/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.defaults +++ /dev/null @@ -1,28 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.firewall b/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.firewall deleted file mode 100644 index 24c64def2..000000000 --- a/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.firewall +++ /dev/null @@ -1,18 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.init b/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.init deleted file mode 100644 index 78cf16dc0..000000000 --- a/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.init +++ /dev/null @@ -1,137 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.sysctl b/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.sysctl deleted file mode 100644 index 1a3d76b18..000000000 --- a/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.sysctl +++ /dev/null @@ -1,2 +0,0 @@ -# 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/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.uci b/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.uci deleted file mode 100644 index 4f2de6877..000000000 --- a/package/qca/nss/qca-nss-ecm-64/files/qca-nss-ecm.uci +++ /dev/null @@ -1,2 +0,0 @@ -config ecm 'global' - option acceleration_engine 'auto' diff --git a/package/qca/nss/qca-nss-ecm-64/patches/001-treewide-componentize-the-module-even-more.patch b/package/qca/nss/qca-nss-ecm-64/patches/001-treewide-componentize-the-module-even-more.patch deleted file mode 100644 index 4e7932c9d..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/001-treewide-componentize-the-module-even-more.patch +++ /dev/null @@ -1,335 +0,0 @@ -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/package/qca/nss/qca-nss-ecm-64/patches/002-kernel-5.10-support.patch b/package/qca/nss/qca-nss-ecm-64/patches/002-kernel-5.10-support.patch deleted file mode 100644 index 107b9571b..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/002-kernel-5.10-support.patch +++ /dev/null @@ -1,831 +0,0 @@ -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/package/qca/nss/qca-nss-ecm-64/patches/003-rework-nfct-notification.patch b/package/qca/nss/qca-nss-ecm-64/patches/003-rework-nfct-notification.patch deleted file mode 100644 index 72005cd70..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/003-rework-nfct-notification.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- 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/package/qca/nss/qca-nss-ecm-64/patches/004-More-compile-fixes.patch b/package/qca/nss/qca-nss-ecm-64/patches/004-More-compile-fixes.patch deleted file mode 100644 index a998d8295..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/004-More-compile-fixes.patch +++ /dev/null @@ -1,58 +0,0 @@ -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/package/qca/nss/qca-nss-ecm-64/patches/005-resolve-high-load.patch b/package/qca/nss/qca-nss-ecm-64/patches/005-resolve-high-load.patch deleted file mode 100644 index f4106a355..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/005-resolve-high-load.patch +++ /dev/null @@ -1,61 +0,0 @@ -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/package/qca/nss/qca-nss-ecm-64/patches/006-ecm_interface-switch-to-kernel_recvmsg-api.patch b/package/qca/nss/qca-nss-ecm-64/patches/006-ecm_interface-switch-to-kernel_recvmsg-api.patch deleted file mode 100644 index caa591abf..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/006-ecm_interface-switch-to-kernel_recvmsg-api.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/ecm_interface.c b/ecm_interface.c -index b461456..6be872a 100644 ---- a/ecm_interface.c -+++ b/ecm_interface.c -@@ -7493,9 +7493,13 @@ - static int ecm_interface_wifi_event_rx(struct socket *sock, struct sockaddr_nl *addr, unsigned char *buf, int len) - { - struct msghdr msg; -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) - struct iovec iov; - mm_segment_t oldfs; - int size; -+#else -+ struct kvec iov; -+#endif - - iov.iov_base = buf; - iov.iov_len = len; -@@ -7505,9 +7509,10 @@ - msg.msg_namelen = sizeof(struct sockaddr_nl); - msg.msg_control = NULL; - msg.msg_controllen = 0; -- iov_iter_init(&msg.msg_iter, READ, &iov, 1, 1); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) - oldfs = get_fs(); - set_fs(KERNEL_DS); -+ iov_iter_init(&msg.msg_iter, READ, &iov, 1, 1); - #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)) - size = sock_recvmsg(sock, &msg, len, msg.msg_flags); - #else -@@ -7516,6 +7521,9 @@ - set_fs(oldfs); - - return size; -+#else -+ return kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len, 0); -+#endif - } - - /* diff --git a/package/qca/nss/qca-nss-ecm-64/patches/007-treewide-rework-notifier-changes-for-5.15.patch b/package/qca/nss/qca-nss-ecm-64/patches/007-treewide-rework-notifier-changes-for-5.15.patch deleted file mode 100644 index 262a8fb85..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/007-treewide-rework-notifier-changes-for-5.15.patch +++ /dev/null @@ -1,72 +0,0 @@ -From e9073363a50a25bddd96e808f04bcf56c45da4ac Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 8 May 2022 18:19:47 +0200 -Subject: [PATCH 07/12] treewide: rework notifier changes for 5.15 - -Rework notifier changes for 5.15 conntrack new implementation. - -Signed-off-by: Ansuel Smith ---- - ecm_conntrack_notifier.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/ecm_conntrack_notifier.c b/ecm_conntrack_notifier.c -index 9c8a45e..9f2cdae 100644 ---- a/ecm_conntrack_notifier.c -+++ b/ecm_conntrack_notifier.c -@@ -322,7 +322,7 @@ EXPORT_SYMBOL(ecm_conntrack_ipv4_event); - #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS - static int ecm_conntrack_event(struct notifier_block *this, unsigned long events, void *ptr) - #else --static int ecm_conntrack_event(unsigned int events, struct nf_ct_event *item) -+static int ecm_conntrack_event(unsigned int events, const struct nf_ct_event *item) - #endif - { - #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS -@@ -388,7 +388,11 @@ static struct notifier_block ecm_conntrack_notifier = { - * Netfilter conntrack event system to monitor connection tracking changes - */ - static struct nf_ct_event_notifier ecm_conntrack_notifier = { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) - .fcn = ecm_conntrack_event, -+#else -+ .ct_event = ecm_conntrack_event, -+#endif - }; - #endif - #endif -@@ -426,13 +430,19 @@ int ecm_conntrack_notifier_init(struct dentry *dentry) - #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS - result = nf_conntrack_register_chain_notifier(&init_net, &ecm_conntrack_notifier); - #else -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) - result = nf_conntrack_register_notifier(&init_net, &ecm_conntrack_notifier); -+#else -+ nf_conntrack_register_notifier(&init_net, &ecm_conntrack_notifier); -+#endif - #endif -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) - if (result < 0) { - DEBUG_ERROR("Can't register nf notifier hook.\n"); - debugfs_remove_recursive(ecm_conntrack_notifier_dentry); - return result; - } -+#endif - #endif - - return 0; -@@ -448,7 +458,11 @@ void ecm_conntrack_notifier_exit(void) - #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS - nf_conntrack_unregister_chain_notifier(&init_net, &ecm_conntrack_notifier); - #else -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) - nf_conntrack_unregister_notifier(&init_net, &ecm_conntrack_notifier); -+#else -+ nf_conntrack_unregister_notifier(&init_net); -+#endif - #endif - /* - * Remove the debugfs files recursively. --- -2.34.1 - diff --git a/package/qca/nss/qca-nss-ecm-64/patches/008-frontends-drop-use-of-static-be_liberal-and-no_windo.patch b/package/qca/nss/qca-nss-ecm-64/patches/008-frontends-drop-use-of-static-be_liberal-and-no_windo.patch deleted file mode 100644 index c5989cc1b..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/008-frontends-drop-use-of-static-be_liberal-and-no_windo.patch +++ /dev/null @@ -1,156 +0,0 @@ ---- a/frontends/nss/ecm_nss_ported_ipv4.c -+++ b/frontends/nss/ecm_nss_ported_ipv4.c -@@ -125,6 +125,7 @@ - static int ecm_nss_ported_ipv4_accelerated_count[ECM_NSS_PORTED_IPV4_PROTO_MAX] = {0}; - /* Array of Number of TCP and UDP connections currently offloaded */ - -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - /* - * Expose what should be a static flag in the TCP connection tracker. - */ -@@ -132,6 +133,7 @@ - extern int nf_ct_tcp_no_window_check; - #endif - extern int nf_ct_tcp_be_liberal; -+#endif - - /* - * ecm_nss_ported_ipv4_connection_callback() -@@ -372,6 +374,10 @@ - uint8_t dest_mac_xlate[ETH_ALEN]; - ecm_db_direction_t ecm_dir; - ecm_front_end_acceleration_mode_t result_mode; -+#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 12, 0) -+ struct net *net = nf_ct_net(ct); -+ struct nf_tcp_net *tn = nf_tcp_pernet(net); -+#endif - - DEBUG_CHECK_MAGIC(npci, ECM_NSS_PORTED_IPV4_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", npci); - -@@ -1236,9 +1242,17 @@ - nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; - nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; - #ifdef ECM_OPENWRT_SUPPORT -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - if (nf_ct_tcp_be_liberal || nf_ct_tcp_no_window_check - #else -+ if (tn->tcp_be_liberal || tn->tcp_no_window_check -+#endif -+#else -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - if (nf_ct_tcp_be_liberal -+#else -+ if (tn->tcp_be_liberal -+#endif - #endif - || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) - || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { ---- a/frontends/nss/ecm_nss_ported_ipv6.c -+++ b/frontends/nss/ecm_nss_ported_ipv6.c -@@ -125,6 +125,7 @@ - static int ecm_nss_ported_ipv6_accelerated_count[ECM_NSS_PORTED_IPV6_PROTO_MAX] = {0}; - /* Array of Number of TCP and UDP connections currently offloaded */ - -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - /* - * Expose what should be a static flag in the TCP connection tracker. - */ -@@ -132,6 +133,7 @@ - extern int nf_ct_tcp_no_window_check; - #endif - extern int nf_ct_tcp_be_liberal; -+#endif - - /* - * ecm_nss_ported_ipv6_connection_callback() -@@ -376,6 +378,10 @@ - ip_addr_t src_ip; - ip_addr_t dest_ip; - ecm_front_end_acceleration_mode_t result_mode; -+#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 12, 0) -+ struct net *net = nf_ct_net(ct); -+ struct nf_tcp_net *tn = nf_tcp_pernet(net); -+#endif - - DEBUG_CHECK_MAGIC(npci, ECM_NSS_PORTED_IPV6_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", npci); - -@@ -1162,9 +1168,17 @@ - nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; - nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; - #ifdef ECM_OPENWRT_SUPPORT -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - if (nf_ct_tcp_be_liberal || nf_ct_tcp_no_window_check - #else -+ if (tn->tcp_be_liberal || tn->tcp_no_window_check -+#endif -+#else -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - if (nf_ct_tcp_be_liberal -+#else -+ if (tn->tcp_be_liberal -+#endif - #endif - || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) - || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { ---- a/frontends/sfe/ecm_sfe_ported_ipv4.c -+++ b/frontends/sfe/ecm_sfe_ported_ipv4.c -@@ -422,6 +422,10 @@ - int32_t interface_type_counts[ECM_DB_IFACE_TYPE_COUNT]; - bool rule_invalid; - ecm_db_direction_t ecm_dir; -+#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 12, 0) -+ struct net *net = nf_ct_net(ct); -+ struct nf_tcp_net *tn = nf_tcp_pernet(net); -+#endif - ecm_front_end_acceleration_mode_t result_mode; - - DEBUG_CHECK_MAGIC(npci, ECM_SFE_PORTED_IPV4_CONNECTION_INSTANCE_MAGIC, "%px: magic failed", npci); -@@ -1333,9 +1337,17 @@ - nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; - nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; - #ifdef ECM_OPENWRT_SUPPORT -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - if (nf_ct_tcp_be_liberal || nf_ct_tcp_no_window_check - #else -+ if (tn->tcp_be_liberal || tn->tcp_no_window_check) -+#endif -+#else -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - if (nf_ct_tcp_be_liberal -+#else -+ if (tn->tcp_be_liberal) -+#endif - #endif - || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) - || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { ---- a/frontends/sfe/ecm_sfe_ported_ipv6.c -+++ b/frontends/sfe/ecm_sfe_ported_ipv6.c -@@ -426,6 +426,10 @@ - int32_t interface_type_counts[ECM_DB_IFACE_TYPE_COUNT]; - bool rule_invalid; - ip_addr_t src_ip; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) -+ struct net *net = nf_ct_net(ct); -+ struct nf_tcp_net *tn = nf_tcp_pernet(net); -+#endif - ip_addr_t dest_ip; - ecm_front_end_acceleration_mode_t result_mode; - -@@ -1293,9 +1297,17 @@ - nircm->tcp_rule.return_end = ct->proto.tcp.seen[return_dir].td_end; - nircm->tcp_rule.return_max_end = ct->proto.tcp.seen[return_dir].td_maxend; - #ifdef ECM_OPENWRT_SUPPORT -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - if (nf_ct_tcp_be_liberal || nf_ct_tcp_no_window_check - #else -+ if (tn->tcp_be_liberal || tn->tcp_no_window_check) -+#endif -+#else -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) - if (nf_ct_tcp_be_liberal -+#else -+ if (tn->tcp_be_liberal) -+#endif - #endif - || (ct->proto.tcp.seen[flow_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL) - || (ct->proto.tcp.seen[return_dir].flags & IP_CT_TCP_FLAG_BE_LIBERAL)) { diff --git a/package/qca/nss/qca-nss-ecm-64/patches/009-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch b/package/qca/nss/qca-nss-ecm-64/patches/009-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch deleted file mode 100644 index 1bcaa12ef..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/009-ecm_tracker_datagram-drop-static-for-EXPORT_SYMBOL.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 9827d8597545ecfee17eba7b08d48dbcdf55c614 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 8 May 2022 18:39:39 +0200 -Subject: [PATCH 09/12] ecm_tracker_datagram: drop static for EXPORT_SYMBOL - -EXPORT_SYMBOL should NOT be static - -Signed-off-by: Ansuel Smith ---- - ecm_tracker_datagram.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/ecm_tracker_datagram.c b/ecm_tracker_datagram.c -index 9c04d73..ae14146 100644 ---- a/ecm_tracker_datagram.c -+++ b/ecm_tracker_datagram.c -@@ -203,7 +203,7 @@ static void ecm_tracker_datagram_datagram_discard(struct ecm_tracker_datagram_in - * ecm_tracker_datagram_discard_all() - * Discard all tracked data - */ --static void ecm_tracker_datagram_discard_all(struct ecm_tracker_datagram_internal_instance *dtii) -+void ecm_tracker_datagram_discard_all(struct ecm_tracker_datagram_internal_instance *dtii) - { - int32_t src_count; - int32_t dest_count; -@@ -364,7 +364,7 @@ static void ecm_tracker_datagram_datagram_discard_callback(struct ecm_tracker_in - * ecm_tracker_datagram_datagram_size_get() - * Return size in bytes of datagram at index i that was sent to the target - */ --static int32_t ecm_tracker_datagram_datagram_size_get(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i) -+int32_t ecm_tracker_datagram_datagram_size_get(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i) - { - struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; - -@@ -412,7 +412,7 @@ static int32_t ecm_tracker_datagram_datagram_size_get_callback(struct ecm_tracke - * ecm_tracker_datagram_datagram_read() - * Read size bytes from datagram at index i into the buffer - */ --static int ecm_tracker_datagram_datagram_read(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer) -+int ecm_tracker_datagram_datagram_read(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer) - { - struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; - int res; -@@ -466,7 +466,7 @@ static int ecm_tracker_datagram_datagram_read_callback(struct ecm_tracker_instan - * ecm_tracker_datagram_datagram_add() - * Append the datagram onto the tracker queue for the given target - */ --static bool ecm_tracker_datagram_datagram_add(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, struct sk_buff *skb) -+bool ecm_tracker_datagram_datagram_add(struct ecm_tracker_datagram_instance *uti, ecm_tracker_sender_type_t sender, struct sk_buff *skb) - { - struct ecm_tracker_datagram_internal_instance *dtii = (struct ecm_tracker_datagram_internal_instance *)uti; - struct sk_buff *skbc; --- -2.34.1 - diff --git a/package/qca/nss/qca-nss-ecm-64/patches/010-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch b/package/qca/nss/qca-nss-ecm-64/patches/010-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch deleted file mode 100644 index da88eea4c..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/010-frontends-drop-udp_get_timeouts-and-use-standard-ups.patch +++ /dev/null @@ -1,74 +0,0 @@ -From ef638a84405c9f6556a9d7c257ccbba74efd228e Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 14 May 2022 20:15:10 +0200 -Subject: [PATCH 10/12] frontends: drop udp_get_timeouts and use standard - upstream api - -Drop udp_get_timeouts and use nf_udp_pernet and ->timeoutrs -instead or relying on a downstream api not present upstream. ---- - frontends/nss/ecm_nss_ipv4.c | 3 ++- - frontends/nss/ecm_nss_ipv6.c | 3 ++- - frontends/sfe/ecm_sfe_ipv4.c | 3 ++- - frontends/sfe/ecm_sfe_ipv6.c | 3 ++- - 4 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/frontends/nss/ecm_nss_ipv4.c b/frontends/nss/ecm_nss_ipv4.c -index 719a747..558819a 100644 ---- a/frontends/nss/ecm_nss_ipv4.c -+++ b/frontends/nss/ecm_nss_ipv4.c -@@ -607,7 +607,8 @@ sync_conntrack: - #else - timeouts = nf_ct_timeout_lookup(ct); - if (!timeouts) { -- timeouts = udp_get_timeouts(nf_ct_net(ct)); -+ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); -+ timeouts = un->timeouts; - } - - spin_lock_bh(&ct->lock); -diff --git a/frontends/nss/ecm_nss_ipv6.c b/frontends/nss/ecm_nss_ipv6.c -index 67ee364..51eb069 100644 ---- a/frontends/nss/ecm_nss_ipv6.c -+++ b/frontends/nss/ecm_nss_ipv6.c -@@ -586,7 +586,8 @@ sync_conntrack: - #else - timeouts = nf_ct_timeout_lookup(ct); - if (!timeouts) { -- timeouts = udp_get_timeouts(nf_ct_net(ct)); -+ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); -+ timeouts = un->timeouts; - } - - spin_lock_bh(&ct->lock); -diff --git a/frontends/sfe/ecm_sfe_ipv4.c b/frontends/sfe/ecm_sfe_ipv4.c -index 3f30821..931af5d 100644 ---- a/frontends/sfe/ecm_sfe_ipv4.c -+++ b/frontends/sfe/ecm_sfe_ipv4.c -@@ -527,7 +527,8 @@ sync_conntrack: - #else - timeouts = nf_ct_timeout_lookup(ct); - if (!timeouts) { -- timeouts = udp_get_timeouts(nf_ct_net(ct)); -+ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); -+ timeouts = un->timeouts; - } - - spin_lock_bh(&ct->lock); -diff --git a/frontends/sfe/ecm_sfe_ipv6.c b/frontends/sfe/ecm_sfe_ipv6.c -index 54fdbf3..63d8888 100644 ---- a/frontends/sfe/ecm_sfe_ipv6.c -+++ b/frontends/sfe/ecm_sfe_ipv6.c -@@ -516,7 +516,8 @@ sync_conntrack: - #else - timeouts = nf_ct_timeout_lookup(ct); - if (!timeouts) { -- timeouts = udp_get_timeouts(nf_ct_net(ct)); -+ struct nf_udp_net *un = nf_udp_pernet(nf_ct_net(ct)); -+ timeouts = un->timeouts; - } - - spin_lock_bh(&ct->lock); --- -2.34.1 - diff --git a/package/qca/nss/qca-nss-ecm-64/patches/901-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch b/package/qca/nss/qca-nss-ecm-64/patches/901-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch deleted file mode 100644 index 491cbedcc..000000000 --- a/package/qca/nss/qca-nss-ecm-64/patches/901-qca-nss-ecm-fix-a-memcpy-overflow-in-ecm_db.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 1958e34c4c1b8b4fb62eba693fbd7693536947b9 Mon Sep 17 00:00:00 2001 -From: flebourse -Date: Thu, 23 Dec 2021 16:11:06 +0100 -Subject: [PATCH] qca-nss-ecm: fix a memcpy overflow in ecm_db - -Calls to ipv6_addr_prefix() trigger a memcpy overflow if the prefix len -argument is greater than 128, cap it at this value. - -stack bactrace: -detected buffer overflow in memcpy -Kernel BUG at fortify_panic+0x20/0x24 -Internal error: Oops - BUG: 0 [#1] SMP -CPU: 2 PID: 2592 Comm: netifd Not tainted 5.10.80 #0 -Hardware name: Xiaomi AX9000 (DT) -Call trace: - fortify_panic+0x20/0x24 - ecm_db_exit+0x42c/0x49c [ecm] - ecm_db_exit+0x464/0x49c [ecm] - atomic_notifier_call_chain+0x5c/0x90 - ip6_route_add+0x13c/0x1a4 - inet6_rtm_newroute+0x98/0xa0 - rtnetlink_rcv_msg+0x10c/0x34c - netlink_rcv_skb+0x5c/0x130 - rtnetlink_rcv+0x1c/0x2c - netlink_unicast+0x1ec/0x2e0 - netlink_sendmsg+0x1a4/0x394 - ____sys_sendmsg+0x270/0x2b4 - ___sys_sendmsg+0x7c/0xc0 - __sys_sendmsg+0x5c/0xb0 - __arm64_sys_sendmsg+0x28/0x34 - el0_svc_common.constprop.0+0x88/0x190 - do_el0_svc+0x74/0x94 - el0_svc+0x14/0x20 - el0_sync_handler+0xa8/0x130 - el0_sync+0x184/0x1c0 -Code: aa0003e1 912b4040 910003fd 97fff56c (d4210000) - -Signed-off-By: Francis Le Bourse ---- - ecm_db/ecm_db.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ecm_db/ecm_db.c b/ecm_db/ecm_db.c -index c6f408d..df04afd 100644 ---- a/ecm_db/ecm_db.c -+++ b/ecm_db/ecm_db.c -@@ -298,7 +298,7 @@ static int ecm_db_ipv6_route_table_update_event(struct notifier_block *nb, - * Compute ECM connection's prefix destination address by masking it with the - * route config's destination address prefix length. - */ -- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); -+ ipv6_addr_prefix(&prefix_addr, &ecm_in6, min(128, cfg->fc_dst_len)); - - DEBUG_TRACE("dest addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); - -@@ -326,7 +326,7 @@ static int ecm_db_ipv6_route_table_update_event(struct notifier_block *nb, - * Compute ECM connection's prefix source address by masking it with the - * route config's destination address prefix length. - */ -- ipv6_addr_prefix(&prefix_addr, &ecm_in6, cfg->fc_dst_len); -+ ipv6_addr_prefix(&prefix_addr, &ecm_in6, min(128, cfg->fc_dst_len)); - - DEBUG_TRACE("src addr prefix: %pI6 prefix_len: %d ecm_in6: %pI6\n", &prefix_addr, cfg->fc_dst_len, &ecm_in6); - --- -2.1.4 - diff --git a/package/qca/nss/qca-nss-ecm/Makefile b/package/qca/nss/qca-nss-ecm/Makefile deleted file mode 100644 index e7feae369..000000000 --- a/package/qca/nss/qca-nss-ecm/Makefile +++ /dev/null @@ -1,278 +0,0 @@ -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=qca-nss-ecm -PKG_RELEASE:=1 - -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-nss-ecm.git -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 - DEPENDS+=+PACKAGE_kmod-qca-mcs:kmod-qca-mcs -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-mcs),) -ECM_MAKE_OPTS+=ECM_MULTICAST_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/package/qca/nss/qca-nss-ecm/files/ecm_dump.sh b/package/qca/nss/qca-nss-ecm/files/ecm_dump.sh deleted file mode 100644 index dbf7de753..000000000 --- a/package/qca/nss/qca-nss-ecm/files/ecm_dump.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm/files/on-demand-down b/package/qca/nss/qca-nss-ecm/files/on-demand-down deleted file mode 100644 index 02d708e03..000000000 --- a/package/qca/nss/qca-nss-ecm/files/on-demand-down +++ /dev/null @@ -1,6 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.defaults b/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.defaults deleted file mode 100644 index 308e265c9..000000000 --- a/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.defaults +++ /dev/null @@ -1,28 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.firewall b/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.firewall deleted file mode 100644 index 24c64def2..000000000 --- a/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.firewall +++ /dev/null @@ -1,18 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.init b/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.init deleted file mode 100644 index 0d58c3599..000000000 --- a/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.init +++ /dev/null @@ -1,133 +0,0 @@ -#!/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/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.sysctl b/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.sysctl deleted file mode 100644 index 1a3d76b18..000000000 --- a/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.sysctl +++ /dev/null @@ -1,2 +0,0 @@ -# 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/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.uci b/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.uci deleted file mode 100644 index 4f2de6877..000000000 --- a/package/qca/nss/qca-nss-ecm/files/qca-nss-ecm.uci +++ /dev/null @@ -1,2 +0,0 @@ -config ecm 'global' - option acceleration_engine 'auto' diff --git a/package/qca/nss/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch b/package/qca/nss/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch deleted file mode 100644 index b1cd2b7b1..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/001-Drop_SFE_from_ecm.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- 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/package/qca/nss/qca-nss-ecm/patches/100-kernel-5.4-support.patch b/package/qca/nss/qca-nss-ecm/patches/100-kernel-5.4-support.patch deleted file mode 100644 index b863ad7e0..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/100-kernel-5.4-support.patch +++ /dev/null @@ -1,1276 +0,0 @@ ---- 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/package/qca/nss/qca-nss-ecm/patches/101-Fix_Kern_Panic_on_UDP_CONNTRACK.patch b/package/qca/nss/qca-nss-ecm/patches/101-Fix_Kern_Panic_on_UDP_CONNTRACK.patch deleted file mode 100644 index 6633f72b4..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/101-Fix_Kern_Panic_on_UDP_CONNTRACK.patch +++ /dev/null @@ -1,60 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/200-resolve-high-load.patch b/package/qca/nss/qca-nss-ecm/patches/200-resolve-high-load.patch deleted file mode 100644 index 2f39d2770..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/200-resolve-high-load.patch +++ /dev/null @@ -1,44 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/203-rework-nfct-notification.patch b/package/qca/nss/qca-nss-ecm/patches/203-rework-nfct-notification.patch deleted file mode 100644 index a0e09c1fa..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/203-rework-nfct-notification.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- 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/package/qca/nss/qca-nss-ecm/patches/400-Check-TCP_UDP-conntrack-state-earlier.patch b/package/qca/nss/qca-nss-ecm/patches/400-Check-TCP_UDP-conntrack-state-earlier.patch deleted file mode 100644 index b7882c1b3..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/400-Check-TCP_UDP-conntrack-state-earlier.patch +++ /dev/null @@ -1,236 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/401-Fix-NSS-stats-request-roll-over-issue.patch b/package/qca/nss/qca-nss-ecm/patches/401-Fix-NSS-stats-request-roll-over-issue.patch deleted file mode 100644 index 217054bb7..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/401-Fix-NSS-stats-request-roll-over-issue.patch +++ /dev/null @@ -1,52 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/401-Fix-for-ref-leak-during-multicast.patch b/package/qca/nss/qca-nss-ecm/patches/401-Fix-for-ref-leak-during-multicast.patch deleted file mode 100644 index e1df653b7..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/401-Fix-for-ref-leak-during-multicast.patch +++ /dev/null @@ -1,112 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/401-Fix-neighbour-solicitation-send-function.patch b/package/qca/nss/qca-nss-ecm/patches/401-Fix-neighbour-solicitation-send-function.patch deleted file mode 100644 index 7d32d6fd5..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/401-Fix-neighbour-solicitation-send-function.patch +++ /dev/null @@ -1,33 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/402-Reference-leak-during-multicast_PPPoE-bridge.patch b/package/qca/nss/qca-nss-ecm/patches/402-Reference-leak-during-multicast_PPPoE-bridge.patch deleted file mode 100644 index 97ce7a7e8..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/402-Reference-leak-during-multicast_PPPoE-bridge.patch +++ /dev/null @@ -1,260 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/403-Access-global-accelerated-count-under-lock.patch b/package/qca/nss/qca-nss-ecm/patches/403-Access-global-accelerated-count-under-lock.patch deleted file mode 100644 index d458e1134..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/403-Access-global-accelerated-count-under-lock.patch +++ /dev/null @@ -1,59 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/403-Fix-IPv6-neighbor-solicitation-request.patch b/package/qca/nss/qca-nss-ecm/patches/403-Fix-IPv6-neighbor-solicitation-request.patch deleted file mode 100644 index 7639b88a0..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/403-Fix-IPv6-neighbor-solicitation-request.patch +++ /dev/null @@ -1,83 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/404-IPv6-solicitation-fix-with-zero-gateway-address.patch b/package/qca/nss/qca-nss-ecm/patches/404-IPv6-solicitation-fix-with-zero-gateway-address.patch deleted file mode 100644 index bdedff442..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/404-IPv6-solicitation-fix-with-zero-gateway-address.patch +++ /dev/null @@ -1,63 +0,0 @@ -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/package/qca/nss/qca-nss-ecm/patches/405-Allow-egress-on-same-port-when-bridge-hairpin-is-enabled.patch b/package/qca/nss/qca-nss-ecm/patches/405-Allow-egress-on-same-port-when-bridge-hairpin-is-enabled.patch deleted file mode 100644 index a236fb757..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/405-Allow-egress-on-same-port-when-bridge-hairpin-is-enabled.patch +++ /dev/null @@ -1,126 +0,0 @@ -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/package/qca/nss/qca-nss-gmac/Makefile b/package/qca/nss/qca-nss-gmac/Makefile deleted file mode 100644 index 6c06d8198..000000000 --- a/package/qca/nss/qca-nss-gmac/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=qca-nss-gmac -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-gmac.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 @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/package/qca/nss/qca-nss-gmac/patches/100-kernel-5.4-support.patch b/package/qca/nss/qca-nss-gmac/patches/100-kernel-5.4-support.patch deleted file mode 100644 index f3b91abc2..000000000 --- a/package/qca/nss/qca-nss-gmac/patches/100-kernel-5.4-support.patch +++ /dev/null @@ -1,279 +0,0 @@ ---- 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/package/qca/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch b/package/qca/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch deleted file mode 100644 index a5bff16bd..000000000 --- a/package/qca/nss/qca-nss-gmac/patches/101-nss-gmac-test-ptr.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/ipq806x/nss_gmac_ctrl.c -+++ b/ipq806x/nss_gmac_ctrl.c -@@ -957,7 +957,8 @@ static int32_t nss_gmac_of_get_pdata(struct device_node *np, - struct net_device *netdev, - struct msm_nss_gmac_platform_data *gmaccfg) - { -- uint8_t *maddr = NULL; -+ int ret; -+ u8 maddr[ETH_ALEN]; - struct nss_gmac_dev *gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev); - struct resource memres_devtree = {0}; - -@@ -991,9 +992,9 @@ static int32_t nss_gmac_of_get_pdata(struct device_node *np, - pr_err("%s: Can't map interrupt\n", np->name); - return -EFAULT; - } -- maddr = (uint8_t *)of_get_mac_address(np); -- if (maddr) -- memcpy(gmaccfg->mac_addr, maddr, ETH_ALEN); -+ ret = of_get_mac_address(np, maddr); -+ if (!ret && is_valid_ether_addr(maddr)) -+ ether_addr_copy(gmaccfg->mac_addr, maddr); - - if (of_address_to_resource(np, 0, &memres_devtree) != 0) - return -EFAULT; diff --git a/package/qca/nss/qca-nss-gmac/patches/200-work-around-interface-close-warning.patch b/package/qca/nss/qca-nss-gmac/patches/200-work-around-interface-close-warning.patch deleted file mode 100644 index 7cb6d6fac..000000000 --- a/package/qca/nss/qca-nss-gmac/patches/200-work-around-interface-close-warning.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- 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/package/qca/qca-mcs/Makefile b/package/qca/qca-mcs/Makefile deleted file mode 100644 index 22783c002..000000000 --- a/package/qca/qca-mcs/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-mcs -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2021-10-28 -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-mcs.git -PKG_SOURCE_VERSION:=31f5cd4b83da5a7c0fdca240b4e72677e4523b6e -PKG_MIRROR_HASH:=3e2e25025dc2e771aafe7d8b12f26ac831d123b34bdd7b7e84bd39c1e933491d - -include $(INCLUDE_DIR)/kernel.mk -include $(INCLUDE_DIR)/package.mk - -define KernelPackage/qca-mcs - SECTION:=kernel - CATEGORY:=Kernel modules - SUBMENU:=Network Support - TITLE:=QCA Multicast Snooping Support - DEPENDS:=@(TARGET_ipq806x||TARGET_ipq807x) - KCONFIG:= \ - CONFIG_NETFILTER=y \ - CONFIG_BRIDGE_NETFILTER=y - FILES:=$(PKG_BUILD_DIR)/qca-mcs.ko - AUTOLOAD:=$(call AutoLoad,52,qca-mcs) -endef - -define KernelPackage/qca-mcs/description - This package installs the IGMP/MLD Snooping Module -endef - -QCA_MC_SNOOPING_HEADERS= \ - $(PKG_BUILD_DIR)/mc_api.h \ - $(PKG_BUILD_DIR)/mc_ecm.h \ - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include/qca-mcs - $(foreach header_file,$(QCA_MC_SNOOPING_HEADERS), $(CP) $(header_file) $(1)/usr/include/qca-mcs;) - $(foreach header_file,$(QCA_MC_SNOOPING_HEADERS), $(CP) $(header_file) $(1)/usr/include/;) -endef - -QCA_MC_SNOOPING_MAKE_OPTS:= \ - $(KERNEL_MAKE_FLAGS) \ - CONFIG_SUPPORT_MLD=y \ - MDIR=$(PKG_BUILD_DIR) \ - KBUILDPATH=$(LINUX_DIR) \ - KERNELPATH=$(LINUX_SRC_DIR) \ - KERNELRELEASE=$(LINUX_RELEASE) - -define Build/Compile - $(MAKE) -C $(LINUX_DIR) M=$(PKG_BUILD_DIR) $(strip $(QCA_MC_SNOOPING_MAKE_OPTS)) -endef - -$(eval $(call KernelPackage,qca-mcs)) diff --git a/package/qca/nss/qca-nss-dp/Makefile b/package/qca/qca-nss-dp/Makefile similarity index 50% rename from package/qca/nss/qca-nss-dp/Makefile rename to package/qca/qca-nss-dp/Makefile index 7bea14c70..c029f1ffb 100644 --- a/package/qca/nss/qca-nss-dp/Makefile +++ b/package/qca/qca-nss-dp/Makefile @@ -1,15 +1,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qca-nss-dp -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=2 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2022-04-30 -PKG_SOURCE_VERSION:=72e9ec4187414461cbcf6ccff100e8b5ebe5f40b -PKG_MIRROR_HASH:=805f16e59c75511132922f97740ebf6bf953845b0bbfd2089c4615456893bb37 +PKG_SOURCE_DATE:=2023-06-06 +PKG_SOURCE_VERSION:=fa67464466f69f00967cc373d1bdd6025f57eb89 +PKG_MIRROR_HASH:=51bf524382a5cb542c2c80d12a91f87b9736de3ac3c1d4a351c97b3502d68574 PKG_BUILD_PARALLEL:=1 +PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/kernel.mk include $(INCLUDE_DIR)/package.mk @@ -18,14 +19,14 @@ 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 + DEPENDS:=@TARGET_qualcommax +kmod-qca-ssdk + TITLE:=Qualcom NSS dataplane ethernet driver FILES:=$(PKG_BUILD_DIR)/qca-nss-dp.ko - AUTOLOAD:=$(call AutoLoad,31,qca-nss-dp) + AUTOLOAD:=$(call AutoLoad,31,qca-nss-dp,1) endef define KernelPackage/qca-nss-dp/Description -This package contains a NSS data plane driver for QCA chipset + NSS dataplane ethernet driver for Qualcom SoCs. endef define Build/InstallDev @@ -38,24 +39,16 @@ EXTRA_CFLAGS+= \ NSS_DP_HAL_DIR:=$(PKG_BUILD_DIR)/hal define Build/Configure - $(LN) $(NSS_DP_HAL_DIR)/soc_ops/$(CONFIG_TARGET_BOARD)/nss_$(CONFIG_TARGET_BOARD).h \ + $(LN) $(NSS_DP_HAL_DIR)/soc_ops/$(CONFIG_TARGET_SUBTARGET)/nss_$(CONFIG_TARGET_SUBTARGET).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)" \ + +$(KERNEL_MAKE) $(PKG_JOBS) \ + -C "$(LINUX_DIR)" \ M="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(CONFIG_TARGET_BOARD)" \ - $(KERNEL_MAKE_FLAGS) \ - $(PKG_JOBS) \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + SoC="$(CONFIG_TARGET_SUBTARGET)" \ modules endef diff --git a/package/qca/qca-nss-dp/patches/0001-nss-dp-Drop-_nocache-variants-of-ioremap.patch b/package/qca/qca-nss-dp/patches/0001-nss-dp-Drop-_nocache-variants-of-ioremap.patch new file mode 100644 index 000000000..c998874d4 --- /dev/null +++ b/package/qca/qca-nss-dp/patches/0001-nss-dp-Drop-_nocache-variants-of-ioremap.patch @@ -0,0 +1,48 @@ +From 946381fd6fdabedf2b5a1d8647a49e3da8f1894e Mon Sep 17 00:00:00 2001 +From: Baruch Siach +Date: Fri, 23 Jun 2023 11:28:02 +0200 +Subject: [PATCH 1/8] nss-dp: Drop _nocache variants of ioremap() + +ioremap_nocache was made equivelant to ioremap and was dropped. + +Signed-off-by: Baruch Siach +Signed-off-by: Robert Marko +--- + hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 2 +- + hal/gmac_ops/syn/gmac/syn_if.c | 2 +- + hal/soc_ops/ipq50xx/nss_ipq50xx.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c ++++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c +@@ -279,7 +279,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_ops/syn/gmac/syn_if.c ++++ b/hal/gmac_ops/syn/gmac/syn_if.c +@@ -806,7 +806,7 @@ static void *syn_init(struct nss_gmac_ha + * 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"); +--- a/hal/soc_ops/ipq50xx/nss_ipq50xx.c ++++ b/hal/soc_ops/ipq50xx/nss_ipq50xx.c +@@ -89,7 +89,7 @@ static void nss_dp_hal_tcsr_set(void) + pr_err("%s: SCM TCSR write error: %d\n", __func__, err); + } + } else { +- tcsr_addr = ioremap_nocache((tcsr_base + TCSR_GMAC_AXI_CACHE_OVERRIDE_OFFSET), ++ tcsr_addr = ioremap((tcsr_base + TCSR_GMAC_AXI_CACHE_OVERRIDE_OFFSET), + TCSR_GMAC_AXI_CACHE_OVERRIDE_REG_SIZE); + if (!tcsr_addr) { + pr_err("%s: ioremap failed\n", __func__); diff --git a/package/qca/nss/qca-nss-dp/patches/0001-edma_tx_rx-support-newer-kernels-time-stamping-API.patch b/package/qca/qca-nss-dp/patches/0002-edma_tx_rx-support-newer-kernels-time-stamping-API.patch similarity index 82% rename from package/qca/nss/qca-nss-dp/patches/0001-edma_tx_rx-support-newer-kernels-time-stamping-API.patch rename to package/qca/qca-nss-dp/patches/0002-edma_tx_rx-support-newer-kernels-time-stamping-API.patch index 1fed4ba8a..d84e9a98d 100644 --- a/package/qca/nss/qca-nss-dp/patches/0001-edma_tx_rx-support-newer-kernels-time-stamping-API.patch +++ b/package/qca/qca-nss-dp/patches/0002-edma_tx_rx-support-newer-kernels-time-stamping-API.patch @@ -1,9 +1,12 @@ -From 40979666b4371012405715ffa61ab5760fcdc6b3 Mon Sep 17 00:00:00 2001 -Message-Id: <40979666b4371012405715ffa61ab5760fcdc6b3.1620066716.git.baruch@tkos.co.il> +From 3357c64b3fc63fe003d5ef02ba7f6abca64d80bf Mon Sep 17 00:00:00 2001 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 +Subject: [PATCH 2/8] edma_tx_rx: support newer kernels time stamping API +Timestamping API has changed in kernel 5.6, so update the implementation +for newer kernels. + +Signed-off-by: Baruch Siach --- hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/package/qca/nss/qca-nss-dp/patches/0004-EDMA-Fix-NAPI-packet-counting.patch b/package/qca/qca-nss-dp/patches/0003-EDMA-Fix-NAPI-packet-counting.patch similarity index 88% rename from package/qca/nss/qca-nss-dp/patches/0004-EDMA-Fix-NAPI-packet-counting.patch rename to package/qca/qca-nss-dp/patches/0003-EDMA-Fix-NAPI-packet-counting.patch index f7653729a..a2268010d 100644 --- a/package/qca/nss/qca-nss-dp/patches/0004-EDMA-Fix-NAPI-packet-counting.patch +++ b/package/qca/qca-nss-dp/patches/0003-EDMA-Fix-NAPI-packet-counting.patch @@ -1,7 +1,7 @@ -From d74920e2a7c413ef40eed72f9cf287cf6fbd5fb8 Mon Sep 17 00:00:00 2001 +From c36420c219bf0e03842a11f69193c802eb42030a 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 +Subject: [PATCH 3/8] EDMA: Fix NAPI packet counting There is a bug in the NAPI packet counting that will cause NAPI over budget warnings. diff --git a/package/qca/nss/qca-nss-dp/patches/0005-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch b/package/qca/qca-nss-dp/patches/0004-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch similarity index 87% rename from package/qca/nss/qca-nss-dp/patches/0005-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch rename to package/qca/qca-nss-dp/patches/0004-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch index 9c22fa790..84fb02a92 100644 --- a/package/qca/nss/qca-nss-dp/patches/0005-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch +++ b/package/qca/qca-nss-dp/patches/0004-EDMA-Use-NAPI_POLL_WEIGHT-as-NAPI-weight.patch @@ -1,7 +1,7 @@ -From 44a30d94abcbb10aacc21db29be212518a6b1bf7 Mon Sep 17 00:00:00 2001 +From 158032d3d4e5089afa2aa38c27c6e222ac427820 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 +Subject: [PATCH 4/8] 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 @@ -20,7 +20,7 @@ Signed-off-by: Robert Marko --- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c +++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c -@@ -837,7 +837,7 @@ static int edma_register_netdevice(struc +@@ -845,7 +845,7 @@ static int edma_register_netdevice(struc */ if (!edma_hw.napi_added) { netif_napi_add(netdev, &edma_hw.napi, edma_napi, diff --git a/package/qca/qca-nss-dp/patches/0005-nss-dp-adapt-to-netif_napi_add-changes.patch b/package/qca/qca-nss-dp/patches/0005-nss-dp-adapt-to-netif_napi_add-changes.patch new file mode 100644 index 000000000..d5b0f6247 --- /dev/null +++ b/package/qca/qca-nss-dp/patches/0005-nss-dp-adapt-to-netif_napi_add-changes.patch @@ -0,0 +1,46 @@ +From e46c4d526d77916c00fff4fff3237b9c9d0d774d Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 23 Jun 2023 12:04:11 +0200 +Subject: [PATCH 5/8] nss-dp: adapt to netif_napi_add() changes + +netif_napi_add() removed the weight argument and just uses the default +NAPI_POLL_WEIGHT in background, so for those requiring custom weight use +netif_napi_add_weight() instead. + +Signed-off-by: Robert Marko +--- + hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 4 ++++ + hal/dp_ops/syn_gmac_dp/syn_dp.c | 5 +++++ + 2 files changed, 9 insertions(+) + +--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c ++++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c +@@ -844,8 +844,12 @@ static int edma_register_netdevice(struc + * NAPI add + */ + if (!edma_hw.napi_added) { ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) + netif_napi_add(netdev, &edma_hw.napi, edma_napi, + NAPI_POLL_WEIGHT); ++#else ++ netif_napi_add(netdev, &edma_hw.napi, edma_napi); ++#endif + /* + * Register the interrupt handlers and enable interrupts + */ +--- a/hal/dp_ops/syn_gmac_dp/syn_dp.c ++++ b/hal/dp_ops/syn_gmac_dp/syn_dp.c +@@ -189,8 +189,13 @@ static int syn_dp_if_init(struct nss_dp_ + } + + if (!dev_info->napi_added) { ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) + netif_napi_add(netdev, &rx_info->napi_rx, syn_dp_napi_poll_rx, SYN_DP_NAPI_BUDGET_RX); + netif_napi_add(netdev, &tx_info->napi_tx, syn_dp_napi_poll_tx, SYN_DP_NAPI_BUDGET_TX); ++#else ++ netif_napi_add_weight(netdev, &rx_info->napi_rx, syn_dp_napi_poll_rx, SYN_DP_NAPI_BUDGET_RX); ++ netif_napi_add_weight(netdev, &tx_info->napi_tx, syn_dp_napi_poll_tx, SYN_DP_NAPI_BUDGET_TX); ++#endif + + /* + * Requesting irq. Set IRQ_DISABLE_UNLAZY flag, this flag diff --git a/package/qca/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch b/package/qca/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch new file mode 100644 index 000000000..0432b82dd --- /dev/null +++ b/package/qca/qca-nss-dp/patches/0006-nss_dp_main-Use-a-phy-handle-property-to-connect-to-.patch @@ -0,0 +1,180 @@ +From 5b05b1d7a2d2001d9711856608f61abaf7b9a9a5 Mon Sep 17 00:00:00 2001 +From: Alexandru Gagniuc +Date: Fri, 23 Jun 2023 13:34:56 +0200 +Subject: [PATCH 6/8] nss_dp_main: Use a 'phy-handle' property to connect to + the PHY + +The original method of connecting a PHY to the ethernet controller +requires the "qcom,link-poll", and "qcom,phy-mdio-addr" devicetree +properties. This is redundant. The PHY node already contains the MDIO +address, and attaching a PHY implies "link-poll". + +Allow using a "phy-handle" property. Remove the following properties, +as they are no longer used: + * "qcom,link-poll" + * "qcom,phy-mdio-addr" + * "mdio-bus" + * "qcom,forced-speed" + * "qcom,forced-duplex" + +Signed-off-by: Alexandru Gagniuc +Signed-off-by: Robert Marko +--- + include/nss_dp_dev.h | 5 +-- + nss_dp_main.c | 91 +++++++------------------------------------- + 2 files changed, 14 insertions(+), 82 deletions(-) + +--- a/include/nss_dp_dev.h ++++ b/include/nss_dp_dev.h +@@ -202,13 +202,10 @@ struct nss_dp_dev { + unsigned long drv_flags; /* Driver specific feature flags */ + + /* Phy related stuff */ ++ struct device_node *phy_node; /* Phy device OF node */ + struct phy_device *phydev; /* Phy device */ + struct mii_bus *miibus; /* MII bus */ + uint32_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? */ +- uint32_t forced_duplex; /* Forced duplex? */ + uint32_t link_state; /* Current link state */ + uint32_t pause; /* Current flow control settings */ + +--- a/nss_dp_main.c ++++ b/nss_dp_main.c +@@ -418,7 +418,7 @@ static int nss_dp_open(struct net_device + + netif_start_queue(netdev); + +- if (!dp_priv->link_poll) { ++ if (!dp_priv->phydev) { + /* Notify data plane link is up */ + if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 1)) { + netdev_dbg(netdev, "Data plane set link failed\n"); +@@ -615,6 +615,12 @@ static int32_t nss_dp_of_get_pdata(struc + return -EFAULT; + } + ++ dp_priv->phy_node = of_parse_phandle(np, "phy-handle", 0); ++ if (!dp_priv->phy_node) { ++ pr_err("%s: error parsing phy-handle\n", np->name); ++ return -EFAULT; ++ } ++ + if (of_property_read_u32(np, "qcom,mactype", &hal_pdata->mactype)) { + pr_err("%s: error reading mactype\n", np->name); + return -EFAULT; +@@ -635,18 +641,6 @@ static int32_t nss_dp_of_get_pdata(struc + return -EFAULT; + #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) { +- pr_err("%s: mdio addr required if link polling is enabled\n", +- np->name); +- return -EFAULT; +- } +- +- of_property_read_u32(np, "qcom,forced-speed", &dp_priv->forced_speed); +- of_property_read_u32(np, "qcom,forced-duplex", &dp_priv->forced_duplex); +- +- + #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) + maddr = (uint8_t *)of_get_mac_address(np); + #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0)) +@@ -695,56 +689,6 @@ static int32_t nss_dp_of_get_pdata(struc + return 0; + } + +-/* +- * nss_dp_mdio_attach() +- */ +-static struct mii_bus *nss_dp_mdio_attach(struct platform_device *pdev) +-{ +- struct device_node *mdio_node; +- struct platform_device *mdio_plat; +-#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,1,0)) +- struct ipq40xx_mdio_data *mdio_data; +-#endif +- +- /* +- * Find mii_bus using "mdio-bus" handle. +- */ +- mdio_node = of_parse_phandle(pdev->dev.of_node, "mdio-bus", 0); +- if (mdio_node) { +- return of_mdio_find_bus(mdio_node); +- } +- +- mdio_node = of_find_compatible_node(NULL, NULL, "qcom,qca-mdio"); +- if (!mdio_node) { +- mdio_node = of_find_compatible_node(NULL, NULL, +- "qcom,ipq40xx-mdio"); +- if (!mdio_node) { +- dev_err(&pdev->dev, "cannot find mdio node by phandle\n"); +- return NULL; +- } +- } +- +- mdio_plat = of_find_device_by_node(mdio_node); +- if (!mdio_plat) { +- dev_err(&pdev->dev, "cannot find platform device from mdio node\n"); +- of_node_put(mdio_node); +- return NULL; +- } +- +-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)) +- return dev_get_drvdata(&mdio_plat->dev); +-#else +- mdio_data = dev_get_drvdata(&mdio_plat->dev); +- if (!mdio_data) { +- dev_err(&pdev->dev, "cannot get mii bus reference from device data\n"); +- of_node_put(mdio_node); +- return NULL; +- } +- +- return mdio_data->mii_bus; +-#endif +-} +- + #ifdef CONFIG_NET_SWITCHDEV + /* + * nss_dp_is_phy_dev() +@@ -803,7 +747,6 @@ static int32_t nss_dp_probe(struct platf + struct device_node *np = pdev->dev.of_node; + struct nss_gmac_hal_platform_data gmac_hal_pdata; + int32_t ret = 0; +- uint8_t phy_id[MII_BUS_ID_SIZE + 3]; + #if defined(NSS_DP_PPE_SUPPORT) + uint32_t vsi_id; + fal_port_t port_id; +@@ -880,22 +823,14 @@ static int32_t nss_dp_probe(struct platf + + dp_priv->drv_flags |= NSS_DP_PRIV_FLAG(INIT_DONE); + +- if (dp_priv->link_poll) { +- dp_priv->miibus = nss_dp_mdio_attach(pdev); +- if (!dp_priv->miibus) { +- netdev_dbg(netdev, "failed to find miibus\n"); +- goto phy_setup_fail; +- } +- snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, +- dp_priv->miibus->id, dp_priv->phy_mdio_addr); +- ++ if (dp_priv->phy_node) { + SET_NETDEV_DEV(netdev, &pdev->dev); + +- dp_priv->phydev = phy_connect(netdev, phy_id, +- &nss_dp_adjust_link, +- dp_priv->phy_mii_type); +- if (IS_ERR(dp_priv->phydev)) { +- netdev_dbg(netdev, "failed to connect to phy device\n"); ++ dp_priv->phydev = of_phy_connect(netdev, dp_priv->phy_node, ++ &nss_dp_adjust_link, 0, ++ dp_priv->phy_mii_type); ++ if (!(dp_priv->phydev)) { ++ netdev_err(netdev, "failed to connect to phy device\n"); + goto phy_setup_fail; + } + } diff --git a/package/qca/nss/qca-nss-dp/patches/0014-nss-dp-edma-v1-use-NAPI-GRO-by-default.patch b/package/qca/qca-nss-dp/patches/0007-nss-dp-edma-v1-use-NAPI-GRO-by-default.patch similarity index 76% rename from package/qca/nss/qca-nss-dp/patches/0014-nss-dp-edma-v1-use-NAPI-GRO-by-default.patch rename to package/qca/qca-nss-dp/patches/0007-nss-dp-edma-v1-use-NAPI-GRO-by-default.patch index 3683b4ec4..6fbe75dc1 100644 --- a/package/qca/nss/qca-nss-dp/patches/0014-nss-dp-edma-v1-use-NAPI-GRO-by-default.patch +++ b/package/qca/qca-nss-dp/patches/0007-nss-dp-edma-v1-use-NAPI-GRO-by-default.patch @@ -1,7 +1,7 @@ -From ae4fe8fb79b68f4cf4a887434ab6a8a9a1c65bfc Mon Sep 17 00:00:00 2001 +From c2df713569fe3bb671d1444c7bf758681081053c Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Thu, 23 Jun 2022 14:18:50 +0200 -Subject: [PATCH] nss-dp: edma-v1: use NAPI GRO by default +Subject: [PATCH 7/8] nss-dp: edma-v1: use NAPI GRO by default Utilize napi_gro_receive instead of plain netif_receive_skb on EDMA v1. @@ -18,11 +18,9 @@ Signed-off-by: Robert Marko hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c | 8 ++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) -diff --git a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c -index 1d748db..e81c461 100644 --- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c +++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c -@@ -589,10 +589,12 @@ drop: +@@ -597,10 +597,12 @@ drop: */ static void edma_if_set_features(struct nss_dp_data_plane_ctx *dpc) { @@ -39,11 +37,9 @@ index 1d748db..e81c461 100644 } /* TODO - check if this is needed */ -diff --git a/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c b/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c -index 5780a30..a002a79 100644 --- a/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c +++ b/hal/dp_ops/edma_dp/edma_v1/edma_tx_rx.c -@@ -410,8 +410,12 @@ static uint32_t edma_clean_rx(struct edma_hw *ehw, +@@ -410,8 +410,12 @@ static uint32_t edma_clean_rx(struct edm if (unlikely(EDMA_RXPH_SERVICE_CODE_GET(rxph) == NSS_PTP_EVENT_SERVICE_CODE)) nss_phy_tstamp_rx_buf(ndev, skb); @@ -58,6 +54,3 @@ index 5780a30..a002a79 100644 next_rx_desc: /* --- -2.38.1 - diff --git a/package/qca/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch b/package/qca/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch new file mode 100644 index 000000000..e90bf32ce --- /dev/null +++ b/package/qca/qca-nss-dp/patches/0008-nss-dp-allow-setting-netdev-name-from-DTS.patch @@ -0,0 +1,50 @@ +From 53b044f7a21d5cd65ada90a228910e6efbad00fa Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sun, 4 Dec 2022 18:41:36 +0100 +Subject: [PATCH 8/8] nss-dp: allow setting netdev name from DTS + +Allow reading the desired netdev name from DTS like DSA allows and then +set it as the netdev name during registration. + +If label is not defined, simply fallback to kernel ethN enumeration. + +Signed-off-by: Robert Marko +--- + nss_dp_main.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +--- a/nss_dp_main.c ++++ b/nss_dp_main.c +@@ -746,18 +746,29 @@ static int32_t nss_dp_probe(struct platf + struct nss_dp_dev *dp_priv; + struct device_node *np = pdev->dev.of_node; + struct nss_gmac_hal_platform_data gmac_hal_pdata; ++ const char *name = of_get_property(np, "label", NULL); + int32_t ret = 0; ++ int assign_type; + #if defined(NSS_DP_PPE_SUPPORT) + uint32_t vsi_id; + fal_port_t port_id; + #endif + ++ if (name) { ++ assign_type = NET_NAME_PREDICTABLE; ++ } else { ++ name = "eth%d"; ++ assign_type = NET_NAME_ENUM; ++ } ++ + /* TODO: See if we need to do some SoC level common init */ + +- netdev = alloc_etherdev_mqs(sizeof(struct nss_dp_dev), +- NSS_DP_NETDEV_TX_QUEUE_NUM, NSS_DP_NETDEV_RX_QUEUE_NUM); ++ netdev = alloc_netdev_mqs(sizeof(struct nss_dp_dev), ++ name, assign_type, ++ ether_setup, ++ NSS_DP_NETDEV_TX_QUEUE_NUM, NSS_DP_NETDEV_RX_QUEUE_NUM); + if (!netdev) { +- pr_info("alloc_etherdev() failed\n"); ++ dev_err(&pdev->dev, "alloc_netdev_mqs() failed\n"); + return -ENOMEM; + } + diff --git a/package/qca/nss/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch b/package/qca/qca-nss-dp/patches/0009-nss-dp-switchdev-fix-FDB-roaming.patch similarity index 65% rename from package/qca/nss/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch rename to package/qca/qca-nss-dp/patches/0009-nss-dp-switchdev-fix-FDB-roaming.patch index 19395ac42..ec10bdc2d 100644 --- a/package/qca/nss/qca-nss-dp/patches/0010-switchdev-fix-FDB-roaming.patch +++ b/package/qca/qca-nss-dp/patches/0009-nss-dp-switchdev-fix-FDB-roaming.patch @@ -1,7 +1,7 @@ -From d16102cad769f430144ca8094d928762b445e9b0 Mon Sep 17 00:00:00 2001 +From 25ca3308edb67aa0c6c70b83edf0e22b8ae7533f Mon Sep 17 00:00:00 2001 From: Robert Marko -Date: Fri, 18 Mar 2022 22:02:01 +0100 -Subject: [PATCH] switchdev: fix FDB roaming +Date: Thu, 29 Jun 2023 13:52:58 +0200 +Subject: [PATCH] nss-dp: switchdev: fix FDB roaming Try and solve the roaming issue by trying to replicate what NSS bridge module is doing, but by utilizing switchdev FDB notifiers instead of @@ -17,12 +17,12 @@ notification provided MAC adress existing FDB entry gets removed. Signed-off-by: Robert Marko --- - nss_dp_switchdev.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 61 insertions(+) + nss_dp_switchdev.c | 73 +++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 72 insertions(+), 1 deletion(-) --- a/nss_dp_switchdev.c +++ b/nss_dp_switchdev.c -@@ -24,6 +24,8 @@ +@@ -29,6 +29,8 @@ #include "nss_dp_dev.h" #include "fal/fal_stp.h" #include "fal/fal_ctrlpkt.h" @@ -31,10 +31,18 @@ Signed-off-by: Robert Marko #define NSS_DP_SWITCH_ID 0 #define NSS_DP_SW_ETHTYPE_PID 0 /* PPE ethtype profile ID for slow protocols */ -@@ -348,10 +350,64 @@ static int nss_dp_switchdev_event(struct - return NOTIFY_DONE; - } +@@ -521,7 +523,76 @@ static struct notifier_block *nss_dp_sw_ + #else + +-static struct notifier_block *nss_dp_sw_ev_nb; ++/* ++ * nss_dp_switchdev_fdb_del_event ++ * ++ * Used for EDMA v1 to remove old MAC in order to preventing having ++ * duplicate MAC entries in FDB thus and avoid roaming issues. ++ */ ++ +static int nss_dp_switchdev_fdb_del_event(struct net_device *netdev, + struct switchdev_notifier_fdb_info *fdb_info) +{ @@ -65,8 +73,14 @@ Signed-off-by: Robert Marko + return notifier_from_errno(rv); +} + -+static int nss_dp_fdb_switchdev_event(struct notifier_block *nb, -+ unsigned long event, void *ptr) ++/* ++ * nss_dp_switchdev_event_nb ++ * ++ * Non blocking switchdev event for netdevice. ++ * Used for EDMA v1 to remove old MAC and avoid roaming issues. ++ */ ++static int nss_dp_switchdev_event_nb(struct notifier_block *unused, ++ unsigned long event, void *ptr) +{ + struct net_device *dev = switchdev_notifier_info_to_dev(ptr); + @@ -80,31 +94,18 @@ Signed-off-by: Robert Marko + switch (event) { + case SWITCHDEV_FDB_DEL_TO_DEVICE: + return nss_dp_switchdev_fdb_del_event(dev, ptr); ++ default: ++ netdev_dbg(dev, "Switchdev event %lu is not supported\n", event); + } + + return NOTIFY_DONE; +} + - static struct notifier_block nss_dp_switchdev_notifier = { - .notifier_call = nss_dp_switchdev_event, - }; - -+static struct notifier_block nss_dp_switchdev_fdb_notifier = { -+ .notifier_call = nss_dp_fdb_switchdev_event, ++static struct notifier_block nss_dp_switchdev_notifier_nb = { ++ .notifier_call = nss_dp_switchdev_event_nb, +}; + - static bool switch_init_done; ++static struct notifier_block *nss_dp_sw_ev_nb = &nss_dp_switchdev_notifier_nb; /* -@@ -366,6 +422,11 @@ void nss_dp_switchdev_setup(struct net_d - return; - } - -+ err = register_switchdev_notifier(&nss_dp_switchdev_fdb_notifier); -+ if (err) { -+ netdev_dbg(dev, "%px:Failed to register switchdev FDB notifier\n", dev); -+ } -+ - err = register_switchdev_blocking_notifier(&nss_dp_switchdev_notifier); - if (err) { - netdev_dbg(dev, "%px:Failed to register switchdev notifier\n", dev); + * nss_dp_bridge_attr_set() diff --git a/package/qca/qca-rfs/Makefile b/package/qca/qca-rfs/Makefile deleted file mode 100644 index 052694388..000000000 --- a/package/qca/qca-rfs/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-rfs -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-rfs.git -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/package/qca/qca-rfs/files/qrfs.init b/package/qca/qca-rfs/files/qrfs.init deleted file mode 100755 index f3f8a38c8..000000000 --- a/package/qca/qca-rfs/files/qrfs.init +++ /dev/null @@ -1,27 +0,0 @@ -#!/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/package/qca/qca-rfs/patches/100-add-kernel-5.4-support.patch b/package/qca/qca-rfs/patches/100-add-kernel-5.4-support.patch deleted file mode 100644 index b7b2db559..000000000 --- a/package/qca/qca-rfs/patches/100-add-kernel-5.4-support.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- 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/package/qca/qca-rfs/patches/200-rework-nfct-notification.patch b/package/qca/qca-rfs/patches/200-rework-nfct-notification.patch deleted file mode 100644 index 81e608c02..000000000 --- a/package/qca/qca-rfs/patches/200-rework-nfct-notification.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- 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/package/qca/qca-ssdk-shell/Makefile b/package/qca/qca-ssdk-shell/Makefile deleted file mode 100644 index 33e7dc50b..000000000 --- a/package/qca/qca-ssdk-shell/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=qca-ssdk-shell -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2022-01-24 -PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/ssdk-shell.git -PKG_SOURCE_VERSION:=01a60b45ac3498a40bbb011d0c3b7d5d3a1cc9cb -PKG_MIRROR_HASH:=6233c02c296af241eb2e1c25e49dfc8d9c6cf1095cb82f1862b125dd125c758e - -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/package/qca/qca-ssdk/Makefile b/package/qca/qca-ssdk/Makefile index 9b751f30d..7cc5602b3 100644 --- a/package/qca/qca-ssdk/Makefile +++ b/package/qca/qca-ssdk/Makefile @@ -3,87 +3,54 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qca-ssdk PKG_RELEASE:=1 -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2022-02-09 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git -PKG_SOURCE_VERSION:=0d6d410637648b1bea0dede48d3fab791689cfce -PKG_MIRROR_HASH:=54891fbd66f147ccc51d9815d91cf20720046b37c41c80311fa12cf66b31b8b0 +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2023-06-06 +PKG_SOURCE_VERSION:=74caf88aa3b6793c300f676e4fb1c62da7507be9 +PKG_MIRROR_HASH:=6bdb90919b773f5fb432c8b374c9419feac32ba6583ad82dfec5e41628a32dd9 -LOCAL_VARIANT=$(patsubst qca-ssdk-%,%,$(patsubst qca-ssdk-%,%,$(BUILD_VARIANT))) +PKG_FLAGS:=nonshared +PKG_BUILD_FLAGS:=no-lto include $(INCLUDE_DIR)/kernel.mk include $(INCLUDE_DIR)/package.mk -define KernelPackage/qca-ssdk/default-nohnat +define KernelPackage/qca-ssdk SECTION:=kernel CATEGORY:=Kernel modules SUBMENU:=Network Devices - TITLE:=Kernel driver for QCA SSDK + TITLE:=Qualcom SSDK switch driver + DEPENDS:=@(TARGET_qualcommax) 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||TARGET_ipq60xx) - VARIANT:=nohnat +define KernelPackage/qca-ssdk/Description + Driver for Qualcomm Atheros switches. endef -define KernelPackage/qca-ssdk-nohnat/Description -This package contains a qca-ssdk driver for QCA chipset -endef +GCC_VERSION=$(shell echo "$(CONFIG_GCC_VERSION)" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') -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 +LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' MODULE_TYPE=KSLIB modules -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) \ +MAKE_FLAGS+= \ + TARGET_NAME=$(CONFIG_TARGET_NAME) \ + TOOL_PATH=$(TOOLCHAIN_DIR)/bin \ SYS_PATH=$(LINUX_DIR) \ - GCC_VERSION=$(GCC_VERSION) \ TOOLPREFIX=$(TARGET_CROSS) \ - TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \ + KVER=$(LINUX_VERSION) \ + ARCH=$(LINUX_KARCH) \ TARGET_SUFFIX=$(CONFIG_TARGET_SUFFIX) \ - EXTRA_CFLAGS=-fno-stack-protector -I$(STAGING_DIR)/usr/include + GCC_VERSION=$(GCC_VERSION) \ + EXTRA_CFLAGS=-fno-stack-protector -I$(STAGING_DIR)/usr/include \ + PTP_FEATURE=disable SWCONFIG_FEATURE=disable \ + $(LNX_CONFIG_OPTS) -ifeq ($(LOCAL_VARIANT),hnat) - QCASSDK_CONFIG_OPTS+= HNAT_FEATURE=enable -ifeq ($(BOARD),ipq40xx) - QCASSDK_CONFIG_OPTS+= RFS_FEATURE=enable +ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq60xx") + MAKE_FLAGS+= CHIP_TYPE=CPPE +else ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") + MAKE_FLAGS+= CHIP_TYPE=HPPE 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 @@ -105,21 +72,14 @@ define Build/InstallDev 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 + if [ -f $(PKG_BUILD_DIR)/include/init/ssdk_netlink.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/init/ssdk_netlink.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)) +$(eval $(call KernelPackage,qca-ssdk)) diff --git a/package/qca/qca-ssdk/files/qca-ssdk b/package/qca/qca-ssdk/files/qca-ssdk deleted file mode 100755 index 389279c0c..000000000 --- a/package/qca/qca-ssdk/files/qca-ssdk +++ /dev/null @@ -1,206 +0,0 @@ -#!/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/package/qca/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10-5.15.patch b/package/qca/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10-5.15.patch deleted file mode 100644 index 62faf7f30..000000000 --- a/package/qca/qca-ssdk/patches/0001-SSDK-config-add-kernel-5.10-5.15.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/config -+++ b/config -@@ -24,6 +24,14 @@ ifeq ($(KVER),$(filter 5.4%,$(KVER))) - OS_VER=5_4 - endif - -+ifeq ($(KVER),$(filter 5.10%,$(KVER))) -+OS_VER=5_10 -+endif -+ -+ifeq ($(KVER),$(filter 5.15%,$(KVER))) -+OS_VER=5_15 -+endif -+ - ifeq ($(KVER), 3.4.0) - OS_VER=3_4 - endif -@@ -132,7 +140,7 @@ ifeq ($(ARCH), arm) - 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% 5.15%,$(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 -@@ -422,7 +422,7 @@ ifeq (KSLIB, $(MODULE_TYPE)) - KASAN_SHADOW_SCALE_SHIFT := 3 - endif - -- ifeq (5_4, $(OS_VER)) -+ ifeq ($(OS_VER),$(filter 5_4 5_10 5_15, $(OS_VER))) - ifeq ($(ARCH), arm64) - KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) - endif -@@ -453,7 +453,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 5_15, $(OS_VER))) - MODULE_CFLAG += -DKVER34 - MODULE_CFLAG += -DKVER32 - MODULE_CFLAG += -DLNX26_22 diff --git a/package/qca/qca-ssdk/patches/0001-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch b/package/qca/qca-ssdk/patches/0001-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch new file mode 100644 index 000000000..da5387daf --- /dev/null +++ b/package/qca/qca-ssdk/patches/0001-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch @@ -0,0 +1,67 @@ +From cdcafa28c857e4d04c9210feb54dc84e427061fe Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 11 Jan 2022 00:28:42 +0100 +Subject: [PATCH 1/2] qca807x: add a LED quirk for Xiaomi AX9000 + +Xiaomi AX9000 has a single LED for each of 4 gigabit ethernet ports that +are connected to QCA8075, and that LED is connected to the 100M LED pin. + +So, by default it will only work when in 10 or 100Mbit mode, this is quite +annoying and makes no sense(If they have connected it to the 1000Mbit LED +pin then it would have worked for 10/100 by default as well). + +So, to solve this add a check for system compatible as we cant parse if +from DTS in any other way and set the 100M LED to blink on 1000Base-T +as well. + +Signed-off-by: Robert Marko +--- + include/hsl/phy/malibu_phy.h | 2 ++ + src/hsl/phy/malibu_phy.c | 11 +++++++++++ + 2 files changed, 13 insertions(+) + +--- a/include/hsl/phy/malibu_phy.h ++++ b/include/hsl/phy/malibu_phy.h +@@ -94,6 +94,7 @@ extern "C" + #define MALIBU_DAC_CTRL_MASK 0x380 + #define MALIBU_DAC_CTRL_VALUE 0x280 + #define MALIBU_LED_1000_CTRL1_100_10_MASK 0x30 ++#define MALIBU_LED_100_CTRL1_1000_MASK 0x40 + + #define MALIBU_PHY_EEE_ADV_100M 0x0002 + #define MALIBU_PHY_EEE_ADV_1000M 0x0004 +@@ -118,6 +119,7 @@ extern "C" + #define MALIBU_PHY_MMD7_EGRESS_COUNTER_HIGH 0x802d + #define MALIBU_PHY_MMD7_EGRESS_COUNTER_LOW 0x802e + #define MALIBU_PHY_MMD7_EGRESS_ERROR_COUNTER 0x802f ++#define MALIBU_PHY_MMD7_LED_100_CTRL1 0x8074 + #define MALIBU_PHY_MMD7_LED_1000_CTRL1 0x8076 + + +--- a/src/hsl/phy/malibu_phy.c ++++ b/src/hsl/phy/malibu_phy.c +@@ -15,6 +15,8 @@ + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + ++#include ++ + #include "sw.h" + #include "fal_port_ctrl.h" + #include "hsl_api.h" +@@ -2716,6 +2718,15 @@ malibu_phy_hw_init(a_uint32_t dev_id, a_ + led_status |= MALIBU_LED_1000_CTRL1_100_10_MASK; + malibu_phy_mmd_write(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_LED_1000_CTRL1, led_status); ++ if (of_machine_is_compatible("xiaomi,ax9000")) { ++ /* add 1000M link LED behavior for Xiaomi AX9000 */ ++ led_status = malibu_phy_mmd_read(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, ++ MALIBU_PHY_MMD7_LED_100_CTRL1); ++ led_status &= ~MALIBU_LED_100_CTRL1_1000_MASK; ++ led_status |= MALIBU_LED_100_CTRL1_1000_MASK; ++ malibu_phy_mmd_write(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, ++ MALIBU_PHY_MMD7_LED_100_CTRL1, led_status); ++ } + /*disable Extended next page*/ + phy_data = malibu_phy_reg_read(dev_id, phy_addr, MALIBU_AUTONEG_ADVERT); + phy_data &= ~MALIBU_EXTENDED_NEXT_PAGE_EN; diff --git a/package/qca/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch b/package/qca/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch deleted file mode 100644 index 05fcbd784..000000000 --- a/package/qca/qca-ssdk/patches/0002-SSDK-replace-ioremap_nocache-with-ioremap.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- a/src/init/ssdk_clk.c -+++ b/src/init/ssdk_clk.c -@@ -696,7 +696,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"); -@@ -713,7 +713,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"); -@@ -761,7 +761,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; -@@ -818,7 +818,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; -@@ -839,7 +839,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 -@@ -2945,7 +2945,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 -@@ -1361,7 +1361,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__); -@@ -1376,7 +1376,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__); -@@ -1409,7 +1409,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/package/qca/qca-ssdk/patches/0002-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch b/package/qca/qca-ssdk/patches/0002-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch new file mode 100644 index 000000000..9d456b239 --- /dev/null +++ b/package/qca/qca-ssdk/patches/0002-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch @@ -0,0 +1,29 @@ +From a750e569aeb4f7b454dbde18cd6d0f2bb1875dfa Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 26 Jan 2022 14:47:33 +0100 +Subject: [PATCH 2/2] qca807x: add a LED quirk for Xiaomi AX3600 + +AX3600 requires the same LED quirk so that PHY LED-s will blink even +once Linux resets the PHY. + +So, just check for its compatible. + +Signed-off-by: Robert Marko +--- + src/hsl/phy/malibu_phy.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/src/hsl/phy/malibu_phy.c ++++ b/src/hsl/phy/malibu_phy.c +@@ -2718,8 +2718,9 @@ malibu_phy_hw_init(a_uint32_t dev_id, a_ + led_status |= MALIBU_LED_1000_CTRL1_100_10_MASK; + malibu_phy_mmd_write(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_LED_1000_CTRL1, led_status); +- if (of_machine_is_compatible("xiaomi,ax9000")) { +- /* add 1000M link LED behavior for Xiaomi AX9000 */ ++ /* add 1000M link LED behavior for Xiaomi boards */ ++ if (of_machine_is_compatible("xiaomi,ax9000") || ++ of_machine_is_compatible("xiaomi,ax3600")) { + led_status = malibu_phy_mmd_read(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_LED_100_CTRL1); + led_status &= ~MALIBU_LED_100_CTRL1_1000_MASK; diff --git a/package/qca/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch b/package/qca/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch deleted file mode 100644 index 61390fab6..000000000 --- a/package/qca/qca-ssdk/patches/0004-platform-use-of_mdio_find_bus-to-get-MDIO-bus.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/src/init/ssdk_plat.c -+++ b/src/init/ssdk_plat.c -@@ -561,7 +561,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]; -@@ -596,12 +595,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/package/qca/qca-ssdk/patches/0005-add-kernel-5.4-support.patch b/package/qca/qca-ssdk/patches/0005-add-kernel-5.4-support.patch deleted file mode 100644 index 1101a8a85..000000000 --- a/package/qca/qca-ssdk/patches/0005-add-kernel-5.4-support.patch +++ /dev/null @@ -1,108 +0,0 @@ ---- a/app/nathelper/linux/lib/nat_helper_dt.c -+++ b/app/nathelper/linux/lib/nat_helper_dt.c -@@ -726,7 +726,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)) -@@ -775,7 +775,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(uintptr_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(uintptr_t ct_add - - 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(uintptr_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) - uintptr_t - napt_ct_list_iterate(uint32_t *hash, uintptr_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, uin - 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 -@@ -483,9 +483,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/package/qca/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch b/package/qca/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch deleted file mode 100644 index e8423b84e..000000000 --- a/package/qca/qca-ssdk/patches/0006-fix-mdio-probe-on-ipq806x.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/init/ssdk_plat.c -+++ b/src/init/ssdk_plat.c -@@ -580,7 +580,7 @@ static int miibus_get(a_uint32_t dev_id) - if (!mdio_node) - mdio_node = of_find_compatible_node(NULL, NULL, "qcom,qca-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/package/qca/qca-ssdk/patches/0007-SSDK-dts-fix-of_get_mac_address.patch b/package/qca/qca-ssdk/patches/0007-SSDK-dts-fix-of_get_mac_address.patch deleted file mode 100644 index 325b70a2e..000000000 --- a/package/qca/qca-ssdk/patches/0007-SSDK-dts-fix-of_get_mac_address.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/src/init/ssdk_dts.c -+++ b/src/init/ssdk_dts.c -@@ -824,8 +824,9 @@ static void ssdk_dt_parse_intf_mac(void) - { - struct device_node *dp_node = NULL; - a_uint32_t dp = 0; -- a_uint8_t *maddr = NULL; -+ u8 maddr[ETH_ALEN]; - char dp_name[8] = {0}; -+ int ret; - - for (dp = 1; dp <= SSDK_MAX_NR_ETH; dp++) { - snprintf(dp_name, sizeof(dp_name), "dp%d", dp); -@@ -833,11 +834,11 @@ static void ssdk_dt_parse_intf_mac(void) - if (!dp_node) { - continue; - } -- maddr = (a_uint8_t *)of_get_mac_address(dp_node); -+ ret = of_get_mac_address(dp_node, maddr); - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) - if (maddr && is_valid_ether_addr(maddr)) { - #else -- if (!IS_ERR(maddr) && is_valid_ether_addr(maddr)) { -+ if (!ret && is_valid_ether_addr(maddr)) { - #endif - ssdk_dt_global.num_intf_mac++; - ether_addr_copy(ssdk_dt_global.intf_mac[dp-1].uc, maddr); diff --git a/package/qca/qca-ssdk/patches/0009-qca8081-convert-to-5.11-IRQ-model.patch b/package/qca/qca-ssdk/patches/0009-qca8081-convert-to-5.11-IRQ-model.patch deleted file mode 100644 index da414d7f6..000000000 --- a/package/qca/qca-ssdk/patches/0009-qca8081-convert-to-5.11-IRQ-model.patch +++ /dev/null @@ -1,70 +0,0 @@ ---- a/src/hsl/phy/qca808x.c -+++ b/src/hsl/phy/qca808x.c -@@ -238,6 +238,7 @@ static int qca808x_config_intr(struct ph - return err; - } - -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) - static int qca808x_ack_interrupt(struct phy_device *phydev) - { - int err; -@@ -257,6 +258,47 @@ static int qca808x_ack_interrupt(struct - - return (err < 0) ? err : 0; - } -+#endif -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 11, 0)) -+static irqreturn_t qca808x_handle_interrupt(struct phy_device *phydev) -+{ -+ a_uint16_t irq_status, int_enabled; -+ a_uint32_t dev_id = 0, phy_id = 0; -+ qca808x_priv *priv = phydev->priv; -+ const struct qca808x_phy_info *pdata = priv->phy_info; -+ -+ if (!pdata) { -+ return SW_FAIL; -+ } -+ -+ dev_id = pdata->dev_id; -+ phy_id = pdata->phy_addr; -+ -+ irq_status = qca808x_phy_reg_read(dev_id, phy_id, -+ QCA808X_PHY_INTR_STATUS); -+ if (irq_status < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ /* Read the current enabled interrupts */ -+ int_enabled = qca808x_phy_reg_read(dev_id, phy_id, -+ QCA808X_PHY_INTR_MASK); -+ if (int_enabled < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ /* See if this was one of our enabled interrupts */ -+ if (!(irq_status & int_enabled)) -+ return IRQ_NONE; -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+#endif - - /* switch linux negtiation capability to fal avariable */ - #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) -@@ -623,7 +665,11 @@ struct phy_driver qca808x_phy_driver = { - .config_intr = qca808x_config_intr, - .config_aneg = qca808x_config_aneg, - .aneg_done = qca808x_aneg_done, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) - .ack_interrupt = qca808x_ack_interrupt, -+#else -+ .handle_interrupt = qca808x_handle_interrupt, -+#endif - .read_status = qca808x_read_status, - .suspend = qca808x_suspend, - .resume = qca808x_resume, diff --git a/package/qca/qca-ssdk/patches/0010-QSDK-config-Avoid-Werror-heroics.patch b/package/qca/qca-ssdk/patches/0010-QSDK-config-Avoid-Werror-heroics.patch deleted file mode 100644 index be626b6ca..000000000 --- a/package/qca/qca-ssdk/patches/0010-QSDK-config-Avoid-Werror-heroics.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ecd1e0c57fdf7f8916fa20f085e08bb4b6ba0396 Mon Sep 17 00:00:00 2001 -From: Alexandru Gagniuc -Date: Fri, 23 Sep 2022 08:21:13 -0500 -Subject: [PATCH 10/11] QSDK: config: Avoid -Werror heroics - -Trying to compile the QSDK with warnings as errors is a very brave -endeavor. It's also stupid as it doesn't work on ipq60xx: - - isisc_acl_prv.h:99: error: "FIELD_GET" redefined [-Werror] - 99 | #define FIELD_GET(reg, field, val) \ - | - -Instead of dealing with the braindead code, just disable Werror. - -Signed-off-by: Alexandru Gagniuc ---- - config | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/config -+++ b/config -@@ -141,7 +141,7 @@ endif - - ifeq ($(ARCH), arm64) - ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4% 5.10% 5.15%,$(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 -+ CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -Wno-error=maybe-uninitialized -Wno-error=array-bounds -mcmodel=large - endif - endif - diff --git a/package/qca/qca-ssdk/patches/0012-include-fix-compilation-error-for-parse_uci_option.patch b/package/qca/qca-ssdk/patches/0012-include-fix-compilation-error-for-parse_uci_option.patch deleted file mode 100644 index 79b04f403..000000000 --- a/package/qca/qca-ssdk/patches/0012-include-fix-compilation-error-for-parse_uci_option.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 8e3500df074625b3eb3a8ed4e8e0b1b116f13d0c Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 7 May 2022 19:03:55 +0200 -Subject: [PATCH] include: fix compilation error for parse_uci_option - -Fix missing include for parse_uci_option - -Signed-off-by: Ansuel Smith ---- - include/ref/ref_uci.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/ref/ref_uci.h -+++ b/include/ref/ref_uci.h -@@ -19,6 +19,7 @@ - extern "C" { - #endif /* __cplusplus */ - -+#include - - #if defined(IN_SWCONFIG) - int diff --git a/package/lean/shortcut-fe/fast-classifier/Makefile b/package/qca/shortcut-fe/fast-classifier/Makefile similarity index 92% rename from package/lean/shortcut-fe/fast-classifier/Makefile rename to package/qca/shortcut-fe/fast-classifier/Makefile index 09c1174dd..6d0036bf7 100644 --- a/package/lean/shortcut-fe/fast-classifier/Makefile +++ b/package/qca/shortcut-fe/fast-classifier/Makefile @@ -67,8 +67,6 @@ Example user space program that communicates with fast classifier kernel module endef -HAVE_ECM:=$(CONFIG_PACKAGE_kmod-qca-nss-ecm-premium)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-noload)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-premium-noload)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-standard) - define Build/Compile/kmod +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ $(KERNEL_MAKE_FLAGS) \ @@ -76,7 +74,6 @@ define Build/Compile/kmod M="$(PKG_BUILD_DIR)" \ CONFIG_FAST_CLASSIFIER=m \ EXTRA_CFLAGS+="-DSFE_SUPPORT_IPV6" \ - $(if $(HAVE_ECM),EXTRA_CFLAGS+="-DCONFIG_SFE_ECM" CONFIG_SFE_ECM=y,) \ modules endef diff --git a/package/lean/shortcut-fe/fast-classifier/src/Makefile b/package/qca/shortcut-fe/fast-classifier/src/Makefile similarity index 100% rename from package/lean/shortcut-fe/fast-classifier/src/Makefile rename to package/qca/shortcut-fe/fast-classifier/src/Makefile diff --git a/package/lean/shortcut-fe/fast-classifier/src/fast-classifier.c b/package/qca/shortcut-fe/fast-classifier/src/fast-classifier.c similarity index 100% rename from package/lean/shortcut-fe/fast-classifier/src/fast-classifier.c rename to package/qca/shortcut-fe/fast-classifier/src/fast-classifier.c diff --git a/package/lean/shortcut-fe/fast-classifier/src/fast-classifier.h b/package/qca/shortcut-fe/fast-classifier/src/fast-classifier.h similarity index 100% rename from package/lean/shortcut-fe/fast-classifier/src/fast-classifier.h rename to package/qca/shortcut-fe/fast-classifier/src/fast-classifier.h diff --git a/package/lean/shortcut-fe/fast-classifier/src/nl_classifier_test.c b/package/qca/shortcut-fe/fast-classifier/src/nl_classifier_test.c similarity index 100% rename from package/lean/shortcut-fe/fast-classifier/src/nl_classifier_test.c rename to package/qca/shortcut-fe/fast-classifier/src/nl_classifier_test.c diff --git a/package/lean/shortcut-fe/fast-classifier/src/userspace_example.c b/package/qca/shortcut-fe/fast-classifier/src/userspace_example.c similarity index 100% rename from package/lean/shortcut-fe/fast-classifier/src/userspace_example.c rename to package/qca/shortcut-fe/fast-classifier/src/userspace_example.c diff --git a/package/lean/shortcut-fe/shortcut-fe/Makefile b/package/qca/shortcut-fe/shortcut-fe/Makefile similarity index 89% rename from package/lean/shortcut-fe/shortcut-fe/Makefile rename to package/qca/shortcut-fe/shortcut-fe/Makefile index dd53042e5..51e372ece 100644 --- a/package/lean/shortcut-fe/shortcut-fe/Makefile +++ b/package/qca/shortcut-fe/shortcut-fe/Makefile @@ -47,8 +47,6 @@ define KernelPackage/shortcut-fe/install $(INSTALL_BIN) ./files/usr/bin/sfe_dump $(1)/usr/bin endef -HAVE_ECM:=$(CONFIG_PACKAGE_kmod-qca-nss-ecm-premium)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-noload)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-premium-noload)$(CONFIG_PACKAGE_kmod-qca-nss-ecm-standard) - define KernelPackage/shortcut-fe-cm SECTION:=kernel CATEGORY:=Kernel modules @@ -72,8 +70,8 @@ define Build/Compile $(KERNEL_MAKE_FLAGS) \ $(PKG_MAKE_FLAGS) \ M="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS+="-DSFE_SUPPORT_IPV6" SFE_SUPPORT_IPV6=y \ - $(if $(HAVE_ECM),EXTRA_CFLAGS+="-DCONFIG_SFE_ECM" CONFIG_SFE_ECM=y,) \ + EXTRA_CFLAGS+="-DSFE_SUPPORT_IPV6" \ + SFE_SUPPORT_IPV6=y \ modules endef diff --git a/package/lean/shortcut-fe/shortcut-fe/files/etc/init.d/shortcut-fe b/package/qca/shortcut-fe/shortcut-fe/files/etc/init.d/shortcut-fe similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/files/etc/init.d/shortcut-fe rename to package/qca/shortcut-fe/shortcut-fe/files/etc/init.d/shortcut-fe diff --git a/package/lean/shortcut-fe/shortcut-fe/files/usr/bin/sfe_dump b/package/qca/shortcut-fe/shortcut-fe/files/usr/bin/sfe_dump similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/files/usr/bin/sfe_dump rename to package/qca/shortcut-fe/shortcut-fe/files/usr/bin/sfe_dump diff --git a/package/lean/shortcut-fe/shortcut-fe/src/Kconfig b/package/qca/shortcut-fe/shortcut-fe/src/Kconfig similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/src/Kconfig rename to package/qca/shortcut-fe/shortcut-fe/src/Kconfig diff --git a/package/lean/shortcut-fe/shortcut-fe/src/Makefile b/package/qca/shortcut-fe/shortcut-fe/src/Makefile similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/src/Makefile rename to package/qca/shortcut-fe/shortcut-fe/src/Makefile diff --git a/package/lean/shortcut-fe/shortcut-fe/src/sfe.h b/package/qca/shortcut-fe/shortcut-fe/src/sfe.h similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/src/sfe.h rename to package/qca/shortcut-fe/shortcut-fe/src/sfe.h diff --git a/package/lean/shortcut-fe/shortcut-fe/src/sfe_backport.h b/package/qca/shortcut-fe/shortcut-fe/src/sfe_backport.h similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/src/sfe_backport.h rename to package/qca/shortcut-fe/shortcut-fe/src/sfe_backport.h diff --git a/package/lean/shortcut-fe/shortcut-fe/src/sfe_cm.c b/package/qca/shortcut-fe/shortcut-fe/src/sfe_cm.c similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/src/sfe_cm.c rename to package/qca/shortcut-fe/shortcut-fe/src/sfe_cm.c diff --git a/package/lean/shortcut-fe/shortcut-fe/src/sfe_cm.h b/package/qca/shortcut-fe/shortcut-fe/src/sfe_cm.h similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/src/sfe_cm.h rename to package/qca/shortcut-fe/shortcut-fe/src/sfe_cm.h diff --git a/package/lean/shortcut-fe/shortcut-fe/src/sfe_ipv4.c b/package/qca/shortcut-fe/shortcut-fe/src/sfe_ipv4.c similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/src/sfe_ipv4.c rename to package/qca/shortcut-fe/shortcut-fe/src/sfe_ipv4.c diff --git a/package/lean/shortcut-fe/shortcut-fe/src/sfe_ipv6.c b/package/qca/shortcut-fe/shortcut-fe/src/sfe_ipv6.c similarity index 100% rename from package/lean/shortcut-fe/shortcut-fe/src/sfe_ipv6.c rename to package/qca/shortcut-fe/shortcut-fe/src/sfe_ipv6.c diff --git a/package/lean/shortcut-fe/simulated-driver/Makefile b/package/qca/shortcut-fe/simulated-driver/Makefile similarity index 97% rename from package/lean/shortcut-fe/simulated-driver/Makefile rename to package/qca/shortcut-fe/simulated-driver/Makefile index 60034b89c..9ed83946f 100644 --- a/package/lean/shortcut-fe/simulated-driver/Makefile +++ b/package/qca/shortcut-fe/simulated-driver/Makefile @@ -30,7 +30,7 @@ define KernelPackage/shortcut-fe-drv SECTION:=kernel CATEGORY:=Kernel modules SUBMENU:=Network Support - DEPENDS:=@TARGET_ipq806x||TARGET_ipq807x +kmod-shortcut-fe + DEPENDS:=@TARGET_qualcommax +kmod-shortcut-fe KCONFIG:= \ CONFIG_NET_CLS_ACT=y \ CONFIG_XFRM=y