From f247ce474ff2b90b3662ecef9570b5798f5a47d3 Mon Sep 17 00:00:00 2001 From: DHDAXCW Date: Tue, 20 Dec 2022 05:44:01 +0000 Subject: [PATCH] rockchip: add kernel 6.1 support --- include/kernel-6.0 | 2 - include/kernel-6.1 | 2 + include/netfilter.mk | 7 - package/kernel/linux/modules/crypto.mk | 26 - package/kernel/linux/modules/fs.mk | 8 +- package/kernel/linux/modules/lib.mk | 5 +- package/kernel/linux/modules/netdevices.mk | 6 +- package/kernel/linux/modules/netfilter.mk | 17 - package/kernel/linux/modules/netsupport.mk | 22 +- package/kernel/linux/modules/other.mk | 10 +- package/kernel/linux/modules/usb.mk | 4 +- package/kernel/linux/modules/video.mk | 16 +- package/{lean => kernel}/r8125/Makefile | 0 .../r8125/patches/010-config.patch | 0 .../r8125/patches/020-5.19-support.patch | 0 .../030-add-LED-configuration-from-OF.patch | 0 package/{lean => kernel}/r8152/Makefile | 6 +- .../r8152/patches/010-5.19-support.patch | 0 .../r8152/patches/020-6.1-support.patch | 38 + package/kernel/r8168/Makefile | 8 +- ...-r8168-add-LED-configuration-from-OF.patch | 4 +- .../r8168/patches/020-5.18-support.patch | 47 - ...9-support.patch => 020-5.19-support.patch} | 0 .../r8168/patches/030-6.1-support.patch | 14 + ...1-fix-nf_conntrack_register_notifier.patch | 25 - package/network/config/firewall/Makefile | 8 +- .../config/firewall/files/firewall.config | 2 +- .../001-firewall3-fix-locking-issue.patch | 38 + .../services/fullconenat}/Makefile | 26 +- .../patches/001-linux-6.1-support.patch | 26 + .../services/fullconenat/src}/Makefile | 0 package/network/utils/iptables/Makefile | 14 - .../001-CONFIG_INITRAMFS_PRESERVE_MTIME.patch | 75 - .../backport-6.0/002-struct-net_device.patch | 122 - ...-x86-arm64-add-arch_has_hw_pte_young.patch | 143 -- ...dd-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch | 132 -- ...102-mm-vmscan.c-refactor-shrink_node.patch | 254 --- ...inux-mm_inline.h-fold-__update_lru_s.patch | 59 - .../104-mm-multi-gen-LRU-groundwork.patch | 777 ------- ...multi-gen-LRU-minimal-implementation.patch | 1425 ------------ ...lti-gen-LRU-exploit-locality-in-rmap.patch | 476 ---- ...lti-gen-LRU-support-page-table-walks.patch | 1662 -------------- ...lti-gen-LRU-optimize-multiple-memcgs.patch | 290 --- .../109-mm-multi-gen-LRU-kill-switch.patch | 475 ---- ...m-multi-gen-LRU-thrashing-prevention.patch | 202 -- ...1-mm-multi-gen-LRU-debugfs-interface.patch | 557 ----- .../112-mm-multi-gen-LRU-admin-guide.patch | 253 --- .../113-mm-multi-gen-LRU-design-doc.patch | 202 -- ...dd-netdev_sw_irq_coalesce_default_on.patch | 59 + ...bsolte-u64_stats_fetch_-_irq-users-d.patch | 2022 +++++++++++++++++ ...ert-to-boolean-for-the-mac_managed_p.patch | 56 + ...9-use-tp_to_dev-instead-of-open-code.patch | 38 + ...-software-interrupt-coalescing-per-d.patch | 33 + ...y-a-bit-code-find-partition-matching.patch | 65 + ...find-OF-node-for-every-MTD-partition.patch | 84 + ...TP-Link-SafeLoader-partitions-table-.patch | 229 ++ .../linux/generic/{config-6.0 => config-6.1} | 487 +++- .../hack-6.0/249-udp-tunnel-selection.patch | 11 - .../linux/generic/hack-6.0/252-SATA_PMP.patch | 23 - .../generic/hack-6.0/253-ksmbd-config.patch | 22 - .../hack-6.0/261-lib-arc4-unhide.patch | 15 - .../301-mips_image_cmdline_hack.patch | 38 - .../hack-6.0/430-mtk-bmt-support.patch | 23 - .../generic/hack-6.0/531-debloat_lzma.patch | 1040 --------- .../640-bridge-only-accept-EAP-locally.patch | 41 - .../661-use_fq_codel_by_default.patch | 100 - .../hack-6.0/920-device_tree_cmdline.patch | 12 - .../204-module_strip.patch | 64 +- .../205-kconfig-exit.patch | 9 + .../210-darwin_scripts_include.patch | 0 .../211-darwin-uuid-typedef-clash.patch | 0 .../212-tools_portability.patch | 10 + .../214-spidev_h_portability.patch | 0 .../220-arm-gc_sections.patch | 2 +- .../221-module_exports.patch | 34 +- .../230-openwrt_lzma_options.patch | 10 +- .../250-netfilter_depends.patch | 0 .../{hack-6.0 => hack-6.1}/251-kconfig.patch | 6 +- .../generic/hack-6.1/253-ksmbd-config.patch | 32 + .../259-regmap_dynamic.patch | 2 +- .../260-crypto_test_dependencies.patch | 0 .../hack-6.1/261-lib-arc4-unhide.patch | 24 + .../280-rfkill-stubs.patch | 2 +- ...cache-use-more-efficient-cache-blast.patch | 0 .../321-powerpc_crtsavres_prereq.patch | 0 ...rans-call-add-disks-after-mtd-device.patch | 112 + .../410-block-fit-partition-parser.patch | 45 +- .../420-mtd-set-rootfs-to-be-root-dev.patch | 2 +- ...ers-add-nvmem-support-to-cmdlinepart.patch | 0 .../hack-6.1/430-mtk-bmt-support.patch | 33 + .../generic/hack-6.1/600-bridge_offload.patch | 846 +++++++ ...of_net-add-mac-address-ascii-support.patch | 112 + ...lter-connmark-introduce-set-dscpmark.patch | 21 +- ...-netfilter-add-xt_FLOWOFFLOAD-target.patch | 82 +- .../651-wireless_mesh_header.patch | 2 +- .../660-fq_codel_defaults.patch | 2 +- ...t-size-the-hashtable-more-adequately.patch | 25 + .../700-swconfig_switch_drivers.patch | 10 +- ...-dsa-mv88e6xxx-disable-ATU-violation.patch | 21 + .../hack-6.1/720-net-phy-add-aqr-phys.patch | 120 + .../721-net-add-packet-mangeling.patch | 167 ++ ...hy-aquantia-enable-AQR112-and-AQR412.patch | 148 ++ ...aquantia-fix-system-side-protocol-mi.patch | 34 + ...y-aquantia-Add-AQR113-driver-support.patch | 43 + ...ntia-add-PHY_IDs-for-AQR112-variants.patch | 63 + ...-r8152-add-LED-configuration-from-OF.patch | 8 +- ...et-add-RTL8152-binding-documentation.patch | 0 .../773-bgmac-add-srab-switch.patch | 2 +- .../780-usb-net-MeigLink_modem_support.patch | 10 + .../790-SFP-GE-T-ignore-TX_FAULT.patch | 63 + .../800-GPIO-add-named-gpio-exports.patch | 6 +- .../hack-6.1/901-debloat_sock_diag.patch | 175 ++ .../902-debloat_proc.patch | 16 +- .../904-debloat_dma_buf.patch | 8 +- .../910-kobject_uevent.patch | 0 .../911-kobject_add_broadcast_uevent.patch | 0 .../hack-6.1/920-device_tree_cmdline.patch | 21 + ...vert-driver-core-Set-fw_devlink-on-b.patch | 30 + ...k-events-support-multiple-registrant.patch | 8 +- ...-linux-kernel-to-support-shortcut-fe.patch | 20 +- .../982-add-bcm-fullconenat-support.patch | 6 +- .../992-add-ndo-do-ioctl.patch | 0 ...-Use-stddefs.h-instead-of-compiler.h.patch | 11 - .../pending-6.0/201-extra_optimization.patch | 25 - ...support-for-minor-aligned-partitions.patch | 389 ---- ...t-add-of_match_table-with-DT-binding.patch | 22 - ...-mtd-core-add-get_mtd_device_by_node.patch | 75 - ..._eth_soc-avoid-creating-duplicate-of.patch | 26 - ...-add-support-for-in-band-link-status.patch | 123 - ...net-phy-at803x-fix-at8033-sgmii-mode.patch | 51 - ...760-net-dsa-mv88e6xxx-fix-vlan-setup.patch | 27 - ...-net-dsa-mt7530-Support-EEE-features.patch | 103 - ...include-asm-rwonce.h-for-kernel-code.patch | 8 +- ...-Use-stddefs.h-instead-of-compiler.h.patch | 22 + ...s-negative-stack-offsets-on-stack-tr.patch | 0 .../103-kbuild-export-SUBARCH.patch} | 10 +- ...e_mem_map-with-ARCH_PFN_OFFSET-calcu.patch | 2 +- ...0-add-linux-spidev-compatible-si3210.patch | 18 + ...ame2-and-add-RENAME_WHITEOUT-support.patch | 0 ...41-jffs2-add-RENAME_EXCHANGE-support.patch | 0 .../142-jffs2-add-splice-ops.patch | 0 ...ge_allow_receiption_on_disabled_port.patch | 0 ...-rs5c372-support_alarms_up_to_1_week.patch | 0 ...he_alarm_to_be_used_as_wakeup_source.patch | 5 +- .../203-kallsyms_uncompressed.patch | 35 +- .../205-backtrace_module_info.patch | 4 +- ...e-filenames-from-deps_initramfs-list.patch | 0 ...able_wilink_platform_without_drivers.patch | 0 .../270-platform-mikrotik-build-bits.patch | 18 +- .../300-mips_expose_boot_raw.patch | 0 .../302-mips_no_branch_likely.patch | 0 .../305-mips_module_reloc.patch | 2 +- .../307-mips_highmem_offset.patch | 0 .../308-mips32r2_tune.patch | 0 .../310-arm_module_unresolved_weak_sym.patch | 0 ...t-command-line-parameters-from-users.patch | 8 +- .../332-arc-add-OWRTDTB-section.patch | 0 ...able-unaligned-access-in-kernel-mode.patch | 0 ...ernel-XZ-compression-option-on-PPC_8.patch | 2 +- .../400-mtd-mtdsplit-support.patch | 85 +- ...support-for-minor-aligned-partitions.patch | 245 ++ .../420-mtd-redboot_space.patch | 0 ...30-mtd-add-myloader-partition-parser.patch | 8 +- ...check-for-bad-blocks-when-calculatin.patch | 0 ...bcm47xxpart-detect-T_Meter-partition.patch | 0 ...mtd-add-routerbootpart-parser-config.patch | 4 +- ...mtd-cfi_cmdset_0002-no-erase_suspend.patch | 0 ...et_0002-add-buffer-write-cmd-timeout.patch | 0 ...25p80-mx-disable-software-protection.patch | 0 .../476-mtd-spi-nor-add-eon-en25q128.patch | 19 + .../479-mtd-spi-nor-add-xtx-xt25f128b.patch | 81 + ...r-add-support-for-Gigadevice-GD25D05.patch | 23 + .../482-mtd-spi-nor-add-gd25q512.patch | 23 + .../484-mtd-spi-nor-add-esmt-f25l16pa.patch | 24 + .../485-mtd-spi-nor-add-xmc-xm25qh128c.patch | 25 + ...nand-add-support-for-ESMT-F50x1G41LB.patch | 143 ++ ...nd-Add-support-for-Etron-EM73D044VCx.patch | 168 ++ ...mtd-device-named-ubi-or-data-on-boot.patch | 6 +- ...to-create-ubiblock-device-for-rootfs.patch | 0 ...ting-ubi0-rootfs-in-init-do_mounts.c.patch | 21 +- ...ROOT_DEV-to-ubiblock-rootfs-if-unset.patch | 0 .../494-mtd-ubi-add-EOF-marker-support.patch | 0 ...-add-bindings-for-mtd-concat-devices.patch | 0 ...cat-add-dt-driver-for-concat-devices.patch | 0 ...i-nor-locking-support-for-MX25L6405D.patch | 32 + ...i-nor-disable-16-bit-sr-for-macronix.patch | 2 +- .../500-fs_cdrom_dependencies.patch | 12 + .../530-jffs2_make_lzma_available.patch | 6 +- .../532-jffs2_eofdetect.patch | 0 .../600-netfilter_conntrack_flush.patch | 10 +- ...etfilter_match_bypass_default_checks.patch | 0 ...netfilter_match_bypass_default_table.patch | 0 ...netfilter_match_reduce_memory_access.patch | 0 ...-netfilter_optional_tcp_window_check.patch | 22 +- ...del-do-not-defer-queue-length-update.patch | 0 .../630-packet_socket_type.patch | 6 +- .../655-increase_skb_pad.patch | 2 +- ...Add-support-for-MAP-E-FMRs-mesh-mode.patch | 12 +- ...ng-with-source-address-failed-policy.patch | 2 +- ...nes-for-_POLICY_FAILED-until-all-cod.patch | 0 ...T-skip-GRO-for-foreign-MAC-addresses.patch | 28 +- ...et-add-mac-address-increment-support.patch | 0 ...83-of_net-add-mac-address-to-of-tree.patch | 17 + ...t-do-mac-address-increment-only-once.patch | 31 + ...ow_offload-handle-netdevice-events-f.patch | 110 + ...net-mtk_eth_soc-enable-threaded-NAPI.patch | 41 + ...detach-callback-to-struct-phy_driver.patch | 4 +- ...a-tag_mtk-add-padding-for-tx-packets.patch | 29 + ...d-knob-for-filtering-rx-tx-BPDU-pack.patch | 174 ++ ...rtl8221-allow-to-configure-SERDES-mo.patch | 6 +- ...e-all-MACs-are-powered-down-before-r.patch | 28 + ...-net-mtk_sgmii-implement-mtk_pcs_ops.patch | 0 ..._sgmii-fix-powering-up-the-SGMII-phy.patch | 0 ...sure-the-SGMII-PHY-is-powered-down-o.patch | 0 ...k_pcs_setup_mode_an-don-t-rely-on-re.patch | 0 ...t-the-speed-according-to-the-phy-int.patch | 0 .../729-net-mtk_eth_soc-improve-comment.patch | 0 ...enable-PCS-polling-to-allow-SFP-work.patch | 0 ...0211_ptr-even-with-no-CFG82111-suppo.patch | 59 + ..._eth_soc-account-for-vlan-in-rx-head.patch | 22 + ..._eth_soc-increase-tx-ring-side-for-Q.patch | 143 ++ ..._eth_soc-avoid-port_mg-assignment-on.patch | 52 + ..._eth_soc-implement-multi-queue-suppo.patch | 654 ++++++ ...t-dsa-tag_mtk-assign-per-port-queues.patch | 20 + ...iatek-ppe-assign-per-port-queues-for.patch | 93 + ..._eth_soc-compile-out-netsys-v2-code-.patch | 28 + ...ort-for-DSA-rx-offloading-via-metada.patch | 72 + ..._eth_soc-fix-VLAN-rx-hardware-accele.patch | 192 ++ ..._eth_soc-work-around-issue-with-send.patch | 78 + ...rnet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch | 21 + ..._eth_soc-drop-packets-to-WDMA-if-the.patch | 37 + ..._eth_soc-fix-flow_offload-related-re.patch | 52 + ..._eth_soc-drop-generic-vlan-rx-offloa.patch | 181 ++ ...et-mtk_wed-introduce-wed-mcu-support.patch | 591 +++++ ...net-mtk_wed-introduce-wed-wo-support.patch | 737 ++++++ ..._wed-rename-tx_wdma-array-in-rx_wdma.patch | 79 + ...mtk_wed-add-configure-wed-wo-support.patch | 1521 +++++++++++++ ...ethernet-mtk_wed-add-rx-mib-counters.patch | 149 ++ ...equest-assisted-learning-on-CPU-port.patch | 2 +- ...-missing-linux-if_ether.h-for-ETH_AL.patch | 0 ...ice-struct-copy-its-DMA-params-to-th.patch | 0 ...pio-cascade-add-generic-GPIO-cascade.patch | 4 +- ...e-old-opp-to-config_clks-on-_set_opp.patch | 108 + .../810-pci_disable_common_quirks.patch | 0 .../811-pci_disable_usb_common_quirks.patch | 2 +- ...problem-with-platfom-data-in-w1-gpio.patch | 0 .../834-ledtrig-libata.patch | 10 +- ...40-hwrng-bcm2835-set-quality-to-1000.patch | 0 ...e-main-irq_chip-structure-a-static-d.patch | 102 + .../920-mangle_bootargs.patch | 6 +- .../pending-6.1/930-qcom-qmi-helpers.patch | 11 + target/linux/rockchip/armv8/config-6.1 | 736 ++++++ .../boot/dts/rockchip/rk3566-lubancat1.dts | 0 .../boot/dts/rockchip/rk3566-lubancat1n.dts | 0 .../boot/dts/rockchip/rk3568-lubancat2.dts | 0 .../boot/dts/rockchip/rk3568-lubancat2.dtsi | 0 .../boot/dts/rockchip/rk3568-lubancat2n.dts | 0 .../boot/dts/rockchip/rk3568-lubancat2n.dtsi | 0 .../boot/dts/rockchip/rk3568-nanopi-r5s.dts | 0 .../boot/dts/rockchip/rk3568-opc-h68k.dts | 0 .../arm64/boot/dts/rockchip/rk3568-roc-pc.dts | 0 .../dts/rockchip/rk3399-guangmiao-g4c.dts | 666 ------ target/linux/rockchip/image/Makefile | 4 - ...Add-support-for-FriendlyARM-NanoPi-R.patch | 3 +- ...kchip-add-EEPROM-node-for-NanoPi-R4S.patch | 31 + ...-phy-Add-driver-for-Motorcomm-yt8521.patch | 1724 ++++++++++++++ ...net-phy-add-Motorcomm-YT8531S-phy-id.patch | 138 ++ ...-rockchip-use-system-LED-for-OpenWrt.patch | 47 + ...dd-OF-node-for-USB-eth-on-NanoPi-R2S.patch | 24 + .../103-nanopi-r4s-sd-signalling.patch | 26 + .../patches-6.1/104-rockchip-rock-pi-4.patch | 34 + ...-initial-signal-voltage-on-power-off.patch | 35 + ...-driver-for-Motorcomm-yt8531-gigabit.patch | 254 +++ ...use-dev_err-for-error-message-about-.patch | 26 + ...ip-do-not-use-uninitialized-variable.patch | 24 + ...ip-do-not-do-custom-power-management.patch | 94 + ...to-rockchip-fix-privete-private-typo.patch | 24 + ...-rockchip-do-not-store-mode-globally.patch | 262 +++ ...pto-rockchip-add-fallback-for-cipher.patch | 244 ++ ...ypto-rockchip-add-fallback-for-ahash.patch | 75 + ...to-rockchip-better-handle-cipher-key.patch | 81 + ...rockchip-remove-non-aligned-handling.patch | 262 +++ ...ckchip-rework-by-using-crypto_engine.patch | 881 +++++++ .../177-crypto-rockchip-rewrite-type.patch | 174 ++ .../178-crypto-rockchip-add-debugfs.patch | 232 ++ .../179-crypto-rockchip-introduce-PM.patch | 181 ++ ...pto-rockchip-handle-reset-also-in-PM.patch | 66 + ...use-clk_bulk-to-simplify-clock-manag.patch | 118 + ...to-rockchip-add-myself-as-maintainer.patch | 30 + ...rypto-rockchip-use-read_poll_timeout.patch | 54 + .../184-crypto-rockchip-fix-style-issue.patch | 55 + ...ypto-rockchip-add-support-for-rk3328.patch | 23 + ...chip-rename-ablk-functions-to-cipher.patch | 119 + ...ckchip-rework-rk_handle_req-function.patch | 180 ++ ...use-a-rk_crypto_info-variable-instea.patch | 172 ++ ...use-the-rk_crypto_info-given-as-para.patch | 34 + ...ypto-convert-rockchip-crypto-to-YAML.patch | 115 + ...s-crypto-rockchip-add-new-compatible.patch | 114 + ...2-clk-rk3399-use-proper-crypto0-name.patch | 37 + ...-dts-rockchip-add-rk3328-crypto-node.patch | 33 + ...-dts-rockchip-rk3399-add-crypto-node.patch | 43 + ...store-crypto_info-in-request-context.patch | 124 + ...Check-for-clocks-numbers-and-their-f.patch | 165 ++ ...rk_ahash_reg_init-use-crypto_info-fr.patch | 40 + ...p-permit-to-have-more-than-one-reset.patch | 24 + ...ypto-rockchip-Add-support-for-RK3399.patch | 464 ++++ ...8-add-i2c0-controller-for-nanopi-r2s.patch | 22 + ...328-Add-support-for-OrangePi-R1-Plus.patch | 52 + ...Add-support-for-OrangePi-R1-Plus-LTS.patch | 79 + ...Add-support-for-FriendlyARM-NanoPi-R.patch | 64 + ...-support-for-FriendlyARM-NanoPi-Neo3.patch | 442 ++++ ...ip-rk356x-add-support-for-new-boards.patch | 32 + ...9-Add-support-for-EmbedFire-DoorNet2.patch | 793 +++++++ ...ip-fix-spdif-fe460000-ordering-on-rk.patch | 59 + ...8-Add-support-for-EmbedFire-DoorNet1.patch | 499 ++++ ...rockchip-RK356x-Add-I2S2-device-node.patch | 45 + ...move-kconfig-to-its-dedicated-direct.patch | 105 + ...to-add-support-for-rockchip-crypto-r.patch | 89 + ...new-dt-binding-doc-to-the-right-entr.patch | 22 + ...support-the-new-crypto-IP-for-rk3568.patch | 1633 +++++++++++++ ...217-ARM64-dts-rk3568-add-crypto-node.patch | 36 + .../patches-6.1/218-fix-build-crypto.patch | 21 + ...-for-rockchip-hardware-random-number.patch | 45 + ...ip-add-hardware-random-number-genera.patch | 69 + ...ip-add-devfreq-driver-for-rk3328-dmc.patch | 44 + ...setting-ddr-clock-via-SIP-Version-2-.patch | 210 ++ ...eq-rockchip-dfi-add-more-soc-support.patch | 662 ++++++ ...m64-dts-rockchip-rk3328-add-dfi-node.patch | 27 + ...anopi-r2s-add-rk3328-dmc-relate-node.patch | 126 + ...drv-net-phy-add-JLSemi-jl2xxx-driver.patch | 702 ++++++ ...ip-add-more-cpu-operating-points-for.patch | 44 + ...chip-rk3399-overclock-to-2.2-1.8-GHz.patch | 46 + 332 files changed, 25565 insertions(+), 10495 deletions(-) delete mode 100644 include/kernel-6.0 create mode 100644 include/kernel-6.1 rename package/{lean => kernel}/r8125/Makefile (100%) rename package/{lean => kernel}/r8125/patches/010-config.patch (100%) rename package/{lean => kernel}/r8125/patches/020-5.19-support.patch (100%) rename package/{lean => kernel}/r8125/patches/030-add-LED-configuration-from-OF.patch (100%) rename package/{lean => kernel}/r8152/Makefile (92%) rename package/{lean => kernel}/r8152/patches/010-5.19-support.patch (100%) create mode 100644 package/kernel/r8152/patches/020-6.1-support.patch delete mode 100644 package/kernel/r8168/patches/020-5.18-support.patch rename package/kernel/r8168/patches/{030-5.19-support.patch => 020-5.19-support.patch} (100%) create mode 100644 package/kernel/r8168/patches/030-6.1-support.patch delete mode 100644 package/lean/openwrt-fullconenat/patches/0001-fix-nf_conntrack_register_notifier.patch create mode 100644 package/network/config/firewall/patches/001-firewall3-fix-locking-issue.patch rename package/{lean/openwrt-fullconenat => network/services/fullconenat}/Makefile (77%) create mode 100644 package/network/services/fullconenat/patches/001-linux-6.1-support.patch rename package/{lean/openwrt-fullconenat/files => network/services/fullconenat/src}/Makefile (100%) delete mode 100644 target/linux/generic/backport-6.0/001-CONFIG_INITRAMFS_PRESERVE_MTIME.patch delete mode 100644 target/linux/generic/backport-6.0/002-struct-net_device.patch delete mode 100644 target/linux/generic/backport-6.0/100-mm-x86-arm64-add-arch_has_hw_pte_young.patch delete mode 100644 target/linux/generic/backport-6.0/101-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch delete mode 100644 target/linux/generic/backport-6.0/102-mm-vmscan.c-refactor-shrink_node.patch delete mode 100644 target/linux/generic/backport-6.0/103-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch delete mode 100644 target/linux/generic/backport-6.0/104-mm-multi-gen-LRU-groundwork.patch delete mode 100644 target/linux/generic/backport-6.0/105-mm-multi-gen-LRU-minimal-implementation.patch delete mode 100644 target/linux/generic/backport-6.0/106-mm-multi-gen-LRU-exploit-locality-in-rmap.patch delete mode 100644 target/linux/generic/backport-6.0/107-mm-multi-gen-LRU-support-page-table-walks.patch delete mode 100644 target/linux/generic/backport-6.0/108-mm-multi-gen-LRU-optimize-multiple-memcgs.patch delete mode 100644 target/linux/generic/backport-6.0/109-mm-multi-gen-LRU-kill-switch.patch delete mode 100644 target/linux/generic/backport-6.0/110-mm-multi-gen-LRU-thrashing-prevention.patch delete mode 100644 target/linux/generic/backport-6.0/111-mm-multi-gen-LRU-debugfs-interface.patch delete mode 100644 target/linux/generic/backport-6.0/112-mm-multi-gen-LRU-admin-guide.patch delete mode 100644 target/linux/generic/backport-6.0/113-mm-multi-gen-LRU-design-doc.patch create mode 100644 target/linux/generic/backport-6.1/100-net-add-netdev_sw_irq_coalesce_default_on.patch create mode 100644 target/linux/generic/backport-6.1/101-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch create mode 100644 target/linux/generic/backport-6.1/102-drivers-net-convert-to-boolean-for-the-mac_managed_p.patch create mode 100644 target/linux/generic/backport-6.1/103-r8169-use-tp_to_dev-instead-of-open-code.patch create mode 100644 target/linux/generic/backport-6.1/104-r8169-enable-GRO-software-interrupt-coalescing-per-d.patch create mode 100644 target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch create mode 100644 target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch create mode 100644 target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch rename target/linux/generic/{config-6.0 => config-6.1} (94%) delete mode 100644 target/linux/generic/hack-6.0/249-udp-tunnel-selection.patch delete mode 100644 target/linux/generic/hack-6.0/252-SATA_PMP.patch delete mode 100644 target/linux/generic/hack-6.0/253-ksmbd-config.patch delete mode 100644 target/linux/generic/hack-6.0/261-lib-arc4-unhide.patch delete mode 100644 target/linux/generic/hack-6.0/301-mips_image_cmdline_hack.patch delete mode 100644 target/linux/generic/hack-6.0/430-mtk-bmt-support.patch delete mode 100644 target/linux/generic/hack-6.0/531-debloat_lzma.patch delete mode 100644 target/linux/generic/hack-6.0/640-bridge-only-accept-EAP-locally.patch delete mode 100644 target/linux/generic/hack-6.0/661-use_fq_codel_by_default.patch delete mode 100644 target/linux/generic/hack-6.0/920-device_tree_cmdline.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/204-module_strip.patch (76%) rename target/linux/generic/{hack-6.0 => hack-6.1}/205-kconfig-exit.patch (50%) rename target/linux/generic/{hack-6.0 => hack-6.1}/210-darwin_scripts_include.patch (100%) rename target/linux/generic/{hack-6.0 => hack-6.1}/211-darwin-uuid-typedef-clash.patch (100%) rename target/linux/generic/{hack-6.0 => hack-6.1}/212-tools_portability.patch (88%) rename target/linux/generic/{hack-6.0 => hack-6.1}/214-spidev_h_portability.patch (100%) rename target/linux/generic/{hack-6.0 => hack-6.1}/220-arm-gc_sections.patch (99%) rename target/linux/generic/{hack-6.0 => hack-6.1}/221-module_exports.patch (80%) rename target/linux/generic/{hack-6.0 => hack-6.1}/230-openwrt_lzma_options.patch (72%) rename target/linux/generic/{hack-6.0 => hack-6.1}/250-netfilter_depends.patch (100%) rename target/linux/generic/{hack-6.0 => hack-6.1}/251-kconfig.patch (96%) create mode 100644 target/linux/generic/hack-6.1/253-ksmbd-config.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/259-regmap_dynamic.patch (98%) rename target/linux/generic/{hack-6.0 => hack-6.1}/260-crypto_test_dependencies.patch (100%) create mode 100644 target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/280-rfkill-stubs.patch (97%) rename target/linux/generic/{hack-6.0 => hack-6.1}/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch (100%) rename target/linux/generic/{hack-6.0 => hack-6.1}/321-powerpc_crtsavres_prereq.patch (100%) create mode 100644 target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/410-block-fit-partition-parser.patch (87%) rename target/linux/generic/{hack-6.0 => hack-6.1}/420-mtd-set-rootfs-to-be-root-dev.patch (94%) rename target/linux/generic/{hack-6.0 => hack-6.1}/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch (100%) create mode 100644 target/linux/generic/hack-6.1/430-mtk-bmt-support.patch create mode 100644 target/linux/generic/hack-6.1/600-bridge_offload.patch create mode 100644 target/linux/generic/hack-6.1/601-of_net-add-mac-address-ascii-support.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/645-netfilter-connmark-introduce-set-dscpmark.patch (93%) rename target/linux/generic/{hack-6.0 => hack-6.1}/650-netfilter-add-xt_FLOWOFFLOAD-target.patch (90%) rename target/linux/generic/{hack-6.0 => hack-6.1}/651-wireless_mesh_header.patch (92%) rename target/linux/generic/{hack-6.0 => hack-6.1}/660-fq_codel_defaults.patch (92%) create mode 100644 target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/700-swconfig_switch_drivers.patch (94%) create mode 100644 target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch create mode 100644 target/linux/generic/hack-6.1/720-net-phy-add-aqr-phys.patch create mode 100644 target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch create mode 100644 target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch create mode 100644 target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch create mode 100644 target/linux/generic/hack-6.1/724-net-phy-aquantia-Add-AQR113-driver-support.patch create mode 100644 target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/760-net-usb-r8152-add-LED-configuration-from-OF.patch (87%) rename target/linux/generic/{hack-6.0 => hack-6.1}/761-dt-bindings-net-add-RTL8152-binding-documentation.patch (100%) rename target/linux/generic/{hack-6.0 => hack-6.1}/773-bgmac-add-srab-switch.patch (98%) rename target/linux/generic/{hack-6.0 => hack-6.1}/780-usb-net-MeigLink_modem_support.patch (83%) create mode 100644 target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/800-GPIO-add-named-gpio-exports.patch (96%) create mode 100644 target/linux/generic/hack-6.1/901-debloat_sock_diag.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/902-debloat_proc.patch (96%) rename target/linux/generic/{hack-6.0 => hack-6.1}/904-debloat_dma_buf.patch (91%) rename target/linux/generic/{hack-6.0 => hack-6.1}/910-kobject_uevent.patch (100%) rename target/linux/generic/{hack-6.0 => hack-6.1}/911-kobject_add_broadcast_uevent.patch (100%) create mode 100644 target/linux/generic/hack-6.1/920-device_tree_cmdline.patch create mode 100644 target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch rename target/linux/generic/{hack-6.0 => hack-6.1}/952-add-net-conntrack-events-support-multiple-registrant.patch (97%) rename target/linux/generic/{hack-6.0 => hack-6.1}/953-net-patch-linux-kernel-to-support-shortcut-fe.patch (92%) rename target/linux/generic/{hack-6.0 => hack-6.1}/982-add-bcm-fullconenat-support.patch (98%) rename target/linux/generic/{hack-6.0 => hack-6.1}/992-add-ndo-do-ioctl.patch (100%) delete mode 100644 target/linux/generic/pending-6.0/101-Use-stddefs.h-instead-of-compiler.h.patch delete mode 100644 target/linux/generic/pending-6.0/201-extra_optimization.patch delete mode 100644 target/linux/generic/pending-6.0/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch delete mode 100644 target/linux/generic/pending-6.0/419-mtd-redboot-add-of_match_table-with-DT-binding.patch delete mode 100644 target/linux/generic/pending-6.0/495-mtd-core-add-get_mtd_device_by_node.patch delete mode 100644 target/linux/generic/pending-6.0/700-net-ethernet-mtk_eth_soc-avoid-creating-duplicate-of.patch delete mode 100644 target/linux/generic/pending-6.0/731-net-dsa-mt7530-add-support-for-in-band-link-status.patch delete mode 100644 target/linux/generic/pending-6.0/735-net-phy-at803x-fix-at8033-sgmii-mode.patch delete mode 100644 target/linux/generic/pending-6.0/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch delete mode 100644 target/linux/generic/pending-6.0/761-net-dsa-mt7530-Support-EEE-features.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch (80%) create mode 100644 target/linux/generic/pending-6.1/101-Use-stddefs.h-instead-of-compiler.h.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch (100%) rename target/linux/generic/{backport-6.0/011-kbuild-export-SUBARCH.patch => pending-6.1/103-kbuild-export-SUBARCH.patch} (73%) rename target/linux/generic/{pending-6.0 => pending-6.1}/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch (97%) create mode 100644 target/linux/generic/pending-6.1/130-add-linux-spidev-compatible-si3210.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/141-jffs2-add-RENAME_EXCHANGE-support.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/142-jffs2-add-splice-ops.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/150-bridge_allow_receiption_on_disabled_port.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/190-rtc-rs5c372-support_alarms_up_to_1_week.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch (90%) rename target/linux/generic/{pending-6.0 => pending-6.1}/203-kallsyms_uncompressed.patch (77%) rename target/linux/generic/{pending-6.0 => pending-6.1}/205-backtrace_module_info.patch (89%) rename target/linux/generic/{pending-6.0 => pending-6.1}/240-remove-unsane-filenames-from-deps_initramfs-list.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/261-enable_wilink_platform_without_drivers.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/270-platform-mikrotik-build-bits.patch (80%) rename target/linux/generic/{pending-6.0 => pending-6.1}/300-mips_expose_boot_raw.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/302-mips_no_branch_likely.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/305-mips_module_reloc.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/307-mips_highmem_offset.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/308-mips32r2_tune.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/310-arm_module_unresolved_weak_sym.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch (97%) rename target/linux/generic/{pending-6.0 => pending-6.1}/332-arc-add-OWRTDTB-section.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/333-arc-enable-unaligned-access-in-kernel-mode.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch (96%) rename target/linux/generic/{pending-6.0 => pending-6.1}/400-mtd-mtdsplit-support.patch (92%) create mode 100644 target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/420-mtd-redboot_space.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/430-mtd-add-myloader-partition-parser.patch (97%) rename target/linux/generic/{pending-6.0 => pending-6.1}/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/435-mtd-add-routerbootpart-parser-config.patch (93%) rename target/linux/generic/{pending-6.0 => pending-6.1}/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/465-m25p80-mx-disable-software-protection.patch (100%) create mode 100644 target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch create mode 100644 target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch create mode 100644 target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch create mode 100644 target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch create mode 100644 target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch create mode 100644 target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch create mode 100644 target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch create mode 100644 target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch (92%) rename target/linux/generic/{pending-6.0 => pending-6.1}/491-ubi-auto-create-ubiblock-device-for-rootfs.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch (72%) rename target/linux/generic/{pending-6.0 => pending-6.1}/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/494-mtd-ubi-add-EOF-marker-support.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch (100%) create mode 100644 target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch (94%) rename target/linux/generic/{pending-6.0 => pending-6.1}/500-fs_cdrom_dependencies.patch (73%) rename target/linux/generic/{pending-6.0 => pending-6.1}/530-jffs2_make_lzma_available.patch (99%) rename target/linux/generic/{pending-6.0 => pending-6.1}/532-jffs2_eofdetect.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/600-netfilter_conntrack_flush.patch (89%) rename target/linux/generic/{pending-6.0 => pending-6.1}/610-netfilter_match_bypass_default_checks.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/611-netfilter_match_bypass_default_table.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/612-netfilter_match_reduce_memory_access.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/613-netfilter_optional_tcp_window_check.patch (77%) rename target/linux/generic/{pending-6.0 => pending-6.1}/620-net_sched-codel-do-not-defer-queue-length-update.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/630-packet_socket_type.patch (95%) rename target/linux/generic/{pending-6.0 => pending-6.1}/655-increase_skb_pad.patch (91%) rename target/linux/generic/{pending-6.0 => pending-6.1}/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch (97%) rename target/linux/generic/{pending-6.0 => pending-6.1}/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch (99%) rename target/linux/generic/{pending-6.0 => pending-6.1}/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/680-NET-skip-GRO-for-foreign-MAC-addresses.patch (83%) rename target/linux/generic/{pending-6.0 => pending-6.1}/682-of_net-add-mac-address-increment-support.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/683-of_net-add-mac-address-to-of-tree.patch (51%) create mode 100644 target/linux/generic/pending-6.1/684-of_net-do-mac-address-increment-only-once.patch create mode 100644 target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch create mode 100644 target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/703-phy-add-detach-callback-to-struct-phy_driver.patch (90%) create mode 100644 target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch create mode 100644 target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch (94%) create mode 100644 target/linux/generic/pending-6.1/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/729-net-mtk_eth_soc-improve-comment.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch (100%) create mode 100644 target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch create mode 100644 target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch create mode 100644 target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch create mode 100644 target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch create mode 100644 target/linux/generic/pending-6.1/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch create mode 100644 target/linux/generic/pending-6.1/732-05-net-dsa-tag_mtk-assign-per-port-queues.patch create mode 100644 target/linux/generic/pending-6.1/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch create mode 100644 target/linux/generic/pending-6.1/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch create mode 100644 target/linux/generic/pending-6.1/732-08-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch create mode 100644 target/linux/generic/pending-6.1/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch create mode 100644 target/linux/generic/pending-6.1/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch create mode 100644 target/linux/generic/pending-6.1/732-11-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch create mode 100644 target/linux/generic/pending-6.1/732-12-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch create mode 100644 target/linux/generic/pending-6.1/732-13-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch create mode 100644 target/linux/generic/pending-6.1/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch create mode 100644 target/linux/generic/pending-6.1/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch create mode 100644 target/linux/generic/pending-6.1/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch create mode 100644 target/linux/generic/pending-6.1/733-03-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch create mode 100644 target/linux/generic/pending-6.1/733-04-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch create mode 100644 target/linux/generic/pending-6.1/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch (94%) rename target/linux/generic/{pending-6.0 => pending-6.1}/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch (98%) create mode 100644 target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/810-pci_disable_common_quirks.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/811-pci_disable_usb_common_quirks.patch (98%) rename target/linux/generic/{pending-6.0 => pending-6.1}/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch (100%) rename target/linux/generic/{pending-6.0 => pending-6.1}/834-ledtrig-libata.patch (92%) rename target/linux/generic/{pending-6.0 => pending-6.1}/840-hwrng-bcm2835-set-quality-to-1000.patch (100%) create mode 100644 target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch rename target/linux/generic/{pending-6.0 => pending-6.1}/920-mangle_bootargs.patch (91%) create mode 100644 target/linux/generic/pending-6.1/930-qcom-qmi-helpers.patch create mode 100644 target/linux/rockchip/armv8/config-6.1 rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3566-lubancat1.dts (100%) rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3566-lubancat1n.dts (100%) rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dts (100%) rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dtsi (100%) rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dts (100%) rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dtsi (100%) rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts (100%) rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3568-opc-h68k.dts (100%) rename target/linux/rockchip/{files => files-6.1}/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts (100%) delete mode 100644 target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3399-guangmiao-g4c.dts create mode 100644 target/linux/rockchip/patches-6.1/005-arm64-dts-rockchip-add-EEPROM-node-for-NanoPi-R4S.patch create mode 100644 target/linux/rockchip/patches-6.1/011-v6.2-net-phy-Add-driver-for-Motorcomm-yt8521.patch create mode 100644 target/linux/rockchip/patches-6.1/012-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch create mode 100644 target/linux/rockchip/patches-6.1/100-rockchip-use-system-LED-for-OpenWrt.patch create mode 100644 target/linux/rockchip/patches-6.1/101-arm64-rockchip-add-OF-node-for-USB-eth-on-NanoPi-R2S.patch create mode 100644 target/linux/rockchip/patches-6.1/103-nanopi-r4s-sd-signalling.patch create mode 100644 target/linux/rockchip/patches-6.1/104-rockchip-rock-pi-4.patch create mode 100644 target/linux/rockchip/patches-6.1/105-mmc-core-set-initial-signal-voltage-on-power-off.patch create mode 100644 target/linux/rockchip/patches-6.1/106-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch create mode 100644 target/linux/rockchip/patches-6.1/167-crypto-rockchip-use-dev_err-for-error-message-about-.patch create mode 100644 target/linux/rockchip/patches-6.1/168-crypto-rockchip-do-not-use-uninitialized-variable.patch create mode 100644 target/linux/rockchip/patches-6.1/169-crypto-rockchip-do-not-do-custom-power-management.patch create mode 100644 target/linux/rockchip/patches-6.1/170-crypto-rockchip-fix-privete-private-typo.patch create mode 100644 target/linux/rockchip/patches-6.1/171-crypto-rockchip-do-not-store-mode-globally.patch create mode 100644 target/linux/rockchip/patches-6.1/172-crypto-rockchip-add-fallback-for-cipher.patch create mode 100644 target/linux/rockchip/patches-6.1/173-crypto-rockchip-add-fallback-for-ahash.patch create mode 100644 target/linux/rockchip/patches-6.1/174-crypto-rockchip-better-handle-cipher-key.patch create mode 100644 target/linux/rockchip/patches-6.1/175-crypto-rockchip-remove-non-aligned-handling.patch create mode 100644 target/linux/rockchip/patches-6.1/176-crypto-rockchip-rework-by-using-crypto_engine.patch create mode 100644 target/linux/rockchip/patches-6.1/177-crypto-rockchip-rewrite-type.patch create mode 100644 target/linux/rockchip/patches-6.1/178-crypto-rockchip-add-debugfs.patch create mode 100644 target/linux/rockchip/patches-6.1/179-crypto-rockchip-introduce-PM.patch create mode 100644 target/linux/rockchip/patches-6.1/180-crypto-rockchip-handle-reset-also-in-PM.patch create mode 100644 target/linux/rockchip/patches-6.1/181-crypto-rockchip-use-clk_bulk-to-simplify-clock-manag.patch create mode 100644 target/linux/rockchip/patches-6.1/182-crypto-rockchip-add-myself-as-maintainer.patch create mode 100644 target/linux/rockchip/patches-6.1/183-crypto-rockchip-use-read_poll_timeout.patch create mode 100644 target/linux/rockchip/patches-6.1/184-crypto-rockchip-fix-style-issue.patch create mode 100644 target/linux/rockchip/patches-6.1/185-crypto-rockchip-add-support-for-rk3328.patch create mode 100644 target/linux/rockchip/patches-6.1/186-crypto-rockchip-rename-ablk-functions-to-cipher.patch create mode 100644 target/linux/rockchip/patches-6.1/187-crypto-rockchip-rework-rk_handle_req-function.patch create mode 100644 target/linux/rockchip/patches-6.1/188-crypto-rockchip-use-a-rk_crypto_info-variable-instea.patch create mode 100644 target/linux/rockchip/patches-6.1/189-crypto-rockchip-use-the-rk_crypto_info-given-as-para.patch create mode 100644 target/linux/rockchip/patches-6.1/190-dt-bindings-crypto-convert-rockchip-crypto-to-YAML.patch create mode 100644 target/linux/rockchip/patches-6.1/191-dt-bindings-crypto-rockchip-add-new-compatible.patch create mode 100644 target/linux/rockchip/patches-6.1/192-clk-rk3399-use-proper-crypto0-name.patch create mode 100644 target/linux/rockchip/patches-6.1/193-arm64-dts-rockchip-add-rk3328-crypto-node.patch create mode 100644 target/linux/rockchip/patches-6.1/194-arm64-dts-rockchip-rk3399-add-crypto-node.patch create mode 100644 target/linux/rockchip/patches-6.1/195-crypto-rockchip-store-crypto_info-in-request-context.patch create mode 100644 target/linux/rockchip/patches-6.1/196-crypto-rockchip-Check-for-clocks-numbers-and-their-f.patch create mode 100644 target/linux/rockchip/patches-6.1/197-crypto-rockchip-rk_ahash_reg_init-use-crypto_info-fr.patch create mode 100644 target/linux/rockchip/patches-6.1/198-crypto-rockchip-permit-to-have-more-than-one-reset.patch create mode 100644 target/linux/rockchip/patches-6.1/199-crypto-rockchip-Add-support-for-RK3399.patch create mode 100644 target/linux/rockchip/patches-6.1/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch create mode 100644 target/linux/rockchip/patches-6.1/202-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus.patch create mode 100644 target/linux/rockchip/patches-6.1/203-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch create mode 100644 target/linux/rockchip/patches-6.1/204-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch create mode 100644 target/linux/rockchip/patches-6.1/205-rockchip-rk3328-add-support-for-FriendlyARM-NanoPi-Neo3.patch create mode 100644 target/linux/rockchip/patches-6.1/210-rockchip-rk356x-add-support-for-new-boards.patch create mode 100644 target/linux/rockchip/patches-6.1/211-rockchip-rk3399-Add-support-for-EmbedFire-DoorNet2.patch create mode 100644 target/linux/rockchip/patches-6.1/212-arm64-dts-rockchip-fix-spdif-fe460000-ordering-on-rk.patch create mode 100644 target/linux/rockchip/patches-6.1/212-rockchip-rk3328-Add-support-for-EmbedFire-DoorNet1.patch create mode 100644 target/linux/rockchip/patches-6.1/213-arm64-dts-rockchip-RK356x-Add-I2S2-device-node.patch create mode 100644 target/linux/rockchip/patches-6.1/213-crypto-rockchip-move-kconfig-to-its-dedicated-direct.patch create mode 100644 target/linux/rockchip/patches-6.1/214-dt-bindings-crypto-add-support-for-rockchip-crypto-r.patch create mode 100644 target/linux/rockchip/patches-6.1/215-MAINTAINERS-add-new-dt-binding-doc-to-the-right-entr.patch create mode 100644 target/linux/rockchip/patches-6.1/216-crypto-rockchip-support-the-new-crypto-IP-for-rk3568.patch create mode 100644 target/linux/rockchip/patches-6.1/217-ARM64-dts-rk3568-add-crypto-node.patch create mode 100644 target/linux/rockchip/patches-6.1/218-fix-build-crypto.patch create mode 100644 target/linux/rockchip/patches-6.1/801-char-add-support-for-rockchip-hardware-random-number.patch create mode 100644 target/linux/rockchip/patches-6.1/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch create mode 100644 target/linux/rockchip/patches-6.1/803-PM-devfreq-rockchip-add-devfreq-driver-for-rk3328-dmc.patch create mode 100644 target/linux/rockchip/patches-6.1/804-clk-rockchip-support-setting-ddr-clock-via-SIP-Version-2-.patch create mode 100644 target/linux/rockchip/patches-6.1/805-PM-devfreq-rockchip-dfi-add-more-soc-support.patch create mode 100644 target/linux/rockchip/patches-6.1/806-arm64-dts-rockchip-rk3328-add-dfi-node.patch create mode 100644 target/linux/rockchip/patches-6.1/807-arm64-dts-nanopi-r2s-add-rk3328-dmc-relate-node.patch create mode 100644 target/linux/rockchip/patches-6.1/808-drv-net-phy-add-JLSemi-jl2xxx-driver.patch create mode 100644 target/linux/rockchip/patches-6.1/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch create mode 100644 target/linux/rockchip/patches-6.1/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz.patch diff --git a/include/kernel-6.0 b/include/kernel-6.0 deleted file mode 100644 index bcbf9c4fb..000000000 --- a/include/kernel-6.0 +++ /dev/null @@ -1,2 +0,0 @@ -LINUX_VERSION-6.0 = .10 -LINUX_KERNEL_HASH-6.0.10 = 39e57fcd84cd70bfa3e1a4185d3aa0ed7f1432f24c6548d16326b0c3c9541dd0 diff --git a/include/kernel-6.1 b/include/kernel-6.1 new file mode 100644 index 000000000..cc7e084e7 --- /dev/null +++ b/include/kernel-6.1 @@ -0,0 +1,2 @@ +LINUX_VERSION-6.1 = +LINUX_KERNEL_HASH-6.1 = 2ca1f17051a430f6fed1196e4952717507171acfd97d96577212502703b25deb diff --git a/include/netfilter.mk b/include/netfilter.mk index 044a97191..06246ecd1 100644 --- a/include/netfilter.mk +++ b/include/netfilter.mk @@ -221,11 +221,6 @@ $(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_IRC, $(P_XT)nf_connt $(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_IRC, $(P_XT)nf_nat_irc)) -# ulog - -$(eval $(call nf_add,IPT_ULOG,CONFIG_IP_NF_TARGET_ULOG, $(P_V4)ipt_ULOG)) - - # nflog $(eval $(call nf_add,IPT_NFLOG,CONFIG_NETFILTER_XT_TARGET_NFLOG, $(P_XT)xt_NFLOG)) @@ -311,7 +306,6 @@ $(eval $(call nf_add,EBTABLES_IP4,CONFIG_BRIDGE_EBT_SNAT, $(P_EBT)ebt_snat)) # watchers $(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_LOG, $(P_EBT)ebt_log)) -$(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_ULOG, $(P_EBT)ebt_ulog)) $(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_NFLOG, $(P_EBT)ebt_nflog)) $(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_NFQUEUE, $(P_EBT)ebt_nfqueue)) @@ -374,7 +368,6 @@ IPT_BUILTIN += $(IPT_NAT6-y) IPT_BUILTIN += $(IPT_NAT_EXTRA-y) IPT_BUILTIN += $(NF_NATHELPER-y) IPT_BUILTIN += $(NF_NATHELPER_EXTRA-y) -IPT_BUILTIN += $(IPT_ULOG-y) IPT_BUILTIN += $(IPT_TPROXY-y) IPT_BUILTIN += $(NFNETLINK-y) IPT_BUILTIN += $(NFNETLINK_LOG-y) diff --git a/package/kernel/linux/modules/crypto.mk b/package/kernel/linux/modules/crypto.mk index c7f66db70..165690c3b 100644 --- a/package/kernel/linux/modules/crypto.mk +++ b/package/kernel/linux/modules/crypto.mk @@ -447,32 +447,6 @@ endef $(eval $(call KernelPackage,crypto-kpp)) -define KernelPackage/crypto-lib-blake2s - TITLE:=BLAKE2s hash function library - KCONFIG:=CONFIG_CRYPTO_LIB_BLAKE2S - HIDDEN:=1 - FILES:= \ - $(LINUX_DIR)/lib/crypto/libblake2s.ko \ - $(LINUX_DIR)/lib/crypto/libblake2s-generic.ko - $(call AddDepends/crypto,+PACKAGE_kmod-crypto-hash:kmod-crypto-hash) -endef - -define KernelPackage/crypto-lib-blake2s/config - imply PACKAGE_kmod-crypto-hash -endef - -define KernelPackage/crypto-lib-blake2s/x86/64 - KCONFIG+=CONFIG_CRYPTO_BLAKE2S_X86 - FILES+=$(LINUX_DIR)/arch/x86/crypto/blake2s-x86_64.ko -endef - -define KernelPackage/crypto-lib-blake2s/arm - KCONFIG+=CONFIG_CRYPTO_BLAKE2S_ARM - FILES+=$(LINUX_DIR)/arch/arm/crypto/blake2s-arm.ko -endef - -$(eval $(call KernelPackage,crypto-lib-blake2s)) - define KernelPackage/crypto-lib-chacha20 TITLE:=ChaCha library interface diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk index 77c61283e..7e3830da2 100644 --- a/package/kernel/linux/modules/fs.mk +++ b/package/kernel/linux/modules/fs.mk @@ -109,9 +109,9 @@ define KernelPackage/fs-cifs +kmod-crypto-ccm \ +kmod-crypto-ecb \ +kmod-crypto-des \ - +(LINUX_5_15||LINUX_6_0):kmod-asn1-decoder \ - +(LINUX_5_15||LINUX_6_0):kmod-oid-registry \ - +(LINUX_5_15||LINUX_6_0):kmod-dnsresolver + +(LINUX_5_15||LINUX_6_1):kmod-asn1-decoder \ + +(LINUX_5_15||LINUX_6_1):kmod-oid-registry \ + +(LINUX_5_15||LINUX_6_1):kmod-dnsresolver endef define KernelPackage/fs-cifs/description @@ -530,7 +530,7 @@ $(eval $(call KernelPackage,fs-ntfs)) define KernelPackage/fs-ntfs3 SUBMENU:=$(FS_MENU) TITLE:=NTFS3 Read-Write file system support - DEPENDS:=@(LINUX_5_4||LINUX_5_10||LINUX_5_15||LINUX_6_0) +kmod-nls-base + DEPENDS:= +kmod-nls-base KCONFIG:= \ CONFIG_NTFS3_FS \ CONFIG_NTFS3_64BIT_CLUSTER=y \ diff --git a/package/kernel/linux/modules/lib.mk b/package/kernel/linux/modules/lib.mk index 103cba642..bbd1fa81e 100644 --- a/package/kernel/linux/modules/lib.mk +++ b/package/kernel/linux/modules/lib.mk @@ -134,6 +134,7 @@ define KernelPackage/lib-zstd $(LINUX_DIR)/crypto/zstd.ko \ $(LINUX_DIR)/lib/xxhash.ko \ $(LINUX_DIR)/lib/zstd/zstd_compress.ko \ + $(LINUX_DIR)/lib/zstd/zstd_common.ko@ge6.1 \ $(LINUX_DIR)/lib/zstd/zstd_decompress.ko AUTOLOAD:=$(call AutoProbe,xxhash zstd zstd_compress zstd_decompress) endef @@ -151,13 +152,15 @@ define KernelPackage/lib-lz4 DEPENDS:=+kmod-crypto-acompress KCONFIG:= \ CONFIG_CRYPTO_LZ4 \ + CONFIG_CRYPTO_LZ4HC \ CONFIG_LZ4_COMPRESS \ CONFIG_LZ4_DECOMPRESS FILES:= \ $(LINUX_DIR)/crypto/lz4.ko \ $(LINUX_DIR)/lib/lz4/lz4_compress.ko \ + $(LINUX_DIR)/lib/lz4/lz4hc_compress.ko \ $(LINUX_DIR)/lib/lz4/lz4_decompress.ko - AUTOLOAD:=$(call AutoProbe,lz4 lz4_compress lz4_decompress) + AUTOLOAD:=$(call AutoProbe,lz4 lz4_compress lz4hc_compress lz4_decompress) endef define KernelPackage/lib-lz4/description diff --git a/package/kernel/linux/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk index 2753f67f5..90185a92b 100644 --- a/package/kernel/linux/modules/netdevices.mk +++ b/package/kernel/linux/modules/netdevices.mk @@ -142,7 +142,7 @@ $(eval $(call KernelPackage,mii)) define KernelPackage/mdio-devres SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Supports MDIO device registration - DEPENDS:=@(LINUX_5_10||LINUX_5_15||LINUX_6_0) +kmod-libphy +(TARGET_armvirt||TARGET_bcm27xx_bcm2708||TARGET_tegra):kmod-of-mdio + DEPENDS:=@(LINUX_5_10||LINUX_5_15||LINUX_6_1) +kmod-libphy +(TARGET_armvirt||TARGET_bcm27xx_bcm2708||TARGET_tegra):kmod-of-mdio KCONFIG:=CONFIG_MDIO_DEVRES HIDDEN:=1 FILES:=$(LINUX_DIR)/drivers/net/phy/mdio_devres.ko @@ -597,7 +597,7 @@ $(eval $(call KernelPackage,8139cp)) define KernelPackage/r8169 SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=RealTek RTL-8169 PCI Gigabit Ethernet Adapter kernel support - DEPENDS:=@PCI_SUPPORT +kmod-mii +r8169-firmware +kmod-phy-realtek +(LINUX_5_10||LINUX_5_15||LINUX_6_0):kmod-mdio-devres + DEPENDS:=@PCI_SUPPORT +kmod-mii +r8169-firmware +kmod-phy-realtek +(LINUX_5_10||LINUX_5_15||LINUX_6_1):kmod-mdio-devres KCONFIG:= \ CONFIG_R8169 \ CONFIG_R8169_NAPI=y \ @@ -723,7 +723,7 @@ $(eval $(call KernelPackage,igbvf)) define KernelPackage/ixgbe SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Intel(R) 82598/82599 PCI-Express 10 Gigabit Ethernet support - DEPENDS:=@PCI_SUPPORT +kmod-mdio +kmod-ptp +kmod-hwmon-core +kmod-libphy +(LINUX_5_10||LINUX_5_15||LINUX_6_0):kmod-mdio-devres + DEPENDS:=@PCI_SUPPORT +kmod-mdio +kmod-ptp +kmod-hwmon-core +kmod-libphy +(LINUX_5_10||LINUX_5_15||LINUX_6_1):kmod-mdio-devres KCONFIG:=CONFIG_IXGBE \ CONFIG_IXGBE_VXLAN=n \ CONFIG_IXGBE_HWMON=y \ diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk index cd01b328c..34b1fd3a1 100644 --- a/package/kernel/linux/modules/netfilter.mk +++ b/package/kernel/linux/modules/netfilter.mk @@ -604,23 +604,6 @@ endef $(eval $(call KernelPackage,nf-nathelper-extra)) -define KernelPackage/ipt-ulog - TITLE:=Module for user-space packet logging - KCONFIG:=$(KCONFIG_IPT_ULOG) - FILES:=$(foreach mod,$(IPT_ULOG-m),$(LINUX_DIR)/net/$(mod).ko) - AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_ULOG-m))) - $(call AddDepends/ipt) -endef - -define KernelPackage/ipt-ulog/description - Netfilter (IPv4) module for user-space packet logging - Includes: - - ULOG -endef - -$(eval $(call KernelPackage,ipt-ulog)) - - define KernelPackage/ipt-nflog TITLE:=Module for user-space packet logging KCONFIG:=$(KCONFIG_IPT_NFLOG) diff --git a/package/kernel/linux/modules/netsupport.mk b/package/kernel/linux/modules/netsupport.mk index bad0daef2..89b07470a 100644 --- a/package/kernel/linux/modules/netsupport.mk +++ b/package/kernel/linux/modules/netsupport.mk @@ -565,6 +565,23 @@ endef $(eval $(call KernelPackage,veth)) +define KernelPackage/vrf + SUBMENU:=$(NETWORK_SUPPORT_MENU) + TITLE:=Virtual Routing and Forwarding (Lite) + DEPENDS:=@KERNEL_NET_L3_MASTER_DEV + KCONFIG:=CONFIG_NET_VRF + FILES:=$(LINUX_DIR)/drivers/net/vrf.ko + AUTOLOAD:=$(call AutoLoad,30,vrf) +endef + +define KernelPackage/vrf/description + This option enables the support for mapping interfaces into VRF's. The + support enables VRF devices. +endef + +$(eval $(call KernelPackage,vrf)) + + define KernelPackage/slhc SUBMENU:=$(NETWORK_SUPPORT_MENU) HIDDEN:=1 @@ -1296,7 +1313,6 @@ define KernelPackage/wireguard SUBMENU:=$(NETWORK_SUPPORT_MENU) TITLE:=WireGuard secure network tunnel DEPENDS:= \ - +kmod-crypto-lib-blake2s \ +kmod-crypto-lib-chacha20poly1305 \ +kmod-crypto-lib-curve25519 \ +kmod-udptunnel4 \ @@ -1340,11 +1356,11 @@ define KernelPackage/qrtr SUBMENU:=$(NETWORK_SUPPORT_MENU) TITLE:=Qualcomm IPC Router support HIDDEN:=1 - DEPENDS:=@(LINUX_5_15||LINUX_6_0) + DEPENDS:=@(LINUX_5_15||LINUX_6_1) KCONFIG:=CONFIG_QRTR FILES:= \ $(LINUX_DIR)/net/qrtr/qrtr.ko \ - $(LINUX_DIR)/net/qrtr/ns.ko + $(LINUX_DIR)/net/qrtr/ns.ko@lt6.0 AUTOLOAD:=$(call AutoProbe,qrtr) endef diff --git a/package/kernel/linux/modules/other.mk b/package/kernel/linux/modules/other.mk index 311048b28..eeb5f0960 100644 --- a/package/kernel/linux/modules/other.mk +++ b/package/kernel/linux/modules/other.mk @@ -916,6 +916,10 @@ define KernelPackage/zram/config bool "lz4" select PACKAGE_kmod-lib-lz4 + config ZRAM_DEF_COMP_LZ4HC + bool "lz4-hc" + select PACKAGE_kmod-lib-lz4hc + config ZRAM_DEF_COMP_ZSTD bool "zstd" select PACKAGE_kmod-lib-zstd @@ -1136,8 +1140,8 @@ $(eval $(call KernelPackage,keys-trusted)) define KernelPackage/tpm SUBMENU:=$(OTHER_MENU) TITLE:=TPM Hardware Support - DEPENDS:= +kmod-random-core +(LINUX_5_15||LINUX_6_0):kmod-asn1-decoder \ - +(LINUX_5_15||LINUX_6_0):kmod-asn1-encoder +(LINUX_5_15||LINUX_6_0):kmod-oid-registry + DEPENDS:= +kmod-random-core +(LINUX_5_15||LINUX_6_1):kmod-asn1-decoder \ + +(LINUX_5_15||LINUX_6_1):kmod-asn1-encoder +(LINUX_5_15||LINUX_6_1):kmod-oid-registry KCONFIG:= CONFIG_TCG_TPM FILES:= $(LINUX_DIR)/drivers/char/tpm/tpm.ko AUTOLOAD:=$(call AutoLoad,10,tpm,1) @@ -1283,7 +1287,7 @@ $(eval $(call KernelPackage,qcom-qmi-helpers)) define KernelPackage/mhi SUBMENU:=$(OTHER_MENU) TITLE:=Modem Host Interface (MHI) bus - DEPENDS:=@(LINUX_5_15||LINUX_6_0) + DEPENDS:=@(LINUX_5_15||LINUX_6_1) KCONFIG:=CONFIG_MHI_BUS \ CONFIG_MHI_BUS_DEBUG=y \ CONFIG_MHI_BUS_PCI_GENERIC=n \ diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk index 4a686d1dd..85c869c04 100644 --- a/package/kernel/linux/modules/usb.mk +++ b/package/kernel/linux/modules/usb.mk @@ -1138,7 +1138,8 @@ $(eval $(call KernelPackage,usb-net-aqc111)) define KernelPackage/usb-net-asix TITLE:=Kernel module for USB-to-Ethernet Asix convertors - DEPENDS:=+kmod-libphy +(LINUX_5_15||LINUX_6_0):kmod-mdio-devres + DEPENDS:=+(LINUX_5_4||LINUX_5_10):kmod-libphy \ + +(LINUX_5_15||LINUX_6_1):kmod-mdio-devres +LINUX_6_1:kmod-phylink KCONFIG:=CONFIG_USB_NET_AX8817X FILES:= \ $(LINUX_DIR)/drivers/$(USBNET_DIR)/asix.ko \ @@ -1153,7 +1154,6 @@ endef $(eval $(call KernelPackage,usb-net-asix)) - define KernelPackage/usb-net-asix-ax88179 TITLE:=Kernel module for USB-to-Gigabit-Ethernet Asix convertors DEPENDS:=+kmod-libphy diff --git a/package/kernel/linux/modules/video.mk b/package/kernel/linux/modules/video.mk index 2291c3304..7b63abc9a 100644 --- a/package/kernel/linux/modules/video.mk +++ b/package/kernel/linux/modules/video.mk @@ -28,7 +28,9 @@ define KernelPackage/backlight CONFIG_BACKLIGHT_ADP8870=n \ CONFIG_BACKLIGHT_OT200=n \ CONFIG_BACKLIGHT_PM8941_WLED=n - FILES:=$(LINUX_DIR)/drivers/video/backlight/backlight.ko + FILES:=$(LINUX_DIR)/drivers/video/backlight/backlight.ko \ + $(LINUX_DIR)/drivers/acpi/video.ko@ge6.1 \ + $(LINUX_DIR)/drivers/platform/x86/wmi.ko@ge6.1 AUTOLOAD:=$(call AutoProbe,video backlight) endef @@ -243,8 +245,8 @@ define KernelPackage/drm SUBMENU:=$(VIDEO_MENU) TITLE:=Direct Rendering Manager (DRM) support HIDDEN:=1 - DEPENDS:=+kmod-dma-buf +kmod-i2c-core +kmod-i2c-algo-bit +PACKAGE_kmod-backlight:kmod-backlight \ - +(LINUX_5_15||LINUX_6_0):kmod-fb + DEPENDS:=+kmod-dma-buf +kmod-i2c-core +kmod-i2c-algo-bit +kmod-backlight \ + +(LINUX_5_15||LINUX_6_1):kmod-fb KCONFIG:= \ CONFIG_DRM \ CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y \ @@ -266,7 +268,7 @@ $(eval $(call KernelPackage,drm)) define KernelPackage/drm-buddy SUBMENU:=$(VIDEO_MENU) TITLE:=A page based buddy allocator - DEPENDS:=@TARGET_x86 @DISPLAY_SUPPORT +kmod-drm @(LINUX_6_0) + DEPENDS:=@TARGET_x86 @DISPLAY_SUPPORT +kmod-drm @LINUX_6_1 KCONFIG:=CONFIG_DRM_BUDDY FILES:= $(LINUX_DIR)/drivers/gpu/drm/drm_buddy.ko AUTOLOAD:=$(call AutoProbe,drm_buddy) @@ -311,7 +313,7 @@ $(eval $(call KernelPackage,drm-kms-helper)) define KernelPackage/drm-display-helper SUBMENU:=$(VIDEO_MENU) TITLE:=DRM helpers for display adapters drivers - DEPENDS:=@DISPLAY_SUPPORT +kmod-drm +TARGET_x86:kmod-drm-buddy @(LINUX_6_0) + DEPENDS:=@DISPLAY_SUPPORT +kmod-drm +TARGET_x86:kmod-drm-buddy @LINUX_6_1 KCONFIG:=CONFIG_DRM_DISPLAY_HELPER FILES:=$(LINUX_DIR)/drivers/gpu/drm/display/drm_display_helper.ko AUTOLOAD:=$(call AutoProbe,drm_display_helper) @@ -328,7 +330,7 @@ define KernelPackage/drm-amdgpu TITLE:=AMDGPU DRM support DEPENDS:=@TARGET_x86 @DISPLAY_SUPPORT +kmod-backlight +kmod-drm-ttm \ +kmod-drm-kms-helper +kmod-i2c-algo-bit +amdgpu-firmware \ - +(LINUX_6_0):kmod-drm-display-helper + +LINUX_6_1:kmod-drm-display-helper KCONFIG:=CONFIG_DRM_AMDGPU \ CONFIG_DRM_AMDGPU_SI=y \ CONFIG_DRM_AMDGPU_CIK=y \ @@ -1103,7 +1105,7 @@ define KernelPackage/drm-i915 SUBMENU:=$(VIDEO_MENU) TITLE:=Intel GPU drm support DEPENDS:=@TARGET_x86 +kmod-drm-ttm +kmod-drm-kms-helper +i915-firmware \ - +(LINUX_6_0):kmod-drm-display-helper + +LINUX_6_1:kmod-drm-display-helper KCONFIG:= \ CONFIG_INTEL_GTT \ CONFIG_DRM_I915 \ diff --git a/package/lean/r8125/Makefile b/package/kernel/r8125/Makefile similarity index 100% rename from package/lean/r8125/Makefile rename to package/kernel/r8125/Makefile diff --git a/package/lean/r8125/patches/010-config.patch b/package/kernel/r8125/patches/010-config.patch similarity index 100% rename from package/lean/r8125/patches/010-config.patch rename to package/kernel/r8125/patches/010-config.patch diff --git a/package/lean/r8125/patches/020-5.19-support.patch b/package/kernel/r8125/patches/020-5.19-support.patch similarity index 100% rename from package/lean/r8125/patches/020-5.19-support.patch rename to package/kernel/r8125/patches/020-5.19-support.patch diff --git a/package/lean/r8125/patches/030-add-LED-configuration-from-OF.patch b/package/kernel/r8125/patches/030-add-LED-configuration-from-OF.patch similarity index 100% rename from package/lean/r8125/patches/030-add-LED-configuration-from-OF.patch rename to package/kernel/r8125/patches/030-add-LED-configuration-from-OF.patch diff --git a/package/lean/r8152/Makefile b/package/kernel/r8152/Makefile similarity index 92% rename from package/lean/r8152/Makefile rename to package/kernel/r8152/Makefile index 2573b6624..5921bdcc7 100644 --- a/package/lean/r8152/Makefile +++ b/package/kernel/r8152/Makefile @@ -7,12 +7,12 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=r8152 -PKG_VERSION:=2.16.1 -PKG_RELEASE:=1 +PKG_VERSION:=2.16.3.20220914 +PKG_RELEASE:=3 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/wget/realtek-r8152-linux/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=2be6a02f6e29485efd107bb7e777ad3c482d9db0ff7e5e6c5ef034a1557a395b +PKG_HASH:=61ed7af34c8882c6028ddd1a27bb78fb5bfba41211f84dd7a06e4dc84dbe9a9a PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/realtek-$(PKG_NAME)-linux-$(PKG_VERSION) diff --git a/package/lean/r8152/patches/010-5.19-support.patch b/package/kernel/r8152/patches/010-5.19-support.patch similarity index 100% rename from package/lean/r8152/patches/010-5.19-support.patch rename to package/kernel/r8152/patches/010-5.19-support.patch diff --git a/package/kernel/r8152/patches/020-6.1-support.patch b/package/kernel/r8152/patches/020-6.1-support.patch new file mode 100644 index 000000000..756aba51f --- /dev/null +++ b/package/kernel/r8152/patches/020-6.1-support.patch @@ -0,0 +1,38 @@ +--- a/compatibility.h ++++ b/compatibility.h +@@ -237,9 +237,15 @@ + #define napi_disable(napi_ptr) netif_poll_disable(container_of(napi_ptr, struct r8152, napi)->netdev) + #define napi_schedule(napi_ptr) netif_rx_schedule(container_of(napi_ptr, struct r8152, napi)->netdev) + #define napi_complete(napi_ptr) netif_rx_complete(container_of(napi_ptr, struct r8152, napi)->netdev) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++ #define netif_napi_add_weight(ndev, napi_ptr, function, weight_t) \ ++ ndev->poll = function; \ ++ ndev->weight = weight_t; ++#else + #define netif_napi_add(ndev, napi_ptr, function, weight_t) \ + ndev->poll = function; \ + ndev->weight = weight_t; ++#endif + typedef unsigned long uintptr_t; + #define DMA_BIT_MASK(value) \ + (value < 64 ? ((1ULL << value) - 1) : 0xFFFFFFFFFFFFFFFFULL) +--- a/r8152.c ++++ b/r8152.c +@@ -20718,10 +20718,17 @@ + + usb_set_intfdata(intf, tp); + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++ if (tp->support_2500full) ++ netif_napi_add_weight(netdev, &tp->napi, r8152_poll, 256); ++ else ++ netif_napi_add_weight(netdev, &tp->napi, r8152_poll, 64); ++#else + if (tp->support_2500full) + netif_napi_add(netdev, &tp->napi, r8152_poll, 256); + else + netif_napi_add(netdev, &tp->napi, r8152_poll, 64); ++#endif + + ret = register_netdev(netdev); + if (ret != 0) { diff --git a/package/kernel/r8168/Makefile b/package/kernel/r8168/Makefile index 1258fc904..8f810c518 100644 --- a/package/kernel/r8168/Makefile +++ b/package/kernel/r8168/Makefile @@ -7,13 +7,13 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=r8168 -PKG_VERSION:=8.050.03 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=8.051.02 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/BROBIRD/openwrt-r8168.git -PKG_SOURCE_VERSION:=ddfaceacd1b7ed2857fb995642a8ffb1fc37e989 -PKG_MIRROR_HASH:=5428f60dc33e9503c6cfdf690c00077149dce24cbb0591129d905b9f1aad9202 +PKG_SOURCE_VERSION:=4f6cfe1ca12fb772deed57f1d2d1062af041ad07 +PKG_MIRROR_HASH:=6b149f5eb3b9e1dc50867a694984d253aa58d97dd5fbab30eb405d2d7b2be587 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) diff --git a/package/kernel/r8168/patches/001-r8168-add-LED-configuration-from-OF.patch b/package/kernel/r8168/patches/001-r8168-add-LED-configuration-from-OF.patch index f49842442..891cabe76 100644 --- a/package/kernel/r8168/patches/001-r8168-add-LED-configuration-from-OF.patch +++ b/package/kernel/r8168/patches/001-r8168-add-LED-configuration-from-OF.patch @@ -8,7 +8,7 @@ #include #include #include -@@ -24643,6 +24644,22 @@ rtl8168_set_bios_setting(struct net_devi +@@ -24769,6 +24770,22 @@ rtl8168_set_bios_setting(struct net_devi } } @@ -31,7 +31,7 @@ static void rtl8168_init_software_variable(struct net_device *dev) { -@@ -25206,6 +25223,8 @@ rtl8168_init_software_variable(struct ne +@@ -25343,6 +25360,8 @@ rtl8168_init_software_variable(struct ne tp->NotWrMcuPatchCode = TRUE; } diff --git a/package/kernel/r8168/patches/020-5.18-support.patch b/package/kernel/r8168/patches/020-5.18-support.patch deleted file mode 100644 index 499389274..000000000 --- a/package/kernel/r8168/patches/020-5.18-support.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/src/r8168_n.c -+++ b/src/r8168_n.c -@@ -3715,7 +3715,11 @@ - txd->opts2 = 0; - while (1) { - memset(tmpAddr, pattern++, len - 14); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0) - pci_dma_sync_single_for_device(tp->pci_dev, -+#else -+ dma_sync_single_for_device(tp_to_dev(tp), -+#endif - le64_to_cpu(mapping), - len, DMA_TO_DEVICE); - txd->opts1 = cpu_to_le32(DescOwn | FirstFrag | LastFrag | len); -@@ -3743,7 +3747,11 @@ - if (rx_len == len) { - dma_sync_single_for_cpu(tp_to_dev(tp), le64_to_cpu(rxd->addr), tp->rx_buf_sz, DMA_FROM_DEVICE); - i = memcmp(skb->data, rx_skb->data, rx_len); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0) - pci_dma_sync_single_for_device(tp->pci_dev, le64_to_cpu(rxd->addr), tp->rx_buf_sz, DMA_FROM_DEVICE); -+#else -+ dma_sync_single_for_device(tp_to_dev(tp), le64_to_cpu(rxd->addr), tp->rx_buf_sz, DMA_FROM_DEVICE); -+#endif - if (i == 0) { - // dev_printk(KERN_INFO, tp_to_dev(tp), "loopback test finished\n",rx_len,len); - break; -@@ -26464,11 +26472,20 @@ - - if ((sizeof(dma_addr_t) > 4) && - use_dac && -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0) - !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && - !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { -+#else -+ !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && -+ !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { -+#endif - dev->features |= NETIF_F_HIGHDMA; - } else { -+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0) - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); -+#else -+ rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); -+#endif - if (rc < 0) { - #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) - if (netif_msg_probe(tp)) diff --git a/package/kernel/r8168/patches/030-5.19-support.patch b/package/kernel/r8168/patches/020-5.19-support.patch similarity index 100% rename from package/kernel/r8168/patches/030-5.19-support.patch rename to package/kernel/r8168/patches/020-5.19-support.patch diff --git a/package/kernel/r8168/patches/030-6.1-support.patch b/package/kernel/r8168/patches/030-6.1-support.patch new file mode 100644 index 000000000..44ab2be19 --- /dev/null +++ b/package/kernel/r8168/patches/030-6.1-support.patch @@ -0,0 +1,14 @@ +--- a/src/r8168.h +--- b/src/r8168.h +@@ -566,7 +566,11 @@ + typedef struct napi_struct *napi_ptr; + typedef int napi_budget; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add_weight(ndev, &priv->napi, function, weight) ++#else + #define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight) ++#endif + #define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget) + #define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr) + #define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev; diff --git a/package/lean/openwrt-fullconenat/patches/0001-fix-nf_conntrack_register_notifier.patch b/package/lean/openwrt-fullconenat/patches/0001-fix-nf_conntrack_register_notifier.patch deleted file mode 100644 index 4ff41f5e1..000000000 --- a/package/lean/openwrt-fullconenat/patches/0001-fix-nf_conntrack_register_notifier.patch +++ /dev/null @@ -1,25 +0,0 @@ -From ea9e2477624adaa40e8a553ef876f60ec8d3150c Mon Sep 17 00:00:00 2001 -From: W_Y_CPP <383152993@qq.com> -Date: Fri, 18 Feb 2022 00:53:12 -0500 -Subject: [PATCH] refresh - ---- - xt_FULLCONENAT.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/xt_FULLCONENAT.c b/xt_FULLCONENAT.c -index f96cfd8a3..237666039 100644 ---- a/xt_FULLCONENAT.c -+++ b/xt_FULLCONENAT.c -@@ -1258,8 +1258,7 @@ static int fullconenat_tg_check(const struct xt_tgchk_param *par) - #endif - - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) && !defined(CONFIG_NF_CONNTRACK_CHAIN_EVENTS) -- if (!READ_ONCE(par->net->ct.nf_conntrack_event_cb)) { -- nf_conntrack_register_notifier(par->net, &ct_event_notifier); -+ if (!READ_ONCE(par->net->ct.nf_conntrack_event_cb)&&(nf_conntrack_register_notifier(par->net, &ct_event_notifier)==0)) { - #else - if (nf_conntrack_register_notifier(par->net, &ct_event_notifier) == 0) { - #endif --- -2.17.1 diff --git a/package/network/config/firewall/Makefile b/package/network/config/firewall/Makefile index 0c55227c3..d7470f23b 100644 --- a/package/network/config/firewall/Makefile +++ b/package/network/config/firewall/Makefile @@ -13,9 +13,9 @@ PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/firewall3.git -PKG_SOURCE_DATE:=2022-01-10 -PKG_SOURCE_VERSION:=0f16ea5f055722a532d4e68c7ba34ed084b48b37 -PKG_MIRROR_HASH:=219478ef95b170b5122030715eac7b3317f2ac4d67e1a936c22a78b10e056123 +PKG_SOURCE_DATE:=2021-03-23 +PKG_SOURCE_VERSION:=61db17edddb1f05e8107f0dbef6f7d060ce67483 +PKG_MIRROR_HASH:=b2eb09816640e14e2dae21fb54ea05c33858fe0004844fe8d99e541a2e19e9c0 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC @@ -59,4 +59,4 @@ define Package/firewall/install $(INSTALL_CONF) $(PKG_BUILD_DIR)/helpers.conf $(1)/usr/share/fw3 endef -$(eval $(call BuildPackage,firewall)) \ No newline at end of file +$(eval $(call BuildPackage,firewall)) diff --git a/package/network/config/firewall/files/firewall.config b/package/network/config/firewall/files/firewall.config index 42f6f6aa3..cdb4d0880 100644 --- a/package/network/config/firewall/files/firewall.config +++ b/package/network/config/firewall/files/firewall.config @@ -3,7 +3,7 @@ config defaults option input ACCEPT option output ACCEPT option forward REJECT - option fullcone 0 + option fullcone 2 # Uncomment this line to disable ipv6 rules # option disable_ipv6 1 diff --git a/package/network/config/firewall/patches/001-firewall3-fix-locking-issue.patch b/package/network/config/firewall/patches/001-firewall3-fix-locking-issue.patch new file mode 100644 index 000000000..8657b5c71 --- /dev/null +++ b/package/network/config/firewall/patches/001-firewall3-fix-locking-issue.patch @@ -0,0 +1,38 @@ +From df1306a96127e91ff2d513a0a67345baaf61d113 Mon Sep 17 00:00:00 2001 +From: Florian Eckert +Date: Fri, 19 Nov 2021 09:51:02 +0100 +Subject: [PATCH] firewall3: fix locking issue + +By calling the command 'fw3 reload' several times at the same time, I +noticed that the locking was not working properly. It happened from time +to time that some firewall rules were present twice in the system! + +By removing the 'unlink' systemcall, this error no longer occurred on my +systems. + +Since fw3 does not run as a service, it makes no sense to delete this +lock file every time a filehandler is no longer open on this lock file, +because fw3 binary is not running. + +If fw3 does run as a service then we can remove this lock file on +service stop. But this is not the case for fw3. + +Signed-off-by: Florian Eckert +--- + utils.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/utils.c b/utils.c +index 17d5bf9..92e966c 100644 +--- a/utils.c ++++ b/utils.c +@@ -397,7 +397,6 @@ fw3_unlock_path(int *fd, const char *lockpath) + warn("Cannot release exclusive lock: %s", strerror(errno)); + + close(*fd); +- unlink(FW3_LOCKFILE); + + *fd = -1; + } +-- +2.30.2 diff --git a/package/lean/openwrt-fullconenat/Makefile b/package/network/services/fullconenat/Makefile similarity index 77% rename from package/lean/openwrt-fullconenat/Makefile rename to package/network/services/fullconenat/Makefile index 3036baf24..d49155c7e 100644 --- a/package/lean/openwrt-fullconenat/Makefile +++ b/package/network/services/fullconenat/Makefile @@ -1,15 +1,14 @@ # -# Copyright (C) 2018 Chion Tang +# Copyright (C) 2022 Chion Tang # # 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:=fullconenat -PKG_RELEASE:=6 +PKG_RELEASE:=9 PKG_SOURCE_DATE:=2022-02-13 PKG_SOURCE_PROTO:=git @@ -19,7 +18,9 @@ PKG_MIRROR_HASH:=00d749235271dee194dcd23c22e6e85207ea90192a62a110b2af0b4e4de1971 PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Chion Tang +include $(INCLUDE_DIR)/kernel.mk include $(INCLUDE_DIR)/package.mk define Package/iptables-mod-fullconenat @@ -28,7 +29,6 @@ define Package/iptables-mod-fullconenat CATEGORY:=Network TITLE:=FULLCONENAT iptables extension DEPENDS:=+iptables +kmod-ipt-fullconenat - MAINTAINER:=Chion Tang endef define Package/iptables-mod-fullconenat/install @@ -40,7 +40,6 @@ define KernelPackage/ipt-fullconenat SUBMENU:=Netfilter Extensions TITLE:=FULLCONENAT netfilter module DEPENDS:=+kmod-nf-ipt +kmod-nf-nat - MAINTAINER:=Chion Tang KCONFIG:= \ CONFIG_NF_CONNTRACK_EVENTS=y \ CONFIG_NF_CONNTRACK_CHAIN_EVENTS=y @@ -49,20 +48,15 @@ endef include $(INCLUDE_DIR)/kernel-defaults.mk -define Build/Prepare - $(call Build/Prepare/Default) - $(CP) ./files/Makefile $(PKG_BUILD_DIR)/ -endef - define Build/Compile +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ - CROSS_COMPILE="$(TARGET_CROSS)" \ - ARCH="$(LINUX_KARCH)" \ - M="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="$(BUILDFLAGS)" \ - modules + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(BUILDFLAGS)" \ + modules $(call Build/Compile/Default) endef -$(eval $(call BuildPackage,iptables-mod-fullconenat)) $(eval $(call KernelPackage,ipt-fullconenat)) +$(eval $(call BuildPackage,iptables-mod-fullconenat)) diff --git a/package/network/services/fullconenat/patches/001-linux-6.1-support.patch b/package/network/services/fullconenat/patches/001-linux-6.1-support.patch new file mode 100644 index 000000000..41721fb5c --- /dev/null +++ b/package/network/services/fullconenat/patches/001-linux-6.1-support.patch @@ -0,0 +1,26 @@ +--- a/xt_FULLCONENAT.c ++++ b/xt_FULLCONENAT.c +@@ -325,7 +325,11 @@ + /* for now we do the same thing for both --random and --random-fully */ + + /* select a random starting point */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++ start = (uint16_t)(get_random_u32() % (u32)range_size); ++#else + start = (uint16_t)(prandom_u32() % (u32)range_size); ++#endif + } else { + + if ((original_port >= min && original_port <= min + range_size - 1) +@@ -995,7 +999,11 @@ + /* for now we do the same thing for both --random and --random-fully */ + + /* select a random starting point */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++ start = (uint16_t)(get_random_u32() % (u32)range_size); ++#else + start = (uint16_t)(prandom_u32() % (u32)range_size); ++#endif + } else { + + if ((original_port >= min && original_port <= min + range_size - 1) diff --git a/package/lean/openwrt-fullconenat/files/Makefile b/package/network/services/fullconenat/src/Makefile similarity index 100% rename from package/lean/openwrt-fullconenat/files/Makefile rename to package/network/services/fullconenat/src/Makefile diff --git a/package/network/utils/iptables/Makefile b/package/network/utils/iptables/Makefile index a04eb1327..bd9d20d16 100644 --- a/package/network/utils/iptables/Makefile +++ b/package/network/utils/iptables/Makefile @@ -222,19 +222,6 @@ iptables extensions for extra NAT targets. - NETMAP endef -define Package/iptables-mod-ulog -$(call Package/iptables/Module, +kmod-ipt-ulog) - TITLE:=user-space packet logging -endef - -define Package/iptables-mod-ulog/description -iptables extensions for user-space packet logging. - - Targets: - - ULOG - -endef - define Package/iptables-mod-nflog $(call Package/iptables/Module, +kmod-nfnetlink-log +kmod-ipt-nflog) TITLE:=Netfilter NFLOG target @@ -674,7 +661,6 @@ $(eval $(call BuildPlugin,iptables-mod-nat-extra,$(IPT_NAT_EXTRA-m))) $(eval $(call BuildPlugin,iptables-mod-iprange,$(IPT_IPRANGE-m))) $(eval $(call BuildPlugin,iptables-mod-cluster,$(IPT_CLUSTER-m))) $(eval $(call BuildPlugin,iptables-mod-clusterip,$(IPT_CLUSTERIP-m))) -$(eval $(call BuildPlugin,iptables-mod-ulog,$(IPT_ULOG-m))) $(eval $(call BuildPlugin,iptables-mod-hashlimit,$(IPT_HASHLIMIT-m))) $(eval $(call BuildPlugin,iptables-mod-rpfilter,$(IPT_RPFILTER-m))) $(eval $(call BuildPlugin,iptables-mod-led,$(IPT_LED-m))) diff --git a/target/linux/generic/backport-6.0/001-CONFIG_INITRAMFS_PRESERVE_MTIME.patch b/target/linux/generic/backport-6.0/001-CONFIG_INITRAMFS_PRESERVE_MTIME.patch deleted file mode 100644 index a757fee62..000000000 --- a/target/linux/generic/backport-6.0/001-CONFIG_INITRAMFS_PRESERVE_MTIME.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1386,16 +1386,6 @@ config BOOT_CONFIG_EMBED_FILE - This bootconfig will be used if there is no initrd or no other - bootconfig in the initrd. - --config INITRAMFS_PRESERVE_MTIME -- bool "Preserve cpio archive mtimes in initramfs" -- default y -- help -- Each entry in an initramfs cpio archive carries an mtime value. When -- enabled, extracted cpio items take this mtime, with directory mtime -- setting deferred until after creation of any child entries. -- -- If unsure, say Y. -- - choice - prompt "Compiler optimization level" - default CC_OPTIMIZE_FOR_PERFORMANCE ---- a/init/initramfs.c -+++ b/init/initramfs.c -@@ -127,17 +127,15 @@ static void __init free_hash(void) - } - } - --#ifdef CONFIG_INITRAMFS_PRESERVE_MTIME --static void __init do_utime(char *filename, time64_t mtime) -+static long __init do_utime(char *filename, time64_t mtime) - { -- struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; -- init_utimes(filename, t); --} -+ struct timespec64 t[2]; - --static void __init do_utime_path(const struct path *path, time64_t mtime) --{ -- struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; -- vfs_utimes(path, t); -+ t[0].tv_sec = mtime; -+ t[0].tv_nsec = 0; -+ t[1].tv_sec = mtime; -+ t[1].tv_nsec = 0; -+ return init_utimes(filename, t); - } - - static __initdata LIST_HEAD(dir_list); -@@ -170,12 +168,6 @@ static void __init dir_utime(void) - kfree(de); - } - } --#else --static void __init do_utime(char *filename, time64_t mtime) {} --static void __init do_utime_path(const struct path *path, time64_t mtime) {} --static void __init dir_add(const char *name, time64_t mtime) {} --static void __init dir_utime(void) {} --#endif - - static __initdata time64_t mtime; - -@@ -407,10 +399,14 @@ static int __init do_name(void) - static int __init do_copy(void) - { - if (byte_count >= body_len) { -+ struct timespec64 t[2] = { }; - if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len) - error("write error"); - -- do_utime_path(&wfile->f_path, mtime); -+ t[0].tv_sec = mtime; -+ t[1].tv_sec = mtime; -+ vfs_utimes(&wfile->f_path, t); -+ - fput(wfile); - if (csum_present && io_csum != hdr_csum) - error("bad data checksum"); diff --git a/target/linux/generic/backport-6.0/002-struct-net_device.patch b/target/linux/generic/backport-6.0/002-struct-net_device.patch deleted file mode 100644 index e45e19ca7..000000000 --- a/target/linux/generic/backport-6.0/002-struct-net_device.patch +++ /dev/null @@ -1,122 +0,0 @@ ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2133,8 +2133,6 @@ struct net_device { - - /* Protocol-specific pointers */ - -- struct in_device __rcu *ip_ptr; -- struct inet6_dev __rcu *ip6_ptr; - #if IS_ENABLED(CONFIG_VLAN_8021Q) - struct vlan_info __rcu *vlan_info; - #endif -@@ -2147,18 +2145,16 @@ struct net_device { - #if IS_ENABLED(CONFIG_ATALK) - void *atalk_ptr; - #endif -+ struct in_device __rcu *ip_ptr; - #if IS_ENABLED(CONFIG_DECNET) - struct dn_dev __rcu *dn_ptr; - #endif -+ struct inet6_dev __rcu *ip6_ptr; - #if IS_ENABLED(CONFIG_AX25) - void *ax25_ptr; - #endif --#if IS_ENABLED(CONFIG_CFG80211) - struct wireless_dev *ieee80211_ptr; --#endif --#if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN) - struct wpan_dev *ieee802154_ptr; --#endif - #if IS_ENABLED(CONFIG_MPLS_ROUTING) - struct mpls_dev __rcu *mpls_ptr; - #endif ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -8379,9 +8379,7 @@ int cfg80211_register_netdevice(struct n - */ - static inline void cfg80211_unregister_netdevice(struct net_device *dev) - { --#if IS_ENABLED(CONFIG_CFG80211) - cfg80211_unregister_wdev(dev->ieee80211_ptr); --#endif - } - - /** ---- a/include/net/cfg802154.h -+++ b/include/net/cfg802154.h -@@ -373,7 +373,6 @@ struct wpan_dev { - - #define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) - --#if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN) - static inline int - wpan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, - const struct ieee802154_addr *daddr, -@@ -384,7 +383,6 @@ wpan_dev_hard_header(struct sk_buff *skb - - return wpan_dev->header_ops->create(skb, dev, daddr, saddr, len); - } --#endif - - struct wpan_phy * - wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size); ---- a/net/batman-adv/hard-interface.c -+++ b/net/batman-adv/hard-interface.c -@@ -308,11 +308,9 @@ static bool batadv_is_cfg80211_netdev(st - if (!net_device) - return false; - --#if IS_ENABLED(CONFIG_CFG80211) - /* cfg80211 drivers have to set ieee80211_ptr */ - if (net_device->ieee80211_ptr) - return true; --#endif - - return false; - } ---- a/net/core/net-sysfs.c -+++ b/net/core/net-sysfs.c -@@ -747,6 +747,7 @@ static const struct attribute_group nets - .attrs = netstat_attrs, - }; - -+#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) - static struct attribute *wireless_attrs[] = { - NULL - }; -@@ -755,19 +756,7 @@ static const struct attribute_group wire - .name = "wireless", - .attrs = wireless_attrs, - }; -- --static bool wireless_group_needed(struct net_device *ndev) --{ --#if IS_ENABLED(CONFIG_CFG80211) -- if (ndev->ieee80211_ptr) -- return true; - #endif --#if IS_ENABLED(CONFIG_WIRELESS_EXT) -- if (ndev->wireless_handlers) -- return true; --#endif -- return false; --} - - #else /* CONFIG_SYSFS */ - #define net_class_groups NULL -@@ -2008,8 +1997,14 @@ int netdev_register_kobject(struct net_d - - *groups++ = &netstat_group; - -- if (wireless_group_needed(ndev)) -+#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) -+ if (ndev->ieee80211_ptr) -+ *groups++ = &wireless_group; -+#if IS_ENABLED(CONFIG_WIRELESS_EXT) -+ else if (ndev->wireless_handlers) - *groups++ = &wireless_group; -+#endif -+#endif - #endif /* CONFIG_SYSFS */ - - error = device_add(dev); diff --git a/target/linux/generic/backport-6.0/100-mm-x86-arm64-add-arch_has_hw_pte_young.patch b/target/linux/generic/backport-6.0/100-mm-x86-arm64-add-arch_has_hw_pte_young.patch deleted file mode 100644 index 18530fae9..000000000 --- a/target/linux/generic/backport-6.0/100-mm-x86-arm64-add-arch_has_hw_pte_young.patch +++ /dev/null @@ -1,143 +0,0 @@ -From e3264035bdac67898d685423ffb2f3a9c3a5964a Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 4 Aug 2021 01:31:34 -0600 -Subject: [PATCH 01/14] mm: x86, arm64: add arch_has_hw_pte_young() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some architectures automatically set the accessed bit in PTEs, e.g., -x86 and arm64 v8.2. On architectures that do not have this capability, -clearing the accessed bit in a PTE usually triggers a page fault -following the TLB miss of this PTE (to emulate the accessed bit). - -Being aware of this capability can help make better decisions, e.g., -whether to spread the work out over a period of time to reduce bursty -page faults when trying to clear the accessed bit in many PTEs. - -Note that theoretically this capability can be unreliable, e.g., -hotplugged CPUs might be different from builtin ones. Therefore it -should not be used in architecture-independent code that involves -correctness, e.g., to determine whether TLB flushes are required (in -combination with the accessed bit). - -Signed-off-by: Yu Zhao -Reviewed-by: Barry Song -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Acked-by: Will Deacon -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: Ib49b44fb56df3333a2ff1fcc496fb1980b976e7a ---- - arch/arm64/include/asm/pgtable.h | 15 ++------------- - arch/x86/include/asm/pgtable.h | 6 +++--- - include/linux/pgtable.h | 13 +++++++++++++ - mm/memory.c | 14 +------------- - 4 files changed, 19 insertions(+), 29 deletions(-) - ---- a/arch/arm64/include/asm/pgtable.h -+++ b/arch/arm64/include/asm/pgtable.h -@@ -1082,24 +1082,13 @@ static inline void update_mmu_cache(stru - * page after fork() + CoW for pfn mappings. We don't always have a - * hardware-managed access flag on arm64. - */ --static inline bool arch_faults_on_old_pte(void) --{ -- /* The register read below requires a stable CPU to make any sense */ -- cant_migrate(); -- -- return !cpu_has_hw_af(); --} --#define arch_faults_on_old_pte arch_faults_on_old_pte -+#define arch_has_hw_pte_young cpu_has_hw_af - - /* - * Experimentally, it's cheap to set the access flag in hardware and we - * benefit from prefaulting mappings as 'old' to start with. - */ --static inline bool arch_wants_old_prefaulted_pte(void) --{ -- return !arch_faults_on_old_pte(); --} --#define arch_wants_old_prefaulted_pte arch_wants_old_prefaulted_pte -+#define arch_wants_old_prefaulted_pte cpu_has_hw_af - - static inline bool pud_sect_supported(void) - { ---- a/arch/x86/include/asm/pgtable.h -+++ b/arch/x86/include/asm/pgtable.h -@@ -1431,10 +1431,10 @@ static inline bool arch_has_pfn_modify_c - return boot_cpu_has_bug(X86_BUG_L1TF); - } - --#define arch_faults_on_old_pte arch_faults_on_old_pte --static inline bool arch_faults_on_old_pte(void) -+#define arch_has_hw_pte_young arch_has_hw_pte_young -+static inline bool arch_has_hw_pte_young(void) - { -- return false; -+ return true; - } - - #ifdef CONFIG_PAGE_TABLE_CHECK ---- a/include/linux/pgtable.h -+++ b/include/linux/pgtable.h -@@ -260,6 +260,19 @@ static inline int pmdp_clear_flush_young - #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ - #endif - -+#ifndef arch_has_hw_pte_young -+/* -+ * Return whether the accessed bit is supported on the local CPU. -+ * -+ * This stub assumes accessing through an old PTE triggers a page fault. -+ * Architectures that automatically set the access bit should overwrite it. -+ */ -+static inline bool arch_has_hw_pte_young(void) -+{ -+ return false; -+} -+#endif -+ - #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR - static inline pte_t ptep_get_and_clear(struct mm_struct *mm, - unsigned long address, ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -125,18 +125,6 @@ int randomize_va_space __read_mostly = - 2; - #endif - --#ifndef arch_faults_on_old_pte --static inline bool arch_faults_on_old_pte(void) --{ -- /* -- * Those arches which don't have hw access flag feature need to -- * implement their own helper. By default, "true" means pagefault -- * will be hit on old pte. -- */ -- return true; --} --#endif -- - #ifndef arch_wants_old_prefaulted_pte - static inline bool arch_wants_old_prefaulted_pte(void) - { -@@ -2872,7 +2860,7 @@ static inline bool __wp_page_copy_user(s - * On architectures with software "accessed" bits, we would - * take a double page fault, so mark it accessed here. - */ -- if (arch_faults_on_old_pte() && !pte_young(vmf->orig_pte)) { -+ if (!arch_has_hw_pte_young() && !pte_young(vmf->orig_pte)) { - pte_t entry; - - vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl); diff --git a/target/linux/generic/backport-6.0/101-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch b/target/linux/generic/backport-6.0/101-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch deleted file mode 100644 index 2d105ad6a..000000000 --- a/target/linux/generic/backport-6.0/101-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 0c0016e6f53b52166fe4da61c81fa6b27f4650cd Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sat, 26 Sep 2020 21:17:18 -0600 -Subject: [PATCH 02/14] mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some architectures support the accessed bit in non-leaf PMD entries, -e.g., x86 sets the accessed bit in a non-leaf PMD entry when using it -as part of linear address translation [1]. Page table walkers that -clear the accessed bit may use this capability to reduce their search -space. - -Note that: -1. Although an inline function is preferable, this capability is added - as a configuration option for consistency with the existing macros. -2. Due to the little interest in other varieties, this capability was - only tested on Intel and AMD CPUs. - -Thanks to the following developers for their efforts [2][3]. - Randy Dunlap - Stephen Rothwell - -[1]: Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 3 (June 2021), section 4.8 -[2] https://lore.kernel.org/r/bfdcc7c8-922f-61a9-aa15-7e7250f04af7@infradead.org/ -[3] https://lore.kernel.org/r/20220413151513.5a0d7a7e@canb.auug.org.au/ - -Signed-off-by: Yu Zhao -Reviewed-by: Barry Song -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I1a17be3ae926f721f7b17ea1539e5c39e8c4f9a8 ---- - arch/Kconfig | 8 ++++++++ - arch/x86/Kconfig | 1 + - arch/x86/include/asm/pgtable.h | 3 ++- - arch/x86/mm/pgtable.c | 5 ++++- - include/linux/pgtable.h | 4 ++-- - 5 files changed, 17 insertions(+), 4 deletions(-) - ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -1418,6 +1418,14 @@ config DYNAMIC_SIGFRAME - config HAVE_ARCH_NODE_DEV_GROUP - bool - -+config ARCH_HAS_NONLEAF_PMD_YOUNG -+ bool -+ help -+ Architectures that select this option are capable of setting the -+ accessed bit in non-leaf PMD entries when using them as part of linear -+ address translations. Page table walkers that clear the accessed bit -+ may use this capability to reduce their search space. -+ - source "kernel/gcov/Kconfig" - - source "scripts/gcc-plugins/Kconfig" ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -85,6 +85,7 @@ config X86 - select ARCH_HAS_PMEM_API if X86_64 - select ARCH_HAS_PTE_DEVMAP if X86_64 - select ARCH_HAS_PTE_SPECIAL -+ select ARCH_HAS_NONLEAF_PMD_YOUNG if PGTABLE_LEVELS > 2 - select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 - select ARCH_HAS_COPY_MC if X86_64 - select ARCH_HAS_SET_MEMORY ---- a/arch/x86/include/asm/pgtable.h -+++ b/arch/x86/include/asm/pgtable.h -@@ -815,7 +815,8 @@ static inline unsigned long pmd_page_vad - - static inline int pmd_bad(pmd_t pmd) - { -- return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE; -+ return (pmd_flags(pmd) & ~(_PAGE_USER | _PAGE_ACCESSED)) != -+ (_KERNPG_TABLE & ~_PAGE_ACCESSED); - } - - static inline unsigned long pages_to_mb(unsigned long npg) ---- a/arch/x86/mm/pgtable.c -+++ b/arch/x86/mm/pgtable.c -@@ -550,7 +550,7 @@ int ptep_test_and_clear_young(struct vm_ - return ret; - } - --#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) - int pmdp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pmd_t *pmdp) - { -@@ -562,6 +562,9 @@ int pmdp_test_and_clear_young(struct vm_ - - return ret; - } -+#endif -+ -+#ifdef CONFIG_TRANSPARENT_HUGEPAGE - int pudp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pud_t *pudp) - { ---- a/include/linux/pgtable.h -+++ b/include/linux/pgtable.h -@@ -213,7 +213,7 @@ static inline int ptep_test_and_clear_yo - #endif - - #ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG --#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) - static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long address, - pmd_t *pmdp) -@@ -234,7 +234,7 @@ static inline int pmdp_test_and_clear_yo - BUILD_BUG(); - return 0; - } --#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -+#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG */ - #endif - - #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH diff --git a/target/linux/generic/backport-6.0/102-mm-vmscan.c-refactor-shrink_node.patch b/target/linux/generic/backport-6.0/102-mm-vmscan.c-refactor-shrink_node.patch deleted file mode 100644 index f7c39744b..000000000 --- a/target/linux/generic/backport-6.0/102-mm-vmscan.c-refactor-shrink_node.patch +++ /dev/null @@ -1,254 +0,0 @@ -From d8e0edcddc441574410a047ede56f79c849a6d37 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 27 Sep 2020 20:49:08 -0600 -Subject: [PATCH 03/14] mm/vmscan.c: refactor shrink_node() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch refactors shrink_node() to improve readability for the -upcoming changes to mm/vmscan.c. - -Signed-off-by: Yu Zhao -Reviewed-by: Barry Song -Reviewed-by: Miaohe Lin -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: Iae734b5b4030205b7db6e8c841f747b6f6ae1a04 ---- - mm/vmscan.c | 198 +++++++++++++++++++++++++++------------------------- - 1 file changed, 104 insertions(+), 94 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -2728,6 +2728,109 @@ enum scan_balance { - SCAN_FILE, - }; - -+static void prepare_scan_count(pg_data_t *pgdat, struct scan_control *sc) -+{ -+ unsigned long file; -+ struct lruvec *target_lruvec; -+ -+ target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); -+ -+ /* -+ * Flush the memory cgroup stats, so that we read accurate per-memcg -+ * lruvec stats for heuristics. -+ */ -+ mem_cgroup_flush_stats(); -+ -+ /* -+ * Determine the scan balance between anon and file LRUs. -+ */ -+ spin_lock_irq(&target_lruvec->lru_lock); -+ sc->anon_cost = target_lruvec->anon_cost; -+ sc->file_cost = target_lruvec->file_cost; -+ spin_unlock_irq(&target_lruvec->lru_lock); -+ -+ /* -+ * Target desirable inactive:active list ratios for the anon -+ * and file LRU lists. -+ */ -+ if (!sc->force_deactivate) { -+ unsigned long refaults; -+ -+ refaults = lruvec_page_state(target_lruvec, -+ WORKINGSET_ACTIVATE_ANON); -+ if (refaults != target_lruvec->refaults[0] || -+ inactive_is_low(target_lruvec, LRU_INACTIVE_ANON)) -+ sc->may_deactivate |= DEACTIVATE_ANON; -+ else -+ sc->may_deactivate &= ~DEACTIVATE_ANON; -+ -+ /* -+ * When refaults are being observed, it means a new -+ * workingset is being established. Deactivate to get -+ * rid of any stale active pages quickly. -+ */ -+ refaults = lruvec_page_state(target_lruvec, -+ WORKINGSET_ACTIVATE_FILE); -+ if (refaults != target_lruvec->refaults[1] || -+ inactive_is_low(target_lruvec, LRU_INACTIVE_FILE)) -+ sc->may_deactivate |= DEACTIVATE_FILE; -+ else -+ sc->may_deactivate &= ~DEACTIVATE_FILE; -+ } else -+ sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE; -+ -+ /* -+ * If we have plenty of inactive file pages that aren't -+ * thrashing, try to reclaim those first before touching -+ * anonymous pages. -+ */ -+ file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE); -+ if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE)) -+ sc->cache_trim_mode = 1; -+ else -+ sc->cache_trim_mode = 0; -+ -+ /* -+ * Prevent the reclaimer from falling into the cache trap: as -+ * cache pages start out inactive, every cache fault will tip -+ * the scan balance towards the file LRU. And as the file LRU -+ * shrinks, so does the window for rotation from references. -+ * This means we have a runaway feedback loop where a tiny -+ * thrashing file LRU becomes infinitely more attractive than -+ * anon pages. Try to detect this based on file LRU size. -+ */ -+ if (!cgroup_reclaim(sc)) { -+ unsigned long total_high_wmark = 0; -+ unsigned long free, anon; -+ int z; -+ -+ free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES); -+ file = node_page_state(pgdat, NR_ACTIVE_FILE) + -+ node_page_state(pgdat, NR_INACTIVE_FILE); -+ -+ for (z = 0; z < MAX_NR_ZONES; z++) { -+ struct zone *zone = &pgdat->node_zones[z]; -+ -+ if (!managed_zone(zone)) -+ continue; -+ -+ total_high_wmark += high_wmark_pages(zone); -+ } -+ -+ /* -+ * Consider anon: if that's low too, this isn't a -+ * runaway file reclaim problem, but rather just -+ * extreme pressure. Reclaim as per usual then. -+ */ -+ anon = node_page_state(pgdat, NR_INACTIVE_ANON); -+ -+ sc->file_is_tiny = -+ file + free <= total_high_wmark && -+ !(sc->may_deactivate & DEACTIVATE_ANON) && -+ anon >> sc->priority; -+ } -+} -+ - /* - * Determine how aggressively the anon and file LRU lists should be - * scanned. -@@ -3197,109 +3300,16 @@ static void shrink_node(pg_data_t *pgdat - unsigned long nr_reclaimed, nr_scanned; - struct lruvec *target_lruvec; - bool reclaimable = false; -- unsigned long file; - - target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); - - again: -- /* -- * Flush the memory cgroup stats, so that we read accurate per-memcg -- * lruvec stats for heuristics. -- */ -- mem_cgroup_flush_stats(); -- - memset(&sc->nr, 0, sizeof(sc->nr)); - - nr_reclaimed = sc->nr_reclaimed; - nr_scanned = sc->nr_scanned; - -- /* -- * Determine the scan balance between anon and file LRUs. -- */ -- spin_lock_irq(&target_lruvec->lru_lock); -- sc->anon_cost = target_lruvec->anon_cost; -- sc->file_cost = target_lruvec->file_cost; -- spin_unlock_irq(&target_lruvec->lru_lock); -- -- /* -- * Target desirable inactive:active list ratios for the anon -- * and file LRU lists. -- */ -- if (!sc->force_deactivate) { -- unsigned long refaults; -- -- refaults = lruvec_page_state(target_lruvec, -- WORKINGSET_ACTIVATE_ANON); -- if (refaults != target_lruvec->refaults[0] || -- inactive_is_low(target_lruvec, LRU_INACTIVE_ANON)) -- sc->may_deactivate |= DEACTIVATE_ANON; -- else -- sc->may_deactivate &= ~DEACTIVATE_ANON; -- -- /* -- * When refaults are being observed, it means a new -- * workingset is being established. Deactivate to get -- * rid of any stale active pages quickly. -- */ -- refaults = lruvec_page_state(target_lruvec, -- WORKINGSET_ACTIVATE_FILE); -- if (refaults != target_lruvec->refaults[1] || -- inactive_is_low(target_lruvec, LRU_INACTIVE_FILE)) -- sc->may_deactivate |= DEACTIVATE_FILE; -- else -- sc->may_deactivate &= ~DEACTIVATE_FILE; -- } else -- sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE; -- -- /* -- * If we have plenty of inactive file pages that aren't -- * thrashing, try to reclaim those first before touching -- * anonymous pages. -- */ -- file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE); -- if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE)) -- sc->cache_trim_mode = 1; -- else -- sc->cache_trim_mode = 0; -- -- /* -- * Prevent the reclaimer from falling into the cache trap: as -- * cache pages start out inactive, every cache fault will tip -- * the scan balance towards the file LRU. And as the file LRU -- * shrinks, so does the window for rotation from references. -- * This means we have a runaway feedback loop where a tiny -- * thrashing file LRU becomes infinitely more attractive than -- * anon pages. Try to detect this based on file LRU size. -- */ -- if (!cgroup_reclaim(sc)) { -- unsigned long total_high_wmark = 0; -- unsigned long free, anon; -- int z; -- -- free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES); -- file = node_page_state(pgdat, NR_ACTIVE_FILE) + -- node_page_state(pgdat, NR_INACTIVE_FILE); -- -- for (z = 0; z < MAX_NR_ZONES; z++) { -- struct zone *zone = &pgdat->node_zones[z]; -- if (!managed_zone(zone)) -- continue; -- -- total_high_wmark += high_wmark_pages(zone); -- } -- -- /* -- * Consider anon: if that's low too, this isn't a -- * runaway file reclaim problem, but rather just -- * extreme pressure. Reclaim as per usual then. -- */ -- anon = node_page_state(pgdat, NR_INACTIVE_ANON); -- -- sc->file_is_tiny = -- file + free <= total_high_wmark && -- !(sc->may_deactivate & DEACTIVATE_ANON) && -- anon >> sc->priority; -- } -+ prepare_scan_count(pgdat, sc); - - shrink_node_memcgs(pgdat, sc); - diff --git a/target/linux/generic/backport-6.0/103-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch b/target/linux/generic/backport-6.0/103-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch deleted file mode 100644 index 2a6a1f24f..000000000 --- a/target/linux/generic/backport-6.0/103-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch +++ /dev/null @@ -1,59 +0,0 @@ -From bc14d2c7c6d0fb8c79ad0fc5eab488b977cbcccf Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 6 Mar 2022 20:22:40 -0700 -Subject: [PATCH 04/14] Revert "include/linux/mm_inline.h: fold - __update_lru_size() into its sole caller" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch undoes the following refactor: -commit 289ccba18af4 ("include/linux/mm_inline.h: fold __update_lru_size() into its sole caller") - -The upcoming changes to include/linux/mm_inline.h will reuse -__update_lru_size(). - -Signed-off-by: Yu Zhao -Reviewed-by: Miaohe Lin -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I6155c407d50199a43b179c7f45904d4b7c052118 ---- - include/linux/mm_inline.h | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -34,7 +34,7 @@ static inline int page_is_file_lru(struc - return folio_is_file_lru(page_folio(page)); - } - --static __always_inline void update_lru_size(struct lruvec *lruvec, -+static __always_inline void __update_lru_size(struct lruvec *lruvec, - enum lru_list lru, enum zone_type zid, - long nr_pages) - { -@@ -43,6 +43,13 @@ static __always_inline void update_lru_s - __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages); - __mod_zone_page_state(&pgdat->node_zones[zid], - NR_ZONE_LRU_BASE + lru, nr_pages); -+} -+ -+static __always_inline void update_lru_size(struct lruvec *lruvec, -+ enum lru_list lru, enum zone_type zid, -+ long nr_pages) -+{ -+ __update_lru_size(lruvec, lru, zid, nr_pages); - #ifdef CONFIG_MEMCG - mem_cgroup_update_lru_size(lruvec, lru, zid, nr_pages); - #endif diff --git a/target/linux/generic/backport-6.0/104-mm-multi-gen-LRU-groundwork.patch b/target/linux/generic/backport-6.0/104-mm-multi-gen-LRU-groundwork.patch deleted file mode 100644 index 4750bdd99..000000000 --- a/target/linux/generic/backport-6.0/104-mm-multi-gen-LRU-groundwork.patch +++ /dev/null @@ -1,777 +0,0 @@ -From 8c6beb4548c216da9dae5e1a7612a108396e3f9e Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Mon, 25 Jan 2021 21:12:33 -0700 -Subject: [PATCH 05/14] mm: multi-gen LRU: groundwork -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Evictable pages are divided into multiple generations for each lruvec. -The youngest generation number is stored in lrugen->max_seq for both -anon and file types as they are aged on an equal footing. The oldest -generation numbers are stored in lrugen->min_seq[] separately for anon -and file types as clean file pages can be evicted regardless of swap -constraints. These three variables are monotonically increasing. - -Generation numbers are truncated into order_base_2(MAX_NR_GENS+1) bits -in order to fit into the gen counter in folio->flags. Each truncated -generation number is an index to lrugen->lists[]. The sliding window -technique is used to track at least MIN_NR_GENS and at most -MAX_NR_GENS generations. The gen counter stores a value within [1, -MAX_NR_GENS] while a page is on one of lrugen->lists[]. Otherwise it -stores 0. - -There are two conceptually independent procedures: "the aging", which -produces young generations, and "the eviction", which consumes old -generations. They form a closed-loop system, i.e., "the page reclaim". -Both procedures can be invoked from userspace for the purposes of -working set estimation and proactive reclaim. These techniques are -commonly used to optimize job scheduling (bin packing) in data -centers [1][2]. - -To avoid confusion, the terms "hot" and "cold" will be applied to the -multi-gen LRU, as a new convention; the terms "active" and "inactive" -will be applied to the active/inactive LRU, as usual. - -The protection of hot pages and the selection of cold pages are based -on page access channels and patterns. There are two access channels: -one through page tables and the other through file descriptors. The -protection of the former channel is by design stronger because: -1. The uncertainty in determining the access patterns of the former - channel is higher due to the approximation of the accessed bit. -2. The cost of evicting the former channel is higher due to the TLB - flushes required and the likelihood of encountering the dirty bit. -3. The penalty of underprotecting the former channel is higher because - applications usually do not prepare themselves for major page - faults like they do for blocked I/O. E.g., GUI applications - commonly use dedicated I/O threads to avoid blocking rendering - threads. -There are also two access patterns: one with temporal locality and the -other without. For the reasons listed above, the former channel is -assumed to follow the former pattern unless VM_SEQ_READ or -VM_RAND_READ is present; the latter channel is assumed to follow the -latter pattern unless outlying refaults have been observed [3][4]. - -The next patch will address the "outlying refaults". Three macros, -i.e., LRU_REFS_WIDTH, LRU_REFS_PGOFF and LRU_REFS_MASK, used later are -added in this patch to make the entire patchset less diffy. - -A page is added to the youngest generation on faulting. The aging -needs to check the accessed bit at least twice before handing this -page over to the eviction. The first check takes care of the accessed -bit set on the initial fault; the second check makes sure this page -has not been used since then. This protocol, AKA second chance, -requires a minimum of two generations, hence MIN_NR_GENS. - -[1] https://dl.acm.org/doi/10.1145/3297858.3304053 -[2] https://dl.acm.org/doi/10.1145/3503222.3507731 -[3] https://lwn.net/Articles/495543/ -[4] https://lwn.net/Articles/815342/ - -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I71de7cd15b8dfa6f9fdd838023474693c4fee0a7 ---- - fs/fuse/dev.c | 3 +- - include/linux/mm_inline.h | 175 ++++++++++++++++++++++++++++++ - include/linux/mmzone.h | 102 +++++++++++++++++ - include/linux/page-flags-layout.h | 13 ++- - include/linux/page-flags.h | 4 +- - include/linux/sched.h | 4 + - kernel/bounds.c | 5 + - mm/Kconfig | 8 ++ - mm/huge_memory.c | 3 +- - mm/memcontrol.c | 2 + - mm/memory.c | 25 +++++ - mm/mm_init.c | 6 +- - mm/mmzone.c | 2 + - mm/swap.c | 11 +- - mm/vmscan.c | 75 +++++++++++++ - 15 files changed, 424 insertions(+), 14 deletions(-) - ---- a/fs/fuse/dev.c -+++ b/fs/fuse/dev.c -@@ -776,7 +776,8 @@ static int fuse_check_page(struct page * - 1 << PG_active | - 1 << PG_workingset | - 1 << PG_reclaim | -- 1 << PG_waiters))) { -+ 1 << PG_waiters | -+ LRU_GEN_MASK | LRU_REFS_MASK))) { - dump_page(page, "fuse: trying to steal weird page"); - return 1; - } ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -40,6 +40,9 @@ static __always_inline void __update_lru - { - struct pglist_data *pgdat = lruvec_pgdat(lruvec); - -+ lockdep_assert_held(&lruvec->lru_lock); -+ WARN_ON_ONCE(nr_pages != (int)nr_pages); -+ - __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages); - __mod_zone_page_state(&pgdat->node_zones[zid], - NR_ZONE_LRU_BASE + lru, nr_pages); -@@ -101,11 +104,177 @@ static __always_inline enum lru_list fol - return lru; - } - -+#ifdef CONFIG_LRU_GEN -+ -+static inline bool lru_gen_enabled(void) -+{ -+ return true; -+} -+ -+static inline bool lru_gen_in_fault(void) -+{ -+ return current->in_lru_fault; -+} -+ -+static inline int lru_gen_from_seq(unsigned long seq) -+{ -+ return seq % MAX_NR_GENS; -+} -+ -+static inline int folio_lru_gen(struct folio *folio) -+{ -+ unsigned long flags = READ_ONCE(folio->flags); -+ -+ return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+} -+ -+static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen) -+{ -+ unsigned long max_seq = lruvec->lrugen.max_seq; -+ -+ VM_WARN_ON_ONCE(gen >= MAX_NR_GENS); -+ -+ /* see the comment on MIN_NR_GENS */ -+ return gen == lru_gen_from_seq(max_seq) || gen == lru_gen_from_seq(max_seq - 1); -+} -+ -+static inline void lru_gen_update_size(struct lruvec *lruvec, struct folio *folio, -+ int old_gen, int new_gen) -+{ -+ int type = folio_is_file_lru(folio); -+ int zone = folio_zonenum(folio); -+ int delta = folio_nr_pages(folio); -+ enum lru_list lru = type * LRU_INACTIVE_FILE; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS); -+ VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS); -+ VM_WARN_ON_ONCE(old_gen == -1 && new_gen == -1); -+ -+ if (old_gen >= 0) -+ WRITE_ONCE(lrugen->nr_pages[old_gen][type][zone], -+ lrugen->nr_pages[old_gen][type][zone] - delta); -+ if (new_gen >= 0) -+ WRITE_ONCE(lrugen->nr_pages[new_gen][type][zone], -+ lrugen->nr_pages[new_gen][type][zone] + delta); -+ -+ /* addition */ -+ if (old_gen < 0) { -+ if (lru_gen_is_active(lruvec, new_gen)) -+ lru += LRU_ACTIVE; -+ __update_lru_size(lruvec, lru, zone, delta); -+ return; -+ } -+ -+ /* deletion */ -+ if (new_gen < 0) { -+ if (lru_gen_is_active(lruvec, old_gen)) -+ lru += LRU_ACTIVE; -+ __update_lru_size(lruvec, lru, zone, -delta); -+ return; -+ } -+} -+ -+static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) -+{ -+ unsigned long seq; -+ unsigned long flags; -+ int gen = folio_lru_gen(folio); -+ int type = folio_is_file_lru(folio); -+ int zone = folio_zonenum(folio); -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ VM_WARN_ON_ONCE_FOLIO(gen != -1, folio); -+ -+ if (folio_test_unevictable(folio)) -+ return false; -+ /* -+ * There are three common cases for this page: -+ * 1. If it's hot, e.g., freshly faulted in or previously hot and -+ * migrated, add it to the youngest generation. -+ * 2. If it's cold but can't be evicted immediately, i.e., an anon page -+ * not in swapcache or a dirty page pending writeback, add it to the -+ * second oldest generation. -+ * 3. Everything else (clean, cold) is added to the oldest generation. -+ */ -+ if (folio_test_active(folio)) -+ seq = lrugen->max_seq; -+ else if ((type == LRU_GEN_ANON && !folio_test_swapcache(folio)) || -+ (folio_test_reclaim(folio) && -+ (folio_test_dirty(folio) || folio_test_writeback(folio)))) -+ seq = lrugen->min_seq[type] + 1; -+ else -+ seq = lrugen->min_seq[type]; -+ -+ gen = lru_gen_from_seq(seq); -+ flags = (gen + 1UL) << LRU_GEN_PGOFF; -+ /* see the comment on MIN_NR_GENS about PG_active */ -+ set_mask_bits(&folio->flags, LRU_GEN_MASK | BIT(PG_active), flags); -+ -+ lru_gen_update_size(lruvec, folio, -1, gen); -+ /* for folio_rotate_reclaimable() */ -+ if (reclaiming) -+ list_add_tail(&folio->lru, &lrugen->lists[gen][type][zone]); -+ else -+ list_add(&folio->lru, &lrugen->lists[gen][type][zone]); -+ -+ return true; -+} -+ -+static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) -+{ -+ unsigned long flags; -+ int gen = folio_lru_gen(folio); -+ -+ if (gen < 0) -+ return false; -+ -+ VM_WARN_ON_ONCE_FOLIO(folio_test_active(folio), folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_test_unevictable(folio), folio); -+ -+ /* for folio_migrate_flags() */ -+ flags = !reclaiming && lru_gen_is_active(lruvec, gen) ? BIT(PG_active) : 0; -+ flags = set_mask_bits(&folio->flags, LRU_GEN_MASK, flags); -+ gen = ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+ -+ lru_gen_update_size(lruvec, folio, gen, -1); -+ list_del(&folio->lru); -+ -+ return true; -+} -+ -+#else /* !CONFIG_LRU_GEN */ -+ -+static inline bool lru_gen_enabled(void) -+{ -+ return false; -+} -+ -+static inline bool lru_gen_in_fault(void) -+{ -+ return false; -+} -+ -+static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) -+{ -+ return false; -+} -+ -+static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - static __always_inline - void lruvec_add_folio(struct lruvec *lruvec, struct folio *folio) - { - enum lru_list lru = folio_lru_list(folio); - -+ if (lru_gen_add_folio(lruvec, folio, false)) -+ return; -+ - update_lru_size(lruvec, lru, folio_zonenum(folio), - folio_nr_pages(folio)); - if (lru != LRU_UNEVICTABLE) -@@ -123,6 +292,9 @@ void lruvec_add_folio_tail(struct lruvec - { - enum lru_list lru = folio_lru_list(folio); - -+ if (lru_gen_add_folio(lruvec, folio, true)) -+ return; -+ - update_lru_size(lruvec, lru, folio_zonenum(folio), - folio_nr_pages(folio)); - /* This is not expected to be used on LRU_UNEVICTABLE */ -@@ -140,6 +312,9 @@ void lruvec_del_folio(struct lruvec *lru - { - enum lru_list lru = folio_lru_list(folio); - -+ if (lru_gen_del_folio(lruvec, folio, false)) -+ return; -+ - if (lru != LRU_UNEVICTABLE) - list_del(&folio->lru); - update_lru_size(lruvec, lru, folio_zonenum(folio), ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -314,6 +314,102 @@ enum lruvec_flags { - */ - }; - -+#endif /* !__GENERATING_BOUNDS_H */ -+ -+/* -+ * Evictable pages are divided into multiple generations. The youngest and the -+ * oldest generation numbers, max_seq and min_seq, are monotonically increasing. -+ * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An -+ * offset within MAX_NR_GENS, i.e., gen, indexes the LRU list of the -+ * corresponding generation. The gen counter in folio->flags stores gen+1 while -+ * a page is on one of lrugen->lists[]. Otherwise it stores 0. -+ * -+ * A page is added to the youngest generation on faulting. The aging needs to -+ * check the accessed bit at least twice before handing this page over to the -+ * eviction. The first check takes care of the accessed bit set on the initial -+ * fault; the second check makes sure this page hasn't been used since then. -+ * This process, AKA second chance, requires a minimum of two generations, -+ * hence MIN_NR_GENS. And to maintain ABI compatibility with the active/inactive -+ * LRU, e.g., /proc/vmstat, these two generations are considered active; the -+ * rest of generations, if they exist, are considered inactive. See -+ * lru_gen_is_active(). -+ * -+ * PG_active is always cleared while a page is on one of lrugen->lists[] so that -+ * the aging needs not to worry about it. And it's set again when a page -+ * considered active is isolated for non-reclaiming purposes, e.g., migration. -+ * See lru_gen_add_folio() and lru_gen_del_folio(). -+ * -+ * MAX_NR_GENS is set to 4 so that the multi-gen LRU can support twice the -+ * number of categories of the active/inactive LRU when keeping track of -+ * accesses through page tables. This requires order_base_2(MAX_NR_GENS+1) bits -+ * in folio->flags. -+ */ -+#define MIN_NR_GENS 2U -+#define MAX_NR_GENS 4U -+ -+#ifndef __GENERATING_BOUNDS_H -+ -+struct lruvec; -+ -+#define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF) -+#define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF) -+ -+#ifdef CONFIG_LRU_GEN -+ -+enum { -+ LRU_GEN_ANON, -+ LRU_GEN_FILE, -+}; -+ -+/* -+ * The youngest generation number is stored in max_seq for both anon and file -+ * types as they are aged on an equal footing. The oldest generation numbers are -+ * stored in min_seq[] separately for anon and file types as clean file pages -+ * can be evicted regardless of swap constraints. -+ * -+ * Normally anon and file min_seq are in sync. But if swapping is constrained, -+ * e.g., out of swap space, file min_seq is allowed to advance and leave anon -+ * min_seq behind. -+ * -+ * The number of pages in each generation is eventually consistent and therefore -+ * can be transiently negative. -+ */ -+struct lru_gen_struct { -+ /* the aging increments the youngest generation number */ -+ unsigned long max_seq; -+ /* the eviction increments the oldest generation numbers */ -+ unsigned long min_seq[ANON_AND_FILE]; -+ /* the multi-gen LRU lists, lazily sorted on eviction */ -+ struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ /* the multi-gen LRU sizes, eventually consistent */ -+ long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+}; -+ -+void lru_gen_init_lruvec(struct lruvec *lruvec); -+ -+#ifdef CONFIG_MEMCG -+void lru_gen_init_memcg(struct mem_cgroup *memcg); -+void lru_gen_exit_memcg(struct mem_cgroup *memcg); -+#endif -+ -+#else /* !CONFIG_LRU_GEN */ -+ -+static inline void lru_gen_init_lruvec(struct lruvec *lruvec) -+{ -+} -+ -+#ifdef CONFIG_MEMCG -+static inline void lru_gen_init_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg) -+{ -+} -+#endif -+ -+#endif /* CONFIG_LRU_GEN */ -+ - struct lruvec { - struct list_head lists[NR_LRU_LISTS]; - /* per lruvec lru_lock for memcg */ -@@ -331,6 +427,10 @@ struct lruvec { - unsigned long refaults[ANON_AND_FILE]; - /* Various lruvec state flags (enum lruvec_flags) */ - unsigned long flags; -+#ifdef CONFIG_LRU_GEN -+ /* evictable pages divided into generations */ -+ struct lru_gen_struct lrugen; -+#endif - #ifdef CONFIG_MEMCG - struct pglist_data *pgdat; - #endif -@@ -746,6 +846,8 @@ static inline bool zone_is_empty(struct - #define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH) - #define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH) - #define KASAN_TAG_PGOFF (LAST_CPUPID_PGOFF - KASAN_TAG_WIDTH) -+#define LRU_GEN_PGOFF (KASAN_TAG_PGOFF - LRU_GEN_WIDTH) -+#define LRU_REFS_PGOFF (LRU_GEN_PGOFF - LRU_REFS_WIDTH) - - /* - * Define the bit shifts to access each section. For non-existent ---- a/include/linux/page-flags-layout.h -+++ b/include/linux/page-flags-layout.h -@@ -55,7 +55,8 @@ - #define SECTIONS_WIDTH 0 - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_SHIFT \ -+ <= BITS_PER_LONG - NR_PAGEFLAGS - #define NODES_WIDTH NODES_SHIFT - #elif defined(CONFIG_SPARSEMEM_VMEMMAP) - #error "Vmemmap: No space for nodes field in page flags" -@@ -89,8 +90,8 @@ - #define LAST_CPUPID_SHIFT 0 - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT \ -- <= BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \ -+ KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS - #define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT - #else - #define LAST_CPUPID_WIDTH 0 -@@ -100,10 +101,12 @@ - #define LAST_CPUPID_NOT_IN_PAGE_FLAGS - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH \ -- > BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \ -+ KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH > BITS_PER_LONG - NR_PAGEFLAGS - #error "Not enough bits in page flags" - #endif - -+#define LRU_REFS_WIDTH 0 -+ - #endif - #endif /* _LINUX_PAGE_FLAGS_LAYOUT */ ---- a/include/linux/page-flags.h -+++ b/include/linux/page-flags.h -@@ -1058,7 +1058,7 @@ static __always_inline void __ClearPageA - 1UL << PG_private | 1UL << PG_private_2 | \ - 1UL << PG_writeback | 1UL << PG_reserved | \ - 1UL << PG_slab | 1UL << PG_active | \ -- 1UL << PG_unevictable | __PG_MLOCKED) -+ 1UL << PG_unevictable | __PG_MLOCKED | LRU_GEN_MASK) - - /* - * Flags checked when a page is prepped for return by the page allocator. -@@ -1069,7 +1069,7 @@ static __always_inline void __ClearPageA - * alloc-free cycle to prevent from reusing the page. - */ - #define PAGE_FLAGS_CHECK_AT_PREP \ -- (PAGEFLAGS_MASK & ~__PG_HWPOISON) -+ ((PAGEFLAGS_MASK & ~__PG_HWPOISON) | LRU_GEN_MASK | LRU_REFS_MASK) - - #define PAGE_FLAGS_PRIVATE \ - (1UL << PG_private | 1UL << PG_private_2) ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -914,6 +914,10 @@ struct task_struct { - #ifdef CONFIG_MEMCG - unsigned in_user_fault:1; - #endif -+#ifdef CONFIG_LRU_GEN -+ /* whether the LRU algorithm may apply to this access */ -+ unsigned in_lru_fault:1; -+#endif - #ifdef CONFIG_COMPAT_BRK - unsigned brk_randomized:1; - #endif ---- a/kernel/bounds.c -+++ b/kernel/bounds.c -@@ -22,6 +22,11 @@ int main(void) - DEFINE(NR_CPUS_BITS, ilog2(CONFIG_NR_CPUS)); - #endif - DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t)); -+#ifdef CONFIG_LRU_GEN -+ DEFINE(LRU_GEN_WIDTH, order_base_2(MAX_NR_GENS + 1)); -+#else -+ DEFINE(LRU_GEN_WIDTH, 0); -+#endif - /* End of constants */ - - return 0; ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -1124,6 +1124,14 @@ config PTE_MARKER_UFFD_WP - purposes. It is required to enable userfaultfd write protection on - file-backed memory types like shmem and hugetlbfs. - -+config LRU_GEN -+ bool "Multi-Gen LRU" -+ depends on MMU -+ # make sure folio->flags has enough spare bits -+ depends on 64BIT || !SPARSEMEM || SPARSEMEM_VMEMMAP -+ help -+ A high performance LRU implementation to overcommit memory. -+ - source "mm/damon/Kconfig" - - endmenu ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -2438,7 +2438,8 @@ static void __split_huge_page_tail(struc - #ifdef CONFIG_64BIT - (1L << PG_arch_2) | - #endif -- (1L << PG_dirty))); -+ (1L << PG_dirty) | -+ LRU_GEN_MASK | LRU_REFS_MASK)); - - /* ->mapping in first tail page is compound_mapcount */ - VM_BUG_ON_PAGE(tail > 2 && page_tail->mapping != TAIL_MAPPING, ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -5170,6 +5170,7 @@ static void __mem_cgroup_free(struct mem - - static void mem_cgroup_free(struct mem_cgroup *memcg) - { -+ lru_gen_exit_memcg(memcg); - memcg_wb_domain_exit(memcg); - __mem_cgroup_free(memcg); - } -@@ -5228,6 +5229,7 @@ static struct mem_cgroup *mem_cgroup_all - memcg->deferred_split_queue.split_queue_len = 0; - #endif - idr_replace(&mem_cgroup_idr, memcg, memcg->id.id); -+ lru_gen_init_memcg(memcg); - return memcg; - fail: - mem_cgroup_id_remove(memcg); ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -5110,6 +5110,27 @@ static inline void mm_account_fault(stru - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); - } - -+#ifdef CONFIG_LRU_GEN -+static void lru_gen_enter_fault(struct vm_area_struct *vma) -+{ -+ /* the LRU algorithm doesn't apply to sequential or random reads */ -+ current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)); -+} -+ -+static void lru_gen_exit_fault(void) -+{ -+ current->in_lru_fault = false; -+} -+#else -+static void lru_gen_enter_fault(struct vm_area_struct *vma) -+{ -+} -+ -+static void lru_gen_exit_fault(void) -+{ -+} -+#endif /* CONFIG_LRU_GEN */ -+ - /* - * By the time we get here, we already hold the mm semaphore - * -@@ -5141,11 +5162,15 @@ vm_fault_t handle_mm_fault(struct vm_are - if (flags & FAULT_FLAG_USER) - mem_cgroup_enter_user_fault(); - -+ lru_gen_enter_fault(vma); -+ - if (unlikely(is_vm_hugetlb_page(vma))) - ret = hugetlb_fault(vma->vm_mm, vma, address, flags); - else - ret = __handle_mm_fault(vma, address, flags); - -+ lru_gen_exit_fault(); -+ - if (flags & FAULT_FLAG_USER) { - mem_cgroup_exit_user_fault(); - /* ---- a/mm/mm_init.c -+++ b/mm/mm_init.c -@@ -65,14 +65,16 @@ void __init mminit_verify_pageflags_layo - - shift = 8 * sizeof(unsigned long); - width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH -- - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH; -+ - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH - LRU_GEN_WIDTH - LRU_REFS_WIDTH; - mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths", -- "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Flags %d\n", -+ "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Gen %d Tier %d Flags %d\n", - SECTIONS_WIDTH, - NODES_WIDTH, - ZONES_WIDTH, - LAST_CPUPID_WIDTH, - KASAN_TAG_WIDTH, -+ LRU_GEN_WIDTH, -+ LRU_REFS_WIDTH, - NR_PAGEFLAGS); - mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts", - "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d\n", ---- a/mm/mmzone.c -+++ b/mm/mmzone.c -@@ -88,6 +88,8 @@ void lruvec_init(struct lruvec *lruvec) - * Poison its list head, so that any operations on it would crash. - */ - list_del(&lruvec->lists[LRU_UNEVICTABLE]); -+ -+ lru_gen_init_lruvec(lruvec); - } - - #if defined(CONFIG_NUMA_BALANCING) && !defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS) ---- a/mm/swap.c -+++ b/mm/swap.c -@@ -484,6 +484,11 @@ void folio_add_lru(struct folio *folio) - folio_test_unevictable(folio), folio); - VM_BUG_ON_FOLIO(folio_test_lru(folio), folio); - -+ /* see the comment in lru_gen_add_folio() */ -+ if (lru_gen_enabled() && !folio_test_unevictable(folio) && -+ lru_gen_in_fault() && !(current->flags & PF_MEMALLOC)) -+ folio_set_active(folio); -+ - folio_get(folio); - local_lock(&cpu_fbatches.lock); - fbatch = this_cpu_ptr(&cpu_fbatches.lru_add); -@@ -575,7 +580,7 @@ static void lru_deactivate_file_fn(struc - - static void lru_deactivate_fn(struct lruvec *lruvec, struct folio *folio) - { -- if (folio_test_active(folio) && !folio_test_unevictable(folio)) { -+ if (!folio_test_unevictable(folio) && (folio_test_active(folio) || lru_gen_enabled())) { - long nr_pages = folio_nr_pages(folio); - - lruvec_del_folio(lruvec, folio); -@@ -688,8 +693,8 @@ void deactivate_page(struct page *page) - { - struct folio *folio = page_folio(page); - -- if (folio_test_lru(folio) && folio_test_active(folio) && -- !folio_test_unevictable(folio)) { -+ if (folio_test_lru(folio) && !folio_test_unevictable(folio) && -+ (folio_test_active(folio) || lru_gen_enabled())) { - struct folio_batch *fbatch; - - folio_get(folio); ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3050,6 +3050,81 @@ static bool can_age_anon_pages(struct pg - return can_demote(pgdat->node_id, sc); - } - -+#ifdef CONFIG_LRU_GEN -+ -+/****************************************************************************** -+ * shorthand helpers -+ ******************************************************************************/ -+ -+#define for_each_gen_type_zone(gen, type, zone) \ -+ for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++) \ -+ for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ -+ for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) -+ -+static struct lruvec __maybe_unused *get_lruvec(struct mem_cgroup *memcg, int nid) -+{ -+ struct pglist_data *pgdat = NODE_DATA(nid); -+ -+#ifdef CONFIG_MEMCG -+ if (memcg) { -+ struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec; -+ -+ /* for hotadd_new_pgdat() */ -+ if (!lruvec->pgdat) -+ lruvec->pgdat = pgdat; -+ -+ return lruvec; -+ } -+#endif -+ VM_WARN_ON_ONCE(!mem_cgroup_disabled()); -+ -+ return pgdat ? &pgdat->__lruvec : NULL; -+} -+ -+/****************************************************************************** -+ * initialization -+ ******************************************************************************/ -+ -+void lru_gen_init_lruvec(struct lruvec *lruvec) -+{ -+ int gen, type, zone; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ lrugen->max_seq = MIN_NR_GENS + 1; -+ -+ for_each_gen_type_zone(gen, type, zone) -+ INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -+} -+ -+#ifdef CONFIG_MEMCG -+void lru_gen_init_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+void lru_gen_exit_memcg(struct mem_cgroup *memcg) -+{ -+ int nid; -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, -+ sizeof(lruvec->lrugen.nr_pages))); -+ } -+} -+#endif -+ -+static int __init init_lru_gen(void) -+{ -+ BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS); -+ BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS); -+ -+ return 0; -+}; -+late_initcall(init_lru_gen); -+ -+#endif /* CONFIG_LRU_GEN */ -+ - static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - unsigned long nr[NR_LRU_LISTS]; diff --git a/target/linux/generic/backport-6.0/105-mm-multi-gen-LRU-minimal-implementation.patch b/target/linux/generic/backport-6.0/105-mm-multi-gen-LRU-minimal-implementation.patch deleted file mode 100644 index 0952c9704..000000000 --- a/target/linux/generic/backport-6.0/105-mm-multi-gen-LRU-minimal-implementation.patch +++ /dev/null @@ -1,1425 +0,0 @@ -From b676b5241d96d7fb2bf298190e750c6099cc0313 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Thu, 27 Jan 2022 20:32:37 -0700 -Subject: [PATCH 06/14] mm: multi-gen LRU: minimal implementation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -To avoid confusion, the terms "promotion" and "demotion" will be -applied to the multi-gen LRU, as a new convention; the terms -"activation" and "deactivation" will be applied to the active/inactive -LRU, as usual. - -The aging produces young generations. Given an lruvec, it increments -max_seq when max_seq-min_seq+1 approaches MIN_NR_GENS. The aging -promotes hot pages to the youngest generation when it finds them -accessed through page tables; the demotion of cold pages happens -consequently when it increments max_seq. Promotion in the aging path -does not involve any LRU list operations, only the updates of the gen -counter and lrugen->nr_pages[]; demotion, unless as the result of the -increment of max_seq, requires LRU list operations, e.g., -lru_deactivate_fn(). The aging has the complexity O(nr_hot_pages), -since it is only interested in hot pages. - -The eviction consumes old generations. Given an lruvec, it increments -min_seq when lrugen->lists[] indexed by min_seq%MAX_NR_GENS becomes -empty. A feedback loop modeled after the PID controller monitors -refaults over anon and file types and decides which type to evict when -both types are available from the same generation. - -The protection of pages accessed multiple times through file -descriptors takes place in the eviction path. Each generation is -divided into multiple tiers. A page accessed N times through file -descriptors is in tier order_base_2(N). Tiers do not have dedicated -lrugen->lists[], only bits in folio->flags. The aforementioned -feedback loop also monitors refaults over all tiers and decides when -to protect pages in which tiers (N>1), using the first tier (N=0,1) as -a baseline. The first tier contains single-use unmapped clean pages, -which are most likely the best choices. In contrast to promotion in -the aging path, the protection of a page in the eviction path is -achieved by moving this page to the next generation, i.e., min_seq+1, -if the feedback loop decides so. This approach has the following -advantages: -1. It removes the cost of activation in the buffered access path by - inferring whether pages accessed multiple times through file - descriptors are statistically hot and thus worth protecting in the - eviction path. -2. It takes pages accessed through page tables into account and avoids - overprotecting pages accessed multiple times through file - descriptors. (Pages accessed through page tables are in the first - tier, since N=0.) -3. More tiers provide better protection for pages accessed more than - twice through file descriptors, when under heavy buffered I/O - workloads. - -Server benchmark results: - Single workload: - fio (buffered I/O): +[30, 32]% - IOPS BW - 5.19-rc1: 2673k 10.2GiB/s - patch1-6: 3491k 13.3GiB/s - - Single workload: - memcached (anon): -[4, 6]% - Ops/sec KB/sec - 5.19-rc1: 1161501.04 45177.25 - patch1-6: 1106168.46 43025.04 - - Configurations: - CPU: two Xeon 6154 - Mem: total 256G - - Node 1 was only used as a ram disk to reduce the variance in the - results. - - patch drivers/block/brd.c < gfp_flags = GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM | __GFP_THISNODE; - > page = alloc_pages_node(1, gfp_flags, 0); - EOF - - cat >>/etc/systemd/system.conf <>/etc/memcached.conf </sys/fs/cgroup/user.slice/test/memory.max - echo $$ >/sys/fs/cgroup/user.slice/test/cgroup.procs - fio -name=mglru --numjobs=72 --directory=/mnt --size=1408m \ - --buffered=1 --ioengine=io_uring --iodepth=128 \ - --iodepth_batch_submit=32 --iodepth_batch_complete=32 \ - --rw=randread --random_distribution=random --norandommap \ - --time_based --ramp_time=10m --runtime=5m --group_reporting - - cat memcached.sh - modprobe brd rd_nr=1 rd_size=113246208 - swapoff -a - mkswap /dev/ram0 - swapon /dev/ram0 - - memtier_benchmark -S /var/run/memcached/memcached.sock \ - -P memcache_binary -n allkeys --key-minimum=1 \ - --key-maximum=65000000 --key-pattern=P:P -c 1 -t 36 \ - --ratio 1:0 --pipeline 8 -d 2000 - - memtier_benchmark -S /var/run/memcached/memcached.sock \ - -P memcache_binary -n allkeys --key-minimum=1 \ - --key-maximum=65000000 --key-pattern=R:R -c 1 -t 36 \ - --ratio 0:1 --pipeline 8 --randomize --distinct-client-seed - -Client benchmark results: - kswapd profiles: - 5.19-rc1 - 40.33% page_vma_mapped_walk (overhead) - 21.80% lzo1x_1_do_compress (real work) - 7.53% do_raw_spin_lock - 3.95% _raw_spin_unlock_irq - 2.52% vma_interval_tree_iter_next - 2.37% folio_referenced_one - 2.28% vma_interval_tree_subtree_search - 1.97% anon_vma_interval_tree_iter_first - 1.60% ptep_clear_flush - 1.06% __zram_bvec_write - - patch1-6 - 39.03% lzo1x_1_do_compress (real work) - 18.47% page_vma_mapped_walk (overhead) - 6.74% _raw_spin_unlock_irq - 3.97% do_raw_spin_lock - 2.49% ptep_clear_flush - 2.48% anon_vma_interval_tree_iter_first - 1.92% folio_referenced_one - 1.88% __zram_bvec_write - 1.48% memmove - 1.31% vma_interval_tree_iter_next - - Configurations: - CPU: single Snapdragon 7c - Mem: total 4G - - ChromeOS MemoryPressure [1] - -[1] https://chromium.googlesource.com/chromiumos/platform/tast-tests/ - -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: Id47465f46f1f77f1e9f0be3972e380ddcfa37cc0 ---- - include/linux/mm_inline.h | 36 ++ - include/linux/mmzone.h | 41 ++ - include/linux/page-flags-layout.h | 5 +- - kernel/bounds.c | 2 + - mm/Kconfig | 11 + - mm/swap.c | 39 ++ - mm/vmscan.c | 792 +++++++++++++++++++++++++++++- - mm/workingset.c | 110 ++++- - 8 files changed, 1025 insertions(+), 11 deletions(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -121,6 +121,33 @@ static inline int lru_gen_from_seq(unsig - return seq % MAX_NR_GENS; - } - -+static inline int lru_hist_from_seq(unsigned long seq) -+{ -+ return seq % NR_HIST_GENS; -+} -+ -+static inline int lru_tier_from_refs(int refs) -+{ -+ VM_WARN_ON_ONCE(refs > BIT(LRU_REFS_WIDTH)); -+ -+ /* see the comment in folio_lru_refs() */ -+ return order_base_2(refs + 1); -+} -+ -+static inline int folio_lru_refs(struct folio *folio) -+{ -+ unsigned long flags = READ_ONCE(folio->flags); -+ bool workingset = flags & BIT(PG_workingset); -+ -+ /* -+ * Return the number of accesses beyond PG_referenced, i.e., N-1 if the -+ * total number of accesses is N>1, since N=0,1 both map to the first -+ * tier. lru_tier_from_refs() will account for this off-by-one. Also see -+ * the comment on MAX_NR_TIERS. -+ */ -+ return ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + workingset; -+} -+ - static inline int folio_lru_gen(struct folio *folio) - { - unsigned long flags = READ_ONCE(folio->flags); -@@ -173,6 +200,15 @@ static inline void lru_gen_update_size(s - __update_lru_size(lruvec, lru, zone, -delta); - return; - } -+ -+ /* promotion */ -+ if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruvec, new_gen)) { -+ __update_lru_size(lruvec, lru, zone, -delta); -+ __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, delta); -+ } -+ -+ /* demotion requires isolation, e.g., lru_deactivate_fn() */ -+ VM_WARN_ON_ONCE(lru_gen_is_active(lruvec, old_gen) && !lru_gen_is_active(lruvec, new_gen)); - } - - static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -347,6 +347,28 @@ enum lruvec_flags { - #define MIN_NR_GENS 2U - #define MAX_NR_GENS 4U - -+/* -+ * Each generation is divided into multiple tiers. A page accessed N times -+ * through file descriptors is in tier order_base_2(N). A page in the first tier -+ * (N=0,1) is marked by PG_referenced unless it was faulted in through page -+ * tables or read ahead. A page in any other tier (N>1) is marked by -+ * PG_referenced and PG_workingset. This implies a minimum of two tiers is -+ * supported without using additional bits in folio->flags. -+ * -+ * In contrast to moving across generations which requires the LRU lock, moving -+ * across tiers only involves atomic operations on folio->flags and therefore -+ * has a negligible cost in the buffered access path. In the eviction path, -+ * comparisons of refaulted/(evicted+protected) from the first tier and the -+ * rest infer whether pages accessed multiple times through file descriptors -+ * are statistically hot and thus worth protecting. -+ * -+ * MAX_NR_TIERS is set to 4 so that the multi-gen LRU can support twice the -+ * number of categories of the active/inactive LRU when keeping track of -+ * accesses through file descriptors. This uses MAX_NR_TIERS-2 spare bits in -+ * folio->flags. -+ */ -+#define MAX_NR_TIERS 4U -+ - #ifndef __GENERATING_BOUNDS_H - - struct lruvec; -@@ -361,6 +383,16 @@ enum { - LRU_GEN_FILE, - }; - -+#define MIN_LRU_BATCH BITS_PER_LONG -+#define MAX_LRU_BATCH (MIN_LRU_BATCH * 64) -+ -+/* whether to keep historical stats from evicted generations */ -+#ifdef CONFIG_LRU_GEN_STATS -+#define NR_HIST_GENS MAX_NR_GENS -+#else -+#define NR_HIST_GENS 1U -+#endif -+ - /* - * The youngest generation number is stored in max_seq for both anon and file - * types as they are aged on an equal footing. The oldest generation numbers are -@@ -383,6 +415,15 @@ struct lru_gen_struct { - struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; - /* the multi-gen LRU sizes, eventually consistent */ - long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ /* the exponential moving average of refaulted */ -+ unsigned long avg_refaulted[ANON_AND_FILE][MAX_NR_TIERS]; -+ /* the exponential moving average of evicted+protected */ -+ unsigned long avg_total[ANON_AND_FILE][MAX_NR_TIERS]; -+ /* the first tier doesn't need protection, hence the minus one */ -+ unsigned long protected[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS - 1]; -+ /* can be modified without holding the LRU lock */ -+ atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; -+ atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; - }; - - void lru_gen_init_lruvec(struct lruvec *lruvec); ---- a/include/linux/page-flags-layout.h -+++ b/include/linux/page-flags-layout.h -@@ -106,7 +106,10 @@ - #error "Not enough bits in page flags" - #endif - --#define LRU_REFS_WIDTH 0 -+/* see the comment on MAX_NR_TIERS */ -+#define LRU_REFS_WIDTH min(__LRU_REFS_WIDTH, BITS_PER_LONG - NR_PAGEFLAGS - \ -+ ZONES_WIDTH - LRU_GEN_WIDTH - SECTIONS_WIDTH - \ -+ NODES_WIDTH - KASAN_TAG_WIDTH - LAST_CPUPID_WIDTH) - - #endif - #endif /* _LINUX_PAGE_FLAGS_LAYOUT */ ---- a/kernel/bounds.c -+++ b/kernel/bounds.c -@@ -24,8 +24,10 @@ int main(void) - DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t)); - #ifdef CONFIG_LRU_GEN - DEFINE(LRU_GEN_WIDTH, order_base_2(MAX_NR_GENS + 1)); -+ DEFINE(__LRU_REFS_WIDTH, MAX_NR_TIERS - 2); - #else - DEFINE(LRU_GEN_WIDTH, 0); -+ DEFINE(__LRU_REFS_WIDTH, 0); - #endif - /* End of constants */ - ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -1124,6 +1124,7 @@ config PTE_MARKER_UFFD_WP - purposes. It is required to enable userfaultfd write protection on - file-backed memory types like shmem and hugetlbfs. - -+# multi-gen LRU { - config LRU_GEN - bool "Multi-Gen LRU" - depends on MMU -@@ -1132,6 +1133,16 @@ config LRU_GEN - help - A high performance LRU implementation to overcommit memory. - -+config LRU_GEN_STATS -+ bool "Full stats for debugging" -+ depends on LRU_GEN -+ help -+ Do not enable this option unless you plan to look at historical stats -+ from evicted generations for debugging purpose. -+ -+ This option has a per-memcg and per-node memory overhead. -+# } -+ - source "mm/damon/Kconfig" - - endmenu ---- a/mm/swap.c -+++ b/mm/swap.c -@@ -428,6 +428,40 @@ static void __lru_cache_activate_folio(s - local_unlock(&cpu_fbatches.lock); - } - -+#ifdef CONFIG_LRU_GEN -+static void folio_inc_refs(struct folio *folio) -+{ -+ unsigned long new_flags, old_flags = READ_ONCE(folio->flags); -+ -+ if (folio_test_unevictable(folio)) -+ return; -+ -+ if (!folio_test_referenced(folio)) { -+ folio_set_referenced(folio); -+ return; -+ } -+ -+ if (!folio_test_workingset(folio)) { -+ folio_set_workingset(folio); -+ return; -+ } -+ -+ /* see the comment on MAX_NR_TIERS */ -+ do { -+ new_flags = old_flags & LRU_REFS_MASK; -+ if (new_flags == LRU_REFS_MASK) -+ break; -+ -+ new_flags += BIT(LRU_REFS_PGOFF); -+ new_flags |= old_flags & ~LRU_REFS_MASK; -+ } while (!try_cmpxchg(&folio->flags, &old_flags, new_flags)); -+} -+#else -+static void folio_inc_refs(struct folio *folio) -+{ -+} -+#endif /* CONFIG_LRU_GEN */ -+ - /* - * Mark a page as having seen activity. - * -@@ -440,6 +474,11 @@ static void __lru_cache_activate_folio(s - */ - void folio_mark_accessed(struct folio *folio) - { -+ if (lru_gen_enabled()) { -+ folio_inc_refs(folio); -+ return; -+ } -+ - if (!folio_test_referenced(folio)) { - folio_set_referenced(folio); - } else if (folio_test_unevictable(folio)) { ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -1334,9 +1334,11 @@ static int __remove_mapping(struct addre - - if (folio_test_swapcache(folio)) { - swp_entry_t swap = folio_swap_entry(folio); -- mem_cgroup_swapout(folio, swap); -+ -+ /* get a shadow entry before mem_cgroup_swapout() clears folio_memcg() */ - if (reclaimed && !mapping_exiting(mapping)) - shadow = workingset_eviction(folio, target_memcg); -+ mem_cgroup_swapout(folio, swap); - __delete_from_swap_cache(folio, swap, shadow); - xa_unlock_irq(&mapping->i_pages); - put_swap_page(&folio->page, swap); -@@ -2733,6 +2735,9 @@ static void prepare_scan_count(pg_data_t - unsigned long file; - struct lruvec *target_lruvec; - -+ if (lru_gen_enabled()) -+ return; -+ - target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); - - /* -@@ -3056,6 +3061,17 @@ static bool can_age_anon_pages(struct pg - * shorthand helpers - ******************************************************************************/ - -+#define LRU_REFS_FLAGS (BIT(PG_referenced) | BIT(PG_workingset)) -+ -+#define DEFINE_MAX_SEQ(lruvec) \ -+ unsigned long max_seq = READ_ONCE((lruvec)->lrugen.max_seq) -+ -+#define DEFINE_MIN_SEQ(lruvec) \ -+ unsigned long min_seq[ANON_AND_FILE] = { \ -+ READ_ONCE((lruvec)->lrugen.min_seq[LRU_GEN_ANON]), \ -+ READ_ONCE((lruvec)->lrugen.min_seq[LRU_GEN_FILE]), \ -+ } -+ - #define for_each_gen_type_zone(gen, type, zone) \ - for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++) \ - for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ -@@ -3081,6 +3097,745 @@ static struct lruvec __maybe_unused *get - return pgdat ? &pgdat->__lruvec : NULL; - } - -+static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ if (!can_demote(pgdat->node_id, sc) && -+ mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH) -+ return 0; -+ -+ return mem_cgroup_swappiness(memcg); -+} -+ -+static int get_nr_gens(struct lruvec *lruvec, int type) -+{ -+ return lruvec->lrugen.max_seq - lruvec->lrugen.min_seq[type] + 1; -+} -+ -+static bool __maybe_unused seq_is_valid(struct lruvec *lruvec) -+{ -+ /* see the comment on lru_gen_struct */ -+ return get_nr_gens(lruvec, LRU_GEN_FILE) >= MIN_NR_GENS && -+ get_nr_gens(lruvec, LRU_GEN_FILE) <= get_nr_gens(lruvec, LRU_GEN_ANON) && -+ get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS; -+} -+ -+/****************************************************************************** -+ * refault feedback loop -+ ******************************************************************************/ -+ -+/* -+ * A feedback loop based on Proportional-Integral-Derivative (PID) controller. -+ * -+ * The P term is refaulted/(evicted+protected) from a tier in the generation -+ * currently being evicted; the I term is the exponential moving average of the -+ * P term over the generations previously evicted, using the smoothing factor -+ * 1/2; the D term isn't supported. -+ * -+ * The setpoint (SP) is always the first tier of one type; the process variable -+ * (PV) is either any tier of the other type or any other tier of the same -+ * type. -+ * -+ * The error is the difference between the SP and the PV; the correction is to -+ * turn off protection when SP>PV or turn on protection when SPlrugen; -+ int hist = lru_hist_from_seq(lrugen->min_seq[type]); -+ -+ pos->refaulted = lrugen->avg_refaulted[type][tier] + -+ atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ pos->total = lrugen->avg_total[type][tier] + -+ atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ pos->total += lrugen->protected[hist][type][tier - 1]; -+ pos->gain = gain; -+} -+ -+static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover) -+{ -+ int hist, tier; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1; -+ unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1; -+ -+ lockdep_assert_held(&lruvec->lru_lock); -+ -+ if (!carryover && !clear) -+ return; -+ -+ hist = lru_hist_from_seq(seq); -+ -+ for (tier = 0; tier < MAX_NR_TIERS; tier++) { -+ if (carryover) { -+ unsigned long sum; -+ -+ sum = lrugen->avg_refaulted[type][tier] + -+ atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ WRITE_ONCE(lrugen->avg_refaulted[type][tier], sum / 2); -+ -+ sum = lrugen->avg_total[type][tier] + -+ atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ sum += lrugen->protected[hist][type][tier - 1]; -+ WRITE_ONCE(lrugen->avg_total[type][tier], sum / 2); -+ } -+ -+ if (clear) { -+ atomic_long_set(&lrugen->refaulted[hist][type][tier], 0); -+ atomic_long_set(&lrugen->evicted[hist][type][tier], 0); -+ if (tier) -+ WRITE_ONCE(lrugen->protected[hist][type][tier - 1], 0); -+ } -+ } -+} -+ -+static bool positive_ctrl_err(struct ctrl_pos *sp, struct ctrl_pos *pv) -+{ -+ /* -+ * Return true if the PV has a limited number of refaults or a lower -+ * refaulted/total than the SP. -+ */ -+ return pv->refaulted < MIN_LRU_BATCH || -+ pv->refaulted * (sp->total + MIN_LRU_BATCH) * sp->gain <= -+ (sp->refaulted + 1) * pv->total * pv->gain; -+} -+ -+/****************************************************************************** -+ * the aging -+ ******************************************************************************/ -+ -+/* protect pages accessed multiple times through file descriptors */ -+static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclaiming) -+{ -+ int type = folio_is_file_lru(folio); -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ unsigned long new_flags, old_flags = READ_ONCE(folio->flags); -+ -+ VM_WARN_ON_ONCE_FOLIO(!(old_flags & LRU_GEN_MASK), folio); -+ -+ do { -+ new_gen = (old_gen + 1) % MAX_NR_GENS; -+ -+ new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS); -+ new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF; -+ /* for folio_end_writeback() */ -+ if (reclaiming) -+ new_flags |= BIT(PG_reclaim); -+ } while (!try_cmpxchg(&folio->flags, &old_flags, new_flags)); -+ -+ lru_gen_update_size(lruvec, folio, old_gen, new_gen); -+ -+ return new_gen; -+} -+ -+static void inc_min_seq(struct lruvec *lruvec, int type) -+{ -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ reset_ctrl_pos(lruvec, type, true); -+ WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1); -+} -+ -+static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap) -+{ -+ int gen, type, zone; -+ bool success = false; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ DEFINE_MIN_SEQ(lruvec); -+ -+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -+ -+ /* find the oldest populated generation */ -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ while (min_seq[type] + MIN_NR_GENS <= lrugen->max_seq) { -+ gen = lru_gen_from_seq(min_seq[type]); -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) { -+ if (!list_empty(&lrugen->lists[gen][type][zone])) -+ goto next; -+ } -+ -+ min_seq[type]++; -+ } -+next: -+ ; -+ } -+ -+ /* see the comment on lru_gen_struct */ -+ if (can_swap) { -+ min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]); -+ min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]); -+ } -+ -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ if (min_seq[type] == lrugen->min_seq[type]) -+ continue; -+ -+ reset_ctrl_pos(lruvec, type, true); -+ WRITE_ONCE(lrugen->min_seq[type], min_seq[type]); -+ success = true; -+ } -+ -+ return success; -+} -+ -+static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, bool can_swap) -+{ -+ int prev, next; -+ int type, zone; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -+ -+ if (max_seq != lrugen->max_seq) -+ goto unlock; -+ -+ for (type = ANON_AND_FILE - 1; type >= 0; type--) { -+ if (get_nr_gens(lruvec, type) != MAX_NR_GENS) -+ continue; -+ -+ VM_WARN_ON_ONCE(type == LRU_GEN_FILE || can_swap); -+ -+ inc_min_seq(lruvec, type); -+ } -+ -+ /* -+ * Update the active/inactive LRU sizes for compatibility. Both sides of -+ * the current max_seq need to be covered, since max_seq+1 can overlap -+ * with min_seq[LRU_GEN_ANON] if swapping is constrained. And if they do -+ * overlap, cold/hot inversion happens. -+ */ -+ prev = lru_gen_from_seq(lrugen->max_seq - 1); -+ next = lru_gen_from_seq(lrugen->max_seq + 1); -+ -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) { -+ enum lru_list lru = type * LRU_INACTIVE_FILE; -+ long delta = lrugen->nr_pages[prev][type][zone] - -+ lrugen->nr_pages[next][type][zone]; -+ -+ if (!delta) -+ continue; -+ -+ __update_lru_size(lruvec, lru, zone, delta); -+ __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, -delta); -+ } -+ } -+ -+ for (type = 0; type < ANON_AND_FILE; type++) -+ reset_ctrl_pos(lruvec, type, false); -+ -+ /* make sure preceding modifications appear */ -+ smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1); -+unlock: -+ spin_unlock_irq(&lruvec->lru_lock); -+} -+ -+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq, -+ struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) -+{ -+ int gen, type, zone; -+ unsigned long old = 0; -+ unsigned long young = 0; -+ unsigned long total = 0; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ unsigned long seq; -+ -+ for (seq = min_seq[type]; seq <= max_seq; seq++) { -+ unsigned long size = 0; -+ -+ gen = lru_gen_from_seq(seq); -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -+ -+ total += size; -+ if (seq == max_seq) -+ young += size; -+ else if (seq + MIN_NR_GENS == max_seq) -+ old += size; -+ } -+ } -+ -+ /* try to scrape all its memory if this memcg was deleted */ -+ *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total; -+ -+ /* -+ * The aging tries to be lazy to reduce the overhead, while the eviction -+ * stalls when the number of generations reaches MIN_NR_GENS. Hence, the -+ * ideal number of generations is MIN_NR_GENS+1. -+ */ -+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) -+ return true; -+ if (min_seq[!can_swap] + MIN_NR_GENS < max_seq) -+ return false; -+ -+ /* -+ * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1) -+ * of the total number of pages for each generation. A reasonable range -+ * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The -+ * aging cares about the upper bound of hot pages, while the eviction -+ * cares about the lower bound of cold pages. -+ */ -+ if (young * MIN_NR_GENS > total) -+ return true; -+ if (old * (MIN_NR_GENS + 2) < total) -+ return true; -+ -+ return false; -+} -+ -+static void age_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ bool need_aging; -+ unsigned long nr_to_scan; -+ int swappiness = get_swappiness(lruvec, sc); -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ VM_WARN_ON_ONCE(sc->memcg_low_reclaim); -+ -+ mem_cgroup_calculate_protection(NULL, memcg); -+ -+ if (mem_cgroup_below_min(memcg)) -+ return; -+ -+ need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); -+ if (need_aging) -+ inc_max_seq(lruvec, max_seq, swappiness); -+} -+ -+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ struct mem_cgroup *memcg; -+ -+ VM_WARN_ON_ONCE(!current_is_kswapd()); -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ -+ age_lruvec(lruvec, sc); -+ -+ cond_resched(); -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+} -+ -+/****************************************************************************** -+ * the eviction -+ ******************************************************************************/ -+ -+static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx) -+{ -+ bool success; -+ int gen = folio_lru_gen(folio); -+ int type = folio_is_file_lru(folio); -+ int zone = folio_zonenum(folio); -+ int delta = folio_nr_pages(folio); -+ int refs = folio_lru_refs(folio); -+ int tier = lru_tier_from_refs(refs); -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio); -+ -+ /* unevictable */ -+ if (!folio_evictable(folio)) { -+ success = lru_gen_del_folio(lruvec, folio, true); -+ VM_WARN_ON_ONCE_FOLIO(!success, folio); -+ folio_set_unevictable(folio); -+ lruvec_add_folio(lruvec, folio); -+ __count_vm_events(UNEVICTABLE_PGCULLED, delta); -+ return true; -+ } -+ -+ /* dirty lazyfree */ -+ if (type == LRU_GEN_FILE && folio_test_anon(folio) && folio_test_dirty(folio)) { -+ success = lru_gen_del_folio(lruvec, folio, true); -+ VM_WARN_ON_ONCE_FOLIO(!success, folio); -+ folio_set_swapbacked(folio); -+ lruvec_add_folio_tail(lruvec, folio); -+ return true; -+ } -+ -+ /* protected */ -+ if (tier > tier_idx) { -+ int hist = lru_hist_from_seq(lrugen->min_seq[type]); -+ -+ gen = folio_inc_gen(lruvec, folio, false); -+ list_move_tail(&folio->lru, &lrugen->lists[gen][type][zone]); -+ -+ WRITE_ONCE(lrugen->protected[hist][type][tier - 1], -+ lrugen->protected[hist][type][tier - 1] + delta); -+ __mod_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + type, delta); -+ return true; -+ } -+ -+ /* waiting for writeback */ -+ if (folio_test_locked(folio) || folio_test_writeback(folio) || -+ (type == LRU_GEN_FILE && folio_test_dirty(folio))) { -+ gen = folio_inc_gen(lruvec, folio, true); -+ list_move(&folio->lru, &lrugen->lists[gen][type][zone]); -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool isolate_folio(struct lruvec *lruvec, struct folio *folio, struct scan_control *sc) -+{ -+ bool success; -+ -+ /* unmapping inhibited */ -+ if (!sc->may_unmap && folio_mapped(folio)) -+ return false; -+ -+ /* swapping inhibited */ -+ if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) && -+ (folio_test_dirty(folio) || -+ (folio_test_anon(folio) && !folio_test_swapcache(folio)))) -+ return false; -+ -+ /* raced with release_pages() */ -+ if (!folio_try_get(folio)) -+ return false; -+ -+ /* raced with another isolation */ -+ if (!folio_test_clear_lru(folio)) { -+ folio_put(folio); -+ return false; -+ } -+ -+ /* see the comment on MAX_NR_TIERS */ -+ if (!folio_test_referenced(folio)) -+ set_mask_bits(&folio->flags, LRU_REFS_MASK | LRU_REFS_FLAGS, 0); -+ -+ /* for shrink_page_list() */ -+ folio_clear_reclaim(folio); -+ folio_clear_referenced(folio); -+ -+ success = lru_gen_del_folio(lruvec, folio, true); -+ VM_WARN_ON_ONCE_FOLIO(!success, folio); -+ -+ return true; -+} -+ -+static int scan_folios(struct lruvec *lruvec, struct scan_control *sc, -+ int type, int tier, struct list_head *list) -+{ -+ int gen, zone; -+ enum vm_event_item item; -+ int sorted = 0; -+ int scanned = 0; -+ int isolated = 0; -+ int remaining = MAX_LRU_BATCH; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ -+ VM_WARN_ON_ONCE(!list_empty(list)); -+ -+ if (get_nr_gens(lruvec, type) == MIN_NR_GENS) -+ return 0; -+ -+ gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ for (zone = sc->reclaim_idx; zone >= 0; zone--) { -+ LIST_HEAD(moved); -+ int skipped = 0; -+ struct list_head *head = &lrugen->lists[gen][type][zone]; -+ -+ while (!list_empty(head)) { -+ struct folio *folio = lru_to_folio(head); -+ int delta = folio_nr_pages(folio); -+ -+ VM_WARN_ON_ONCE_FOLIO(folio_test_unevictable(folio), folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_test_active(folio), folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_is_file_lru(folio) != type, folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio); -+ -+ scanned += delta; -+ -+ if (sort_folio(lruvec, folio, tier)) -+ sorted += delta; -+ else if (isolate_folio(lruvec, folio, sc)) { -+ list_add(&folio->lru, list); -+ isolated += delta; -+ } else { -+ list_move(&folio->lru, &moved); -+ skipped += delta; -+ } -+ -+ if (!--remaining || max(isolated, skipped) >= MIN_LRU_BATCH) -+ break; -+ } -+ -+ if (skipped) { -+ list_splice(&moved, head); -+ __count_zid_vm_events(PGSCAN_SKIP, zone, skipped); -+ } -+ -+ if (!remaining || isolated >= MIN_LRU_BATCH) -+ break; -+ } -+ -+ item = current_is_kswapd() ? PGSCAN_KSWAPD : PGSCAN_DIRECT; -+ if (!cgroup_reclaim(sc)) { -+ __count_vm_events(item, isolated); -+ __count_vm_events(PGREFILL, sorted); -+ } -+ __count_memcg_events(memcg, item, isolated); -+ __count_memcg_events(memcg, PGREFILL, sorted); -+ __count_vm_events(PGSCAN_ANON + type, isolated); -+ -+ /* -+ * There might not be eligible pages due to reclaim_idx, may_unmap and -+ * may_writepage. Check the remaining to prevent livelock if it's not -+ * making progress. -+ */ -+ return isolated || !remaining ? scanned : 0; -+} -+ -+static int get_tier_idx(struct lruvec *lruvec, int type) -+{ -+ int tier; -+ struct ctrl_pos sp, pv; -+ -+ /* -+ * To leave a margin for fluctuations, use a larger gain factor (1:2). -+ * This value is chosen because any other tier would have at least twice -+ * as many refaults as the first tier. -+ */ -+ read_ctrl_pos(lruvec, type, 0, 1, &sp); -+ for (tier = 1; tier < MAX_NR_TIERS; tier++) { -+ read_ctrl_pos(lruvec, type, tier, 2, &pv); -+ if (!positive_ctrl_err(&sp, &pv)) -+ break; -+ } -+ -+ return tier - 1; -+} -+ -+static int get_type_to_scan(struct lruvec *lruvec, int swappiness, int *tier_idx) -+{ -+ int type, tier; -+ struct ctrl_pos sp, pv; -+ int gain[ANON_AND_FILE] = { swappiness, 200 - swappiness }; -+ -+ /* -+ * Compare the first tier of anon with that of file to determine which -+ * type to scan. Also need to compare other tiers of the selected type -+ * with the first tier of the other type to determine the last tier (of -+ * the selected type) to evict. -+ */ -+ read_ctrl_pos(lruvec, LRU_GEN_ANON, 0, gain[LRU_GEN_ANON], &sp); -+ read_ctrl_pos(lruvec, LRU_GEN_FILE, 0, gain[LRU_GEN_FILE], &pv); -+ type = positive_ctrl_err(&sp, &pv); -+ -+ read_ctrl_pos(lruvec, !type, 0, gain[!type], &sp); -+ for (tier = 1; tier < MAX_NR_TIERS; tier++) { -+ read_ctrl_pos(lruvec, type, tier, gain[type], &pv); -+ if (!positive_ctrl_err(&sp, &pv)) -+ break; -+ } -+ -+ *tier_idx = tier - 1; -+ -+ return type; -+} -+ -+static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness, -+ int *type_scanned, struct list_head *list) -+{ -+ int i; -+ int type; -+ int scanned; -+ int tier = -1; -+ DEFINE_MIN_SEQ(lruvec); -+ -+ /* -+ * Try to make the obvious choice first. When anon and file are both -+ * available from the same generation, interpret swappiness 1 as file -+ * first and 200 as anon first. -+ */ -+ if (!swappiness) -+ type = LRU_GEN_FILE; -+ else if (min_seq[LRU_GEN_ANON] < min_seq[LRU_GEN_FILE]) -+ type = LRU_GEN_ANON; -+ else if (swappiness == 1) -+ type = LRU_GEN_FILE; -+ else if (swappiness == 200) -+ type = LRU_GEN_ANON; -+ else -+ type = get_type_to_scan(lruvec, swappiness, &tier); -+ -+ for (i = !swappiness; i < ANON_AND_FILE; i++) { -+ if (tier < 0) -+ tier = get_tier_idx(lruvec, type); -+ -+ scanned = scan_folios(lruvec, sc, type, tier, list); -+ if (scanned) -+ break; -+ -+ type = !type; -+ tier = -1; -+ } -+ -+ *type_scanned = type; -+ -+ return scanned; -+} -+ -+static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness) -+{ -+ int type; -+ int scanned; -+ int reclaimed; -+ LIST_HEAD(list); -+ struct folio *folio; -+ enum vm_event_item item; -+ struct reclaim_stat stat; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ scanned = isolate_folios(lruvec, sc, swappiness, &type, &list); -+ -+ scanned += try_to_inc_min_seq(lruvec, swappiness); -+ -+ if (get_nr_gens(lruvec, !swappiness) == MIN_NR_GENS) -+ scanned = 0; -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ -+ if (list_empty(&list)) -+ return scanned; -+ -+ reclaimed = shrink_page_list(&list, pgdat, sc, &stat, false); -+ -+ list_for_each_entry(folio, &list, lru) { -+ /* restore LRU_REFS_FLAGS cleared by isolate_folio() */ -+ if (folio_test_workingset(folio)) -+ folio_set_referenced(folio); -+ -+ /* don't add rejected pages to the oldest generation */ -+ if (folio_test_reclaim(folio) && -+ (folio_test_dirty(folio) || folio_test_writeback(folio))) -+ folio_clear_active(folio); -+ else -+ folio_set_active(folio); -+ } -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ move_pages_to_lru(lruvec, &list); -+ -+ item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT; -+ if (!cgroup_reclaim(sc)) -+ __count_vm_events(item, reclaimed); -+ __count_memcg_events(memcg, item, reclaimed); -+ __count_vm_events(PGSTEAL_ANON + type, reclaimed); -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ -+ mem_cgroup_uncharge_list(&list); -+ free_unref_page_list(&list); -+ -+ sc->nr_reclaimed += reclaimed; -+ -+ return scanned; -+} -+ -+static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, -+ bool can_swap) -+{ -+ bool need_aging; -+ unsigned long nr_to_scan; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (mem_cgroup_below_min(memcg) || -+ (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) -+ return 0; -+ -+ need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); -+ if (!need_aging) -+ return nr_to_scan; -+ -+ /* skip the aging path at the default priority */ -+ if (sc->priority == DEF_PRIORITY) -+ goto done; -+ -+ /* leave the work to lru_gen_age_node() */ -+ if (current_is_kswapd()) -+ return 0; -+ -+ inc_max_seq(lruvec, max_seq, can_swap); -+done: -+ return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ struct blk_plug plug; -+ unsigned long scanned = 0; -+ -+ lru_add_drain(); -+ -+ blk_start_plug(&plug); -+ -+ while (true) { -+ int delta; -+ int swappiness; -+ unsigned long nr_to_scan; -+ -+ if (sc->may_swap) -+ swappiness = get_swappiness(lruvec, sc); -+ else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc)) -+ swappiness = 1; -+ else -+ swappiness = 0; -+ -+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); -+ if (!nr_to_scan) -+ break; -+ -+ delta = evict_folios(lruvec, sc, swappiness); -+ if (!delta) -+ break; -+ -+ scanned += delta; -+ if (scanned >= nr_to_scan) -+ break; -+ -+ cond_resched(); -+ } -+ -+ blk_finish_plug(&plug); -+} -+ - /****************************************************************************** - * initialization - ******************************************************************************/ -@@ -3123,6 +3878,16 @@ static int __init init_lru_gen(void) - }; - late_initcall(init_lru_gen); - -+#else /* !CONFIG_LRU_GEN */ -+ -+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+} -+ - #endif /* CONFIG_LRU_GEN */ - - static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -@@ -3136,6 +3901,11 @@ static void shrink_lruvec(struct lruvec - struct blk_plug plug; - bool scan_adjusted; - -+ if (lru_gen_enabled()) { -+ lru_gen_shrink_lruvec(lruvec, sc); -+ return; -+ } -+ - get_scan_count(lruvec, sc, nr); - - /* Record the original scan target for proportional adjustments later */ -@@ -3642,6 +4412,9 @@ static void snapshot_refaults(struct mem - struct lruvec *target_lruvec; - unsigned long refaults; - -+ if (lru_gen_enabled()) -+ return; -+ - target_lruvec = mem_cgroup_lruvec(target_memcg, pgdat); - refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_ANON); - target_lruvec->refaults[0] = refaults; -@@ -4008,12 +4781,16 @@ unsigned long try_to_free_mem_cgroup_pag - } - #endif - --static void age_active_anon(struct pglist_data *pgdat, -- struct scan_control *sc) -+static void kswapd_age_node(struct pglist_data *pgdat, struct scan_control *sc) - { - struct mem_cgroup *memcg; - struct lruvec *lruvec; - -+ if (lru_gen_enabled()) { -+ lru_gen_age_node(pgdat, sc); -+ return; -+ } -+ - if (!can_age_anon_pages(pgdat, sc)) - return; - -@@ -4333,12 +5110,11 @@ restart: - sc.may_swap = !nr_boost_reclaim; - - /* -- * Do some background aging of the anon list, to give -- * pages a chance to be referenced before reclaiming. All -- * pages are rotated regardless of classzone as this is -- * about consistent aging. -+ * Do some background aging, to give pages a chance to be -+ * referenced before reclaiming. All pages are rotated -+ * regardless of classzone as this is about consistent aging. - */ -- age_active_anon(pgdat, &sc); -+ kswapd_age_node(pgdat, &sc); - - /* - * If we're getting trouble reclaiming, start doing writepage ---- a/mm/workingset.c -+++ b/mm/workingset.c -@@ -187,7 +187,6 @@ static unsigned int bucket_order __read_ - static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long eviction, - bool workingset) - { -- eviction >>= bucket_order; - eviction &= EVICTION_MASK; - eviction = (eviction << MEM_CGROUP_ID_SHIFT) | memcgid; - eviction = (eviction << NODES_SHIFT) | pgdat->node_id; -@@ -212,10 +211,107 @@ static void unpack_shadow(void *shadow, - - *memcgidp = memcgid; - *pgdat = NODE_DATA(nid); -- *evictionp = entry << bucket_order; -+ *evictionp = entry; - *workingsetp = workingset; - } - -+#ifdef CONFIG_LRU_GEN -+ -+static void *lru_gen_eviction(struct folio *folio) -+{ -+ int hist; -+ unsigned long token; -+ unsigned long min_seq; -+ struct lruvec *lruvec; -+ struct lru_gen_struct *lrugen; -+ int type = folio_is_file_lru(folio); -+ int delta = folio_nr_pages(folio); -+ int refs = folio_lru_refs(folio); -+ int tier = lru_tier_from_refs(refs); -+ struct mem_cgroup *memcg = folio_memcg(folio); -+ struct pglist_data *pgdat = folio_pgdat(folio); -+ -+ BUILD_BUG_ON(LRU_GEN_WIDTH + LRU_REFS_WIDTH > BITS_PER_LONG - EVICTION_SHIFT); -+ -+ lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ lrugen = &lruvec->lrugen; -+ min_seq = READ_ONCE(lrugen->min_seq[type]); -+ token = (min_seq << LRU_REFS_WIDTH) | max(refs - 1, 0); -+ -+ hist = lru_hist_from_seq(min_seq); -+ atomic_long_add(delta, &lrugen->evicted[hist][type][tier]); -+ -+ return pack_shadow(mem_cgroup_id(memcg), pgdat, token, refs); -+} -+ -+static void lru_gen_refault(struct folio *folio, void *shadow) -+{ -+ int hist, tier, refs; -+ int memcg_id; -+ bool workingset; -+ unsigned long token; -+ unsigned long min_seq; -+ struct lruvec *lruvec; -+ struct lru_gen_struct *lrugen; -+ struct mem_cgroup *memcg; -+ struct pglist_data *pgdat; -+ int type = folio_is_file_lru(folio); -+ int delta = folio_nr_pages(folio); -+ -+ unpack_shadow(shadow, &memcg_id, &pgdat, &token, &workingset); -+ -+ if (pgdat != folio_pgdat(folio)) -+ return; -+ -+ rcu_read_lock(); -+ -+ memcg = folio_memcg_rcu(folio); -+ if (memcg_id != mem_cgroup_id(memcg)) -+ goto unlock; -+ -+ lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ lrugen = &lruvec->lrugen; -+ -+ min_seq = READ_ONCE(lrugen->min_seq[type]); -+ if ((token >> LRU_REFS_WIDTH) != (min_seq & (EVICTION_MASK >> LRU_REFS_WIDTH))) -+ goto unlock; -+ -+ hist = lru_hist_from_seq(min_seq); -+ /* see the comment in folio_lru_refs() */ -+ refs = (token & (BIT(LRU_REFS_WIDTH) - 1)) + workingset; -+ tier = lru_tier_from_refs(refs); -+ -+ atomic_long_add(delta, &lrugen->refaulted[hist][type][tier]); -+ mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + type, delta); -+ -+ /* -+ * Count the following two cases as stalls: -+ * 1. For pages accessed through page tables, hotter pages pushed out -+ * hot pages which refaulted immediately. -+ * 2. For pages accessed multiple times through file descriptors, -+ * numbers of accesses might have been out of the range. -+ */ -+ if (lru_gen_in_fault() || refs == BIT(LRU_REFS_WIDTH)) { -+ folio_set_workingset(folio); -+ mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta); -+ } -+unlock: -+ rcu_read_unlock(); -+} -+ -+#else /* !CONFIG_LRU_GEN */ -+ -+static void *lru_gen_eviction(struct folio *folio) -+{ -+ return NULL; -+} -+ -+static void lru_gen_refault(struct folio *folio, void *shadow) -+{ -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - /** - * workingset_age_nonresident - age non-resident entries as LRU ages - * @lruvec: the lruvec that was aged -@@ -264,10 +360,14 @@ void *workingset_eviction(struct folio * - VM_BUG_ON_FOLIO(folio_ref_count(folio), folio); - VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio); - -+ if (lru_gen_enabled()) -+ return lru_gen_eviction(folio); -+ - lruvec = mem_cgroup_lruvec(target_memcg, pgdat); - /* XXX: target_memcg can be NULL, go through lruvec */ - memcgid = mem_cgroup_id(lruvec_memcg(lruvec)); - eviction = atomic_long_read(&lruvec->nonresident_age); -+ eviction >>= bucket_order; - workingset_age_nonresident(lruvec, folio_nr_pages(folio)); - return pack_shadow(memcgid, pgdat, eviction, - folio_test_workingset(folio)); -@@ -298,7 +398,13 @@ void workingset_refault(struct folio *fo - int memcgid; - long nr; - -+ if (lru_gen_enabled()) { -+ lru_gen_refault(folio, shadow); -+ return; -+ } -+ - unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset); -+ eviction <<= bucket_order; - - rcu_read_lock(); - /* diff --git a/target/linux/generic/backport-6.0/106-mm-multi-gen-LRU-exploit-locality-in-rmap.patch b/target/linux/generic/backport-6.0/106-mm-multi-gen-LRU-exploit-locality-in-rmap.patch deleted file mode 100644 index 729db5afa..000000000 --- a/target/linux/generic/backport-6.0/106-mm-multi-gen-LRU-exploit-locality-in-rmap.patch +++ /dev/null @@ -1,476 +0,0 @@ -From 93fa87bdef9e7fa9977355c4712c000f31639231 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Thu, 27 Jan 2022 20:43:22 -0700 -Subject: [PATCH 07/14] mm: multi-gen LRU: exploit locality in rmap -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Searching the rmap for PTEs mapping each page on an LRU list (to test -and clear the accessed bit) can be expensive because pages from -different VMAs (PA space) are not cache friendly to the rmap (VA -space). For workloads mostly using mapped pages, searching the rmap -can incur the highest CPU cost in the reclaim path. - -This patch exploits spatial locality to reduce the trips into the -rmap. When shrink_page_list() walks the rmap and finds a young PTE, a -new function lru_gen_look_around() scans at most BITS_PER_LONG-1 -adjacent PTEs. On finding another young PTE, it clears the accessed -bit and updates the gen counter of the page mapped by this PTE to -(max_seq%MAX_NR_GENS)+1. - -Server benchmark results: - Single workload: - fio (buffered I/O): no change - - Single workload: - memcached (anon): +[3, 5]% - Ops/sec KB/sec - patch1-6: 1106168.46 43025.04 - patch1-7: 1147696.57 44640.29 - - Configurations: - no change - -Client benchmark results: - kswapd profiles: - patch1-6 - 39.03% lzo1x_1_do_compress (real work) - 18.47% page_vma_mapped_walk (overhead) - 6.74% _raw_spin_unlock_irq - 3.97% do_raw_spin_lock - 2.49% ptep_clear_flush - 2.48% anon_vma_interval_tree_iter_first - 1.92% folio_referenced_one - 1.88% __zram_bvec_write - 1.48% memmove - 1.31% vma_interval_tree_iter_next - - patch1-7 - 48.16% lzo1x_1_do_compress (real work) - 8.20% page_vma_mapped_walk (overhead) - 7.06% _raw_spin_unlock_irq - 2.92% ptep_clear_flush - 2.53% __zram_bvec_write - 2.11% do_raw_spin_lock - 2.02% memmove - 1.93% lru_gen_look_around - 1.56% free_unref_page_list - 1.40% memset - - Configurations: - no change - -Signed-off-by: Yu Zhao -Acked-by: Barry Song -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I4b9ca0fd20f566ce554e703f14cee3fe0048c2fd ---- - include/linux/memcontrol.h | 31 +++++++ - include/linux/mm.h | 5 + - include/linux/mmzone.h | 6 ++ - mm/internal.h | 1 + - mm/memcontrol.c | 1 + - mm/rmap.c | 6 ++ - mm/swap.c | 4 +- - mm/vmscan.c | 184 +++++++++++++++++++++++++++++++++++++ - 8 files changed, 236 insertions(+), 2 deletions(-) - ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -444,6 +444,7 @@ static inline struct obj_cgroup *__folio - * - LRU isolation - * - lock_page_memcg() - * - exclusive reference -+ * - mem_cgroup_trylock_pages() - * - * For a kmem folio a caller should hold an rcu read lock to protect memcg - * associated with a kmem folio from being released. -@@ -505,6 +506,7 @@ static inline struct mem_cgroup *folio_m - * - LRU isolation - * - lock_page_memcg() - * - exclusive reference -+ * - mem_cgroup_trylock_pages() - * - * For a kmem page a caller should hold an rcu read lock to protect memcg - * associated with a kmem page from being released. -@@ -959,6 +961,23 @@ void unlock_page_memcg(struct page *page - - void __mod_memcg_state(struct mem_cgroup *memcg, int idx, int val); - -+/* try to stablize folio_memcg() for all the pages in a memcg */ -+static inline bool mem_cgroup_trylock_pages(struct mem_cgroup *memcg) -+{ -+ rcu_read_lock(); -+ -+ if (mem_cgroup_disabled() || !atomic_read(&memcg->moving_account)) -+ return true; -+ -+ rcu_read_unlock(); -+ return false; -+} -+ -+static inline void mem_cgroup_unlock_pages(void) -+{ -+ rcu_read_unlock(); -+} -+ - /* idx can be of type enum memcg_stat_item or node_stat_item */ - static inline void mod_memcg_state(struct mem_cgroup *memcg, - int idx, int val) -@@ -1433,6 +1452,18 @@ static inline void folio_memcg_unlock(st - { - } - -+static inline bool mem_cgroup_trylock_pages(struct mem_cgroup *memcg) -+{ -+ /* to match folio_memcg_rcu() */ -+ rcu_read_lock(); -+ return true; -+} -+ -+static inline void mem_cgroup_unlock_pages(void) -+{ -+ rcu_read_unlock(); -+} -+ - static inline void mem_cgroup_handle_over_high(void) - { - } ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1465,6 +1465,11 @@ static inline unsigned long folio_pfn(st - return page_to_pfn(&folio->page); - } - -+static inline struct folio *pfn_folio(unsigned long pfn) -+{ -+ return page_folio(pfn_to_page(pfn)); -+} -+ - static inline atomic_t *folio_pincount_ptr(struct folio *folio) - { - return &folio_page(folio, 1)->compound_pincount; ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -372,6 +372,7 @@ enum lruvec_flags { - #ifndef __GENERATING_BOUNDS_H - - struct lruvec; -+struct page_vma_mapped_walk; - - #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF) - #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF) -@@ -427,6 +428,7 @@ struct lru_gen_struct { - }; - - void lru_gen_init_lruvec(struct lruvec *lruvec); -+void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); - - #ifdef CONFIG_MEMCG - void lru_gen_init_memcg(struct mem_cgroup *memcg); -@@ -439,6 +441,10 @@ static inline void lru_gen_init_lruvec(s - { - } - -+static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) -+{ -+} -+ - #ifdef CONFIG_MEMCG - static inline void lru_gen_init_memcg(struct mem_cgroup *memcg) - { ---- a/mm/internal.h -+++ b/mm/internal.h -@@ -83,6 +83,7 @@ vm_fault_t do_swap_page(struct vm_fault - void folio_rotate_reclaimable(struct folio *folio); - bool __folio_end_writeback(struct folio *folio); - void deactivate_file_folio(struct folio *folio); -+void folio_activate(struct folio *folio); - - void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, - unsigned long floor, unsigned long ceiling); ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -2789,6 +2789,7 @@ static void commit_charge(struct folio * - * - LRU isolation - * - lock_page_memcg() - * - exclusive reference -+ * - mem_cgroup_trylock_pages() - */ - folio->memcg_data = (unsigned long)memcg; - } ---- a/mm/rmap.c -+++ b/mm/rmap.c -@@ -833,6 +833,12 @@ static bool folio_referenced_one(struct - } - - if (pvmw.pte) { -+ if (lru_gen_enabled() && pte_young(*pvmw.pte) && -+ !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) { -+ lru_gen_look_around(&pvmw); -+ referenced++; -+ } -+ - if (ptep_clear_flush_young_notify(vma, address, - pvmw.pte)) { - /* ---- a/mm/swap.c -+++ b/mm/swap.c -@@ -366,7 +366,7 @@ static void folio_activate_drain(int cpu - folio_batch_move_lru(fbatch, folio_activate_fn); - } - --static void folio_activate(struct folio *folio) -+void folio_activate(struct folio *folio) - { - if (folio_test_lru(folio) && !folio_test_active(folio) && - !folio_test_unevictable(folio)) { -@@ -385,7 +385,7 @@ static inline void folio_activate_drain( - { - } - --static void folio_activate(struct folio *folio) -+void folio_activate(struct folio *folio) - { - struct lruvec *lruvec; - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -1635,6 +1635,11 @@ retry: - if (!sc->may_unmap && folio_mapped(folio)) - goto keep_locked; - -+ /* folio_update_gen() tried to promote this page? */ -+ if (lru_gen_enabled() && !ignore_references && -+ folio_mapped(folio) && folio_test_referenced(folio)) -+ goto keep_locked; -+ - /* - * The number of dirty pages determines if a node is marked - * reclaim_congested. kswapd will stall and start writing -@@ -3219,6 +3224,29 @@ static bool positive_ctrl_err(struct ctr - * the aging - ******************************************************************************/ - -+/* promote pages accessed through page tables */ -+static int folio_update_gen(struct folio *folio, int gen) -+{ -+ unsigned long new_flags, old_flags = READ_ONCE(folio->flags); -+ -+ VM_WARN_ON_ONCE(gen >= MAX_NR_GENS); -+ VM_WARN_ON_ONCE(!rcu_read_lock_held()); -+ -+ do { -+ /* lru_gen_del_folio() has isolated this page? */ -+ if (!(old_flags & LRU_GEN_MASK)) { -+ /* for shrink_page_list() */ -+ new_flags = old_flags | BIT(PG_referenced); -+ continue; -+ } -+ -+ new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS); -+ new_flags |= (gen + 1UL) << LRU_GEN_PGOFF; -+ } while (!try_cmpxchg(&folio->flags, &old_flags, new_flags)); -+ -+ return ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+} -+ - /* protect pages accessed multiple times through file descriptors */ - static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclaiming) - { -@@ -3230,6 +3258,11 @@ static int folio_inc_gen(struct lruvec * - VM_WARN_ON_ONCE_FOLIO(!(old_flags & LRU_GEN_MASK), folio); - - do { -+ new_gen = ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+ /* folio_update_gen() has promoted this page? */ -+ if (new_gen >= 0 && new_gen != old_gen) -+ return new_gen; -+ - new_gen = (old_gen + 1) % MAX_NR_GENS; - - new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS); -@@ -3244,6 +3277,43 @@ static int folio_inc_gen(struct lruvec * - return new_gen; - } - -+static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr) -+{ -+ unsigned long pfn = pte_pfn(pte); -+ -+ VM_WARN_ON_ONCE(addr < vma->vm_start || addr >= vma->vm_end); -+ -+ if (!pte_present(pte) || is_zero_pfn(pfn)) -+ return -1; -+ -+ if (WARN_ON_ONCE(pte_devmap(pte) || pte_special(pte))) -+ return -1; -+ -+ if (WARN_ON_ONCE(!pfn_valid(pfn))) -+ return -1; -+ -+ return pfn; -+} -+ -+static struct folio *get_pfn_folio(unsigned long pfn, struct mem_cgroup *memcg, -+ struct pglist_data *pgdat) -+{ -+ struct folio *folio; -+ -+ /* try to avoid unnecessary memory loads */ -+ if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) -+ return NULL; -+ -+ folio = pfn_folio(pfn); -+ if (folio_nid(folio) != pgdat->node_id) -+ return NULL; -+ -+ if (folio_memcg_rcu(folio) != memcg) -+ return NULL; -+ -+ return folio; -+} -+ - static void inc_min_seq(struct lruvec *lruvec, int type) - { - struct lru_gen_struct *lrugen = &lruvec->lrugen; -@@ -3443,6 +3513,114 @@ static void lru_gen_age_node(struct pgli - } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); - } - -+/* -+ * This function exploits spatial locality when shrink_page_list() walks the -+ * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. -+ */ -+void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) -+{ -+ int i; -+ pte_t *pte; -+ unsigned long start; -+ unsigned long end; -+ unsigned long addr; -+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; -+ struct folio *folio = pfn_folio(pvmw->pfn); -+ struct mem_cgroup *memcg = folio_memcg(folio); -+ struct pglist_data *pgdat = folio_pgdat(folio); -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ DEFINE_MAX_SEQ(lruvec); -+ int old_gen, new_gen = lru_gen_from_seq(max_seq); -+ -+ lockdep_assert_held(pvmw->ptl); -+ VM_WARN_ON_ONCE_FOLIO(folio_test_lru(folio), folio); -+ -+ if (spin_is_contended(pvmw->ptl)) -+ return; -+ -+ start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start); -+ end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1; -+ -+ if (end - start > MIN_LRU_BATCH * PAGE_SIZE) { -+ if (pvmw->address - start < MIN_LRU_BATCH * PAGE_SIZE / 2) -+ end = start + MIN_LRU_BATCH * PAGE_SIZE; -+ else if (end - pvmw->address < MIN_LRU_BATCH * PAGE_SIZE / 2) -+ start = end - MIN_LRU_BATCH * PAGE_SIZE; -+ else { -+ start = pvmw->address - MIN_LRU_BATCH * PAGE_SIZE / 2; -+ end = pvmw->address + MIN_LRU_BATCH * PAGE_SIZE / 2; -+ } -+ } -+ -+ pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE; -+ -+ rcu_read_lock(); -+ arch_enter_lazy_mmu_mode(); -+ -+ for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) { -+ unsigned long pfn; -+ -+ pfn = get_pte_pfn(pte[i], pvmw->vma, addr); -+ if (pfn == -1) -+ continue; -+ -+ if (!pte_young(pte[i])) -+ continue; -+ -+ folio = get_pfn_folio(pfn, memcg, pgdat); -+ if (!folio) -+ continue; -+ -+ if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i)) -+ VM_WARN_ON_ONCE(true); -+ -+ if (pte_dirty(pte[i]) && !folio_test_dirty(folio) && -+ !(folio_test_anon(folio) && folio_test_swapbacked(folio) && -+ !folio_test_swapcache(folio))) -+ folio_mark_dirty(folio); -+ -+ old_gen = folio_lru_gen(folio); -+ if (old_gen < 0) -+ folio_set_referenced(folio); -+ else if (old_gen != new_gen) -+ __set_bit(i, bitmap); -+ } -+ -+ arch_leave_lazy_mmu_mode(); -+ rcu_read_unlock(); -+ -+ if (bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) { -+ for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { -+ folio = pfn_folio(pte_pfn(pte[i])); -+ folio_activate(folio); -+ } -+ return; -+ } -+ -+ /* folio_update_gen() requires stable folio_memcg() */ -+ if (!mem_cgroup_trylock_pages(memcg)) -+ return; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq); -+ -+ for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { -+ folio = pfn_folio(pte_pfn(pte[i])); -+ if (folio_memcg_rcu(folio) != memcg) -+ continue; -+ -+ old_gen = folio_update_gen(folio, new_gen); -+ if (old_gen < 0 || old_gen == new_gen) -+ continue; -+ -+ lru_gen_update_size(lruvec, folio, old_gen, new_gen); -+ } -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ -+ mem_cgroup_unlock_pages(); -+} -+ - /****************************************************************************** - * the eviction - ******************************************************************************/ -@@ -3479,6 +3657,12 @@ static bool sort_folio(struct lruvec *lr - return true; - } - -+ /* promoted */ -+ if (gen != lru_gen_from_seq(lrugen->min_seq[type])) { -+ list_move(&folio->lru, &lrugen->lists[gen][type][zone]); -+ return true; -+ } -+ - /* protected */ - if (tier > tier_idx) { - int hist = lru_hist_from_seq(lrugen->min_seq[type]); diff --git a/target/linux/generic/backport-6.0/107-mm-multi-gen-LRU-support-page-table-walks.patch b/target/linux/generic/backport-6.0/107-mm-multi-gen-LRU-support-page-table-walks.patch deleted file mode 100644 index de8109ca5..000000000 --- a/target/linux/generic/backport-6.0/107-mm-multi-gen-LRU-support-page-table-walks.patch +++ /dev/null @@ -1,1662 +0,0 @@ -From 1901916ee0f75841efdee055df64fa86d0512d53 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Thu, 27 Jan 2022 19:23:01 -0700 -Subject: [PATCH 08/14] mm: multi-gen LRU: support page table walks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -To further exploit spatial locality, the aging prefers to walk page -tables to search for young PTEs and promote hot pages. A kill switch -will be added in the next patch to disable this behavior. When -disabled, the aging relies on the rmap only. - -NB: this behavior has nothing similar with the page table scanning in -the 2.4 kernel [1], which searches page tables for old PTEs, adds cold -pages to swapcache and unmaps them. - -To avoid confusion, the term "iteration" specifically means the -traversal of an entire mm_struct list; the term "walk" will be applied -to page tables and the rmap, as usual. - -An mm_struct list is maintained for each memcg, and an mm_struct -follows its owner task to the new memcg when this task is migrated. -Given an lruvec, the aging iterates lruvec_memcg()->mm_list and calls -walk_page_range() with each mm_struct on this list to promote hot -pages before it increments max_seq. - -When multiple page table walkers iterate the same list, each of them -gets a unique mm_struct; therefore they can run concurrently. Page -table walkers ignore any misplaced pages, e.g., if an mm_struct was -migrated, pages it left in the previous memcg will not be promoted -when its current memcg is under reclaim. Similarly, page table walkers -will not promote pages from nodes other than the one under reclaim. - -This patch uses the following optimizations when walking page tables: -1. It tracks the usage of mm_struct's between context switches so that - page table walkers can skip processes that have been sleeping since - the last iteration. -2. It uses generational Bloom filters to record populated branches so - that page table walkers can reduce their search space based on the - query results, e.g., to skip page tables containing mostly holes or - misplaced pages. -3. It takes advantage of the accessed bit in non-leaf PMD entries when - CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y. -4. It does not zigzag between a PGD table and the same PMD table - spanning multiple VMAs. IOW, it finishes all the VMAs within the - range of the same PMD table before it returns to a PGD table. This - improves the cache performance for workloads that have large - numbers of tiny VMAs [2], especially when CONFIG_PGTABLE_LEVELS=5. - -Server benchmark results: - Single workload: - fio (buffered I/O): no change - - Single workload: - memcached (anon): +[8, 10]% - Ops/sec KB/sec - patch1-7: 1147696.57 44640.29 - patch1-8: 1245274.91 48435.66 - - Configurations: - no change - -Client benchmark results: - kswapd profiles: - patch1-7 - 48.16% lzo1x_1_do_compress (real work) - 8.20% page_vma_mapped_walk (overhead) - 7.06% _raw_spin_unlock_irq - 2.92% ptep_clear_flush - 2.53% __zram_bvec_write - 2.11% do_raw_spin_lock - 2.02% memmove - 1.93% lru_gen_look_around - 1.56% free_unref_page_list - 1.40% memset - - patch1-8 - 49.44% lzo1x_1_do_compress (real work) - 6.19% page_vma_mapped_walk (overhead) - 5.97% _raw_spin_unlock_irq - 3.13% get_pfn_folio - 2.85% ptep_clear_flush - 2.42% __zram_bvec_write - 2.08% do_raw_spin_lock - 1.92% memmove - 1.44% alloc_zspage - 1.36% memset - - Configurations: - no change - -Thanks to the following developers for their efforts [3]. - kernel test robot - -[1] https://lwn.net/Articles/23732/ -[2] https://llvm.org/docs/ScudoHardenedAllocator.html -[3] https://lore.kernel.org/r/202204160827.ekEARWQo-lkp@intel.com/ - -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I1065451af34154306418510c19e03ea798dc13af ---- - fs/exec.c | 2 + - include/linux/memcontrol.h | 5 + - include/linux/mm_types.h | 76 +++ - include/linux/mmzone.h | 56 +- - include/linux/swap.h | 4 + - kernel/exit.c | 1 + - kernel/fork.c | 9 + - kernel/sched/core.c | 1 + - mm/memcontrol.c | 25 + - mm/vmscan.c | 1008 +++++++++++++++++++++++++++++++++++- - 10 files changed, 1170 insertions(+), 17 deletions(-) - ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1011,6 +1011,7 @@ static int exec_mmap(struct mm_struct *m - active_mm = tsk->active_mm; - tsk->active_mm = mm; - tsk->mm = mm; -+ lru_gen_add_mm(mm); - /* - * This prevents preemption while active_mm is being loaded and - * it and mm are being updated, which could cause problems for -@@ -1026,6 +1027,7 @@ static int exec_mmap(struct mm_struct *m - tsk->mm->vmacache_seqnum = 0; - vmacache_flush(tsk); - task_unlock(tsk); -+ lru_gen_use_mm(mm); - if (old_mm) { - mmap_read_unlock(old_mm); - BUG_ON(active_mm != old_mm); ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -350,6 +350,11 @@ struct mem_cgroup { - struct deferred_split deferred_split_queue; - #endif - -+#ifdef CONFIG_LRU_GEN -+ /* per-memcg mm_struct list */ -+ struct lru_gen_mm_list mm_list; -+#endif -+ - struct mem_cgroup_per_node *nodeinfo[]; - }; - ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -672,6 +672,22 @@ struct mm_struct { - */ - unsigned long ksm_merging_pages; - #endif -+#ifdef CONFIG_LRU_GEN -+ struct { -+ /* this mm_struct is on lru_gen_mm_list */ -+ struct list_head list; -+ /* -+ * Set when switching to this mm_struct, as a hint of -+ * whether it has been used since the last time per-node -+ * page table walkers cleared the corresponding bits. -+ */ -+ unsigned long bitmap; -+#ifdef CONFIG_MEMCG -+ /* points to the memcg of "owner" above */ -+ struct mem_cgroup *memcg; -+#endif -+ } lru_gen; -+#endif /* CONFIG_LRU_GEN */ - } __randomize_layout; - - /* -@@ -698,6 +714,66 @@ static inline cpumask_t *mm_cpumask(stru - return (struct cpumask *)&mm->cpu_bitmap; - } - -+#ifdef CONFIG_LRU_GEN -+ -+struct lru_gen_mm_list { -+ /* mm_struct list for page table walkers */ -+ struct list_head fifo; -+ /* protects the list above */ -+ spinlock_t lock; -+}; -+ -+void lru_gen_add_mm(struct mm_struct *mm); -+void lru_gen_del_mm(struct mm_struct *mm); -+#ifdef CONFIG_MEMCG -+void lru_gen_migrate_mm(struct mm_struct *mm); -+#endif -+ -+static inline void lru_gen_init_mm(struct mm_struct *mm) -+{ -+ INIT_LIST_HEAD(&mm->lru_gen.list); -+ mm->lru_gen.bitmap = 0; -+#ifdef CONFIG_MEMCG -+ mm->lru_gen.memcg = NULL; -+#endif -+} -+ -+static inline void lru_gen_use_mm(struct mm_struct *mm) -+{ -+ /* -+ * When the bitmap is set, page reclaim knows this mm_struct has been -+ * used since the last time it cleared the bitmap. So it might be worth -+ * walking the page tables of this mm_struct to clear the accessed bit. -+ */ -+ WRITE_ONCE(mm->lru_gen.bitmap, -1); -+} -+ -+#else /* !CONFIG_LRU_GEN */ -+ -+static inline void lru_gen_add_mm(struct mm_struct *mm) -+{ -+} -+ -+static inline void lru_gen_del_mm(struct mm_struct *mm) -+{ -+} -+ -+#ifdef CONFIG_MEMCG -+static inline void lru_gen_migrate_mm(struct mm_struct *mm) -+{ -+} -+#endif -+ -+static inline void lru_gen_init_mm(struct mm_struct *mm) -+{ -+} -+ -+static inline void lru_gen_use_mm(struct mm_struct *mm) -+{ -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - struct mmu_gather; - extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm); - extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm); ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -405,7 +405,7 @@ enum { - * min_seq behind. - * - * The number of pages in each generation is eventually consistent and therefore -- * can be transiently negative. -+ * can be transiently negative when reset_batch_size() is pending. - */ - struct lru_gen_struct { - /* the aging increments the youngest generation number */ -@@ -427,6 +427,53 @@ struct lru_gen_struct { - atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; - }; - -+enum { -+ MM_LEAF_TOTAL, /* total leaf entries */ -+ MM_LEAF_OLD, /* old leaf entries */ -+ MM_LEAF_YOUNG, /* young leaf entries */ -+ MM_NONLEAF_TOTAL, /* total non-leaf entries */ -+ MM_NONLEAF_FOUND, /* non-leaf entries found in Bloom filters */ -+ MM_NONLEAF_ADDED, /* non-leaf entries added to Bloom filters */ -+ NR_MM_STATS -+}; -+ -+/* double-buffering Bloom filters */ -+#define NR_BLOOM_FILTERS 2 -+ -+struct lru_gen_mm_state { -+ /* set to max_seq after each iteration */ -+ unsigned long seq; -+ /* where the current iteration continues (inclusive) */ -+ struct list_head *head; -+ /* where the last iteration ended (exclusive) */ -+ struct list_head *tail; -+ /* to wait for the last page table walker to finish */ -+ struct wait_queue_head wait; -+ /* Bloom filters flip after each iteration */ -+ unsigned long *filters[NR_BLOOM_FILTERS]; -+ /* the mm stats for debugging */ -+ unsigned long stats[NR_HIST_GENS][NR_MM_STATS]; -+ /* the number of concurrent page table walkers */ -+ int nr_walkers; -+}; -+ -+struct lru_gen_mm_walk { -+ /* the lruvec under reclaim */ -+ struct lruvec *lruvec; -+ /* unstable max_seq from lru_gen_struct */ -+ unsigned long max_seq; -+ /* the next address within an mm to scan */ -+ unsigned long next_addr; -+ /* to batch promoted pages */ -+ int nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ /* to batch the mm stats */ -+ int mm_stats[NR_MM_STATS]; -+ /* total batched items */ -+ int batched; -+ bool can_swap; -+ bool force_scan; -+}; -+ - void lru_gen_init_lruvec(struct lruvec *lruvec); - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); - -@@ -477,6 +524,8 @@ struct lruvec { - #ifdef CONFIG_LRU_GEN - /* evictable pages divided into generations */ - struct lru_gen_struct lrugen; -+ /* to concurrently iterate lru_gen_mm_list */ -+ struct lru_gen_mm_state mm_state; - #endif - #ifdef CONFIG_MEMCG - struct pglist_data *pgdat; -@@ -1156,6 +1205,11 @@ typedef struct pglist_data { - - unsigned long flags; - -+#ifdef CONFIG_LRU_GEN -+ /* kswap mm walk data */ -+ struct lru_gen_mm_walk mm_walk; -+#endif -+ - ZONE_PADDING(_pad2_) - - /* Per-node vmstats */ ---- a/include/linux/swap.h -+++ b/include/linux/swap.h -@@ -162,6 +162,10 @@ union swap_header { - */ - struct reclaim_state { - unsigned long reclaimed_slab; -+#ifdef CONFIG_LRU_GEN -+ /* per-thread mm walk data */ -+ struct lru_gen_mm_walk *mm_walk; -+#endif - }; - - #ifdef __KERNEL__ ---- a/kernel/exit.c -+++ b/kernel/exit.c -@@ -466,6 +466,7 @@ assign_new_owner: - goto retry; - } - WRITE_ONCE(mm->owner, c); -+ lru_gen_migrate_mm(mm); - task_unlock(c); - put_task_struct(c); - } ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -1152,6 +1152,7 @@ static struct mm_struct *mm_init(struct - goto fail_nocontext; - - mm->user_ns = get_user_ns(user_ns); -+ lru_gen_init_mm(mm); - return mm; - - fail_nocontext: -@@ -1194,6 +1195,7 @@ static inline void __mmput(struct mm_str - } - if (mm->binfmt) - module_put(mm->binfmt->module); -+ lru_gen_del_mm(mm); - mmdrop(mm); - } - -@@ -2692,6 +2694,13 @@ pid_t kernel_clone(struct kernel_clone_a - get_task_struct(p); - } - -+ if (IS_ENABLED(CONFIG_LRU_GEN) && !(clone_flags & CLONE_VM)) { -+ /* lock the task to synchronize with memcg migration */ -+ task_lock(p); -+ lru_gen_add_mm(p->mm); -+ task_unlock(p); -+ } -+ - wake_up_new_task(p); - - /* forking complete and child started to run, tell ptracer */ ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -5166,6 +5166,7 @@ context_switch(struct rq *rq, struct tas - * finish_task_switch()'s mmdrop(). - */ - switch_mm_irqs_off(prev->active_mm, next->mm, next); -+ lru_gen_use_mm(next->mm); - - if (!prev->mm) { // from kernel - /* will mmdrop() in finish_task_switch(). */ ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -6199,6 +6199,30 @@ static void mem_cgroup_move_task(void) - } - #endif - -+#ifdef CONFIG_LRU_GEN -+static void mem_cgroup_attach(struct cgroup_taskset *tset) -+{ -+ struct task_struct *task; -+ struct cgroup_subsys_state *css; -+ -+ /* find the first leader if there is any */ -+ cgroup_taskset_for_each_leader(task, css, tset) -+ break; -+ -+ if (!task) -+ return; -+ -+ task_lock(task); -+ if (task->mm && READ_ONCE(task->mm->owner) == task) -+ lru_gen_migrate_mm(task->mm); -+ task_unlock(task); -+} -+#else -+static void mem_cgroup_attach(struct cgroup_taskset *tset) -+{ -+} -+#endif /* CONFIG_LRU_GEN */ -+ - static int seq_puts_memcg_tunable(struct seq_file *m, unsigned long value) - { - if (value == PAGE_COUNTER_MAX) -@@ -6604,6 +6628,7 @@ struct cgroup_subsys memory_cgrp_subsys - .css_reset = mem_cgroup_css_reset, - .css_rstat_flush = mem_cgroup_css_rstat_flush, - .can_attach = mem_cgroup_can_attach, -+ .attach = mem_cgroup_attach, - .cancel_attach = mem_cgroup_cancel_attach, - .post_attach = mem_cgroup_move_task, - .dfl_cftypes = memory_files, ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -49,6 +49,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -3082,7 +3084,7 @@ static bool can_age_anon_pages(struct pg - for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ - for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) - --static struct lruvec __maybe_unused *get_lruvec(struct mem_cgroup *memcg, int nid) -+static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid) - { - struct pglist_data *pgdat = NODE_DATA(nid); - -@@ -3128,6 +3130,371 @@ static bool __maybe_unused seq_is_valid( - } - - /****************************************************************************** -+ * mm_struct list -+ ******************************************************************************/ -+ -+static struct lru_gen_mm_list *get_mm_list(struct mem_cgroup *memcg) -+{ -+ static struct lru_gen_mm_list mm_list = { -+ .fifo = LIST_HEAD_INIT(mm_list.fifo), -+ .lock = __SPIN_LOCK_UNLOCKED(mm_list.lock), -+ }; -+ -+#ifdef CONFIG_MEMCG -+ if (memcg) -+ return &memcg->mm_list; -+#endif -+ VM_WARN_ON_ONCE(!mem_cgroup_disabled()); -+ -+ return &mm_list; -+} -+ -+void lru_gen_add_mm(struct mm_struct *mm) -+{ -+ int nid; -+ struct mem_cgroup *memcg = get_mem_cgroup_from_mm(mm); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ -+ VM_WARN_ON_ONCE(!list_empty(&mm->lru_gen.list)); -+#ifdef CONFIG_MEMCG -+ VM_WARN_ON_ONCE(mm->lru_gen.memcg); -+ mm->lru_gen.memcg = memcg; -+#endif -+ spin_lock(&mm_list->lock); -+ -+ for_each_node_state(nid, N_MEMORY) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ if (!lruvec) -+ continue; -+ -+ /* the first addition since the last iteration */ -+ if (lruvec->mm_state.tail == &mm_list->fifo) -+ lruvec->mm_state.tail = &mm->lru_gen.list; -+ } -+ -+ list_add_tail(&mm->lru_gen.list, &mm_list->fifo); -+ -+ spin_unlock(&mm_list->lock); -+} -+ -+void lru_gen_del_mm(struct mm_struct *mm) -+{ -+ int nid; -+ struct lru_gen_mm_list *mm_list; -+ struct mem_cgroup *memcg = NULL; -+ -+ if (list_empty(&mm->lru_gen.list)) -+ return; -+ -+#ifdef CONFIG_MEMCG -+ memcg = mm->lru_gen.memcg; -+#endif -+ mm_list = get_mm_list(memcg); -+ -+ spin_lock(&mm_list->lock); -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ if (!lruvec) -+ continue; -+ -+ /* where the last iteration ended (exclusive) */ -+ if (lruvec->mm_state.tail == &mm->lru_gen.list) -+ lruvec->mm_state.tail = lruvec->mm_state.tail->next; -+ -+ /* where the current iteration continues (inclusive) */ -+ if (lruvec->mm_state.head != &mm->lru_gen.list) -+ continue; -+ -+ lruvec->mm_state.head = lruvec->mm_state.head->next; -+ /* the deletion ends the current iteration */ -+ if (lruvec->mm_state.head == &mm_list->fifo) -+ WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1); -+ } -+ -+ list_del_init(&mm->lru_gen.list); -+ -+ spin_unlock(&mm_list->lock); -+ -+#ifdef CONFIG_MEMCG -+ mem_cgroup_put(mm->lru_gen.memcg); -+ mm->lru_gen.memcg = NULL; -+#endif -+} -+ -+#ifdef CONFIG_MEMCG -+void lru_gen_migrate_mm(struct mm_struct *mm) -+{ -+ struct mem_cgroup *memcg; -+ struct task_struct *task = rcu_dereference_protected(mm->owner, true); -+ -+ VM_WARN_ON_ONCE(task->mm != mm); -+ lockdep_assert_held(&task->alloc_lock); -+ -+ /* for mm_update_next_owner() */ -+ if (mem_cgroup_disabled()) -+ return; -+ -+ rcu_read_lock(); -+ memcg = mem_cgroup_from_task(task); -+ rcu_read_unlock(); -+ if (memcg == mm->lru_gen.memcg) -+ return; -+ -+ VM_WARN_ON_ONCE(!mm->lru_gen.memcg); -+ VM_WARN_ON_ONCE(list_empty(&mm->lru_gen.list)); -+ -+ lru_gen_del_mm(mm); -+ lru_gen_add_mm(mm); -+} -+#endif -+ -+/* -+ * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when -+ * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of -+ * bits in a bitmap, k is the number of hash functions and n is the number of -+ * inserted items. -+ * -+ * Page table walkers use one of the two filters to reduce their search space. -+ * To get rid of non-leaf entries that no longer have enough leaf entries, the -+ * aging uses the double-buffering technique to flip to the other filter each -+ * time it produces a new generation. For non-leaf entries that have enough -+ * leaf entries, the aging carries them over to the next generation in -+ * walk_pmd_range(); the eviction also report them when walking the rmap -+ * in lru_gen_look_around(). -+ * -+ * For future optimizations: -+ * 1. It's not necessary to keep both filters all the time. The spare one can be -+ * freed after the RCU grace period and reallocated if needed again. -+ * 2. And when reallocating, it's worth scaling its size according to the number -+ * of inserted entries in the other filter, to reduce the memory overhead on -+ * small systems and false positives on large systems. -+ * 3. Jenkins' hash function is an alternative to Knuth's. -+ */ -+#define BLOOM_FILTER_SHIFT 15 -+ -+static inline int filter_gen_from_seq(unsigned long seq) -+{ -+ return seq % NR_BLOOM_FILTERS; -+} -+ -+static void get_item_key(void *item, int *key) -+{ -+ u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2); -+ -+ BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32)); -+ -+ key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1); -+ key[1] = hash >> BLOOM_FILTER_SHIFT; -+} -+ -+static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq) -+{ -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = lruvec->mm_state.filters[gen]; -+ if (filter) { -+ bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT)); -+ return; -+ } -+ -+ filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT), -+ __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); -+ WRITE_ONCE(lruvec->mm_state.filters[gen], filter); -+} -+ -+static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item) -+{ -+ int key[2]; -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = READ_ONCE(lruvec->mm_state.filters[gen]); -+ if (!filter) -+ return; -+ -+ get_item_key(item, key); -+ -+ if (!test_bit(key[0], filter)) -+ set_bit(key[0], filter); -+ if (!test_bit(key[1], filter)) -+ set_bit(key[1], filter); -+} -+ -+static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item) -+{ -+ int key[2]; -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = READ_ONCE(lruvec->mm_state.filters[gen]); -+ if (!filter) -+ return true; -+ -+ get_item_key(item, key); -+ -+ return test_bit(key[0], filter) && test_bit(key[1], filter); -+} -+ -+static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last) -+{ -+ int i; -+ int hist; -+ -+ lockdep_assert_held(&get_mm_list(lruvec_memcg(lruvec))->lock); -+ -+ if (walk) { -+ hist = lru_hist_from_seq(walk->max_seq); -+ -+ for (i = 0; i < NR_MM_STATS; i++) { -+ WRITE_ONCE(lruvec->mm_state.stats[hist][i], -+ lruvec->mm_state.stats[hist][i] + walk->mm_stats[i]); -+ walk->mm_stats[i] = 0; -+ } -+ } -+ -+ if (NR_HIST_GENS > 1 && last) { -+ hist = lru_hist_from_seq(lruvec->mm_state.seq + 1); -+ -+ for (i = 0; i < NR_MM_STATS; i++) -+ WRITE_ONCE(lruvec->mm_state.stats[hist][i], 0); -+ } -+} -+ -+static bool should_skip_mm(struct mm_struct *mm, struct lru_gen_mm_walk *walk) -+{ -+ int type; -+ unsigned long size = 0; -+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); -+ int key = pgdat->node_id % BITS_PER_TYPE(mm->lru_gen.bitmap); -+ -+ if (!walk->force_scan && !test_bit(key, &mm->lru_gen.bitmap)) -+ return true; -+ -+ clear_bit(key, &mm->lru_gen.bitmap); -+ -+ for (type = !walk->can_swap; type < ANON_AND_FILE; type++) { -+ size += type ? get_mm_counter(mm, MM_FILEPAGES) : -+ get_mm_counter(mm, MM_ANONPAGES) + -+ get_mm_counter(mm, MM_SHMEMPAGES); -+ } -+ -+ if (size < MIN_LRU_BATCH) -+ return true; -+ -+ return !mmget_not_zero(mm); -+} -+ -+static bool iterate_mm_list(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, -+ struct mm_struct **iter) -+{ -+ bool first = false; -+ bool last = true; -+ struct mm_struct *mm = NULL; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ struct lru_gen_mm_state *mm_state = &lruvec->mm_state; -+ -+ /* -+ * There are four interesting cases for this page table walker: -+ * 1. It tries to start a new iteration of mm_list with a stale max_seq; -+ * there is nothing left to do. -+ * 2. It's the first of the current generation, and it needs to reset -+ * the Bloom filter for the next generation. -+ * 3. It reaches the end of mm_list, and it needs to increment -+ * mm_state->seq; the iteration is done. -+ * 4. It's the last of the current generation, and it needs to reset the -+ * mm stats counters for the next generation. -+ */ -+ spin_lock(&mm_list->lock); -+ -+ VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq); -+ VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq); -+ VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers); -+ -+ if (walk->max_seq <= mm_state->seq) { -+ if (!*iter) -+ last = false; -+ goto done; -+ } -+ -+ if (!mm_state->nr_walkers) { -+ VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); -+ -+ mm_state->head = mm_list->fifo.next; -+ first = true; -+ } -+ -+ while (!mm && mm_state->head != &mm_list->fifo) { -+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list); -+ -+ mm_state->head = mm_state->head->next; -+ -+ /* force scan for those added after the last iteration */ -+ if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) { -+ mm_state->tail = mm_state->head; -+ walk->force_scan = true; -+ } -+ -+ if (should_skip_mm(mm, walk)) -+ mm = NULL; -+ } -+ -+ if (mm_state->head == &mm_list->fifo) -+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1); -+done: -+ if (*iter && !mm) -+ mm_state->nr_walkers--; -+ if (!*iter && mm) -+ mm_state->nr_walkers++; -+ -+ if (mm_state->nr_walkers) -+ last = false; -+ -+ if (*iter || last) -+ reset_mm_stats(lruvec, walk, last); -+ -+ spin_unlock(&mm_list->lock); -+ -+ if (mm && first) -+ reset_bloom_filter(lruvec, walk->max_seq + 1); -+ -+ if (*iter) -+ mmput_async(*iter); -+ -+ *iter = mm; -+ -+ return last; -+} -+ -+static bool iterate_mm_list_nowalk(struct lruvec *lruvec, unsigned long max_seq) -+{ -+ bool success = false; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ struct lru_gen_mm_state *mm_state = &lruvec->mm_state; -+ -+ spin_lock(&mm_list->lock); -+ -+ VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq); -+ -+ if (max_seq > mm_state->seq && !mm_state->nr_walkers) { -+ VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); -+ -+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1); -+ reset_mm_stats(lruvec, NULL, true); -+ success = true; -+ } -+ -+ spin_unlock(&mm_list->lock); -+ -+ return success; -+} -+ -+/****************************************************************************** - * refault feedback loop - ******************************************************************************/ - -@@ -3277,6 +3644,118 @@ static int folio_inc_gen(struct lruvec * - return new_gen; - } - -+static void update_batch_size(struct lru_gen_mm_walk *walk, struct folio *folio, -+ int old_gen, int new_gen) -+{ -+ int type = folio_is_file_lru(folio); -+ int zone = folio_zonenum(folio); -+ int delta = folio_nr_pages(folio); -+ -+ VM_WARN_ON_ONCE(old_gen >= MAX_NR_GENS); -+ VM_WARN_ON_ONCE(new_gen >= MAX_NR_GENS); -+ -+ walk->batched++; -+ -+ walk->nr_pages[old_gen][type][zone] -= delta; -+ walk->nr_pages[new_gen][type][zone] += delta; -+} -+ -+static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk) -+{ -+ int gen, type, zone; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ walk->batched = 0; -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ enum lru_list lru = type * LRU_INACTIVE_FILE; -+ int delta = walk->nr_pages[gen][type][zone]; -+ -+ if (!delta) -+ continue; -+ -+ walk->nr_pages[gen][type][zone] = 0; -+ WRITE_ONCE(lrugen->nr_pages[gen][type][zone], -+ lrugen->nr_pages[gen][type][zone] + delta); -+ -+ if (lru_gen_is_active(lruvec, gen)) -+ lru += LRU_ACTIVE; -+ __update_lru_size(lruvec, lru, zone, delta); -+ } -+} -+ -+static int should_skip_vma(unsigned long start, unsigned long end, struct mm_walk *args) -+{ -+ struct address_space *mapping; -+ struct vm_area_struct *vma = args->vma; -+ struct lru_gen_mm_walk *walk = args->private; -+ -+ if (!vma_is_accessible(vma)) -+ return true; -+ -+ if (is_vm_hugetlb_page(vma)) -+ return true; -+ -+ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ)) -+ return true; -+ -+ if (vma == get_gate_vma(vma->vm_mm)) -+ return true; -+ -+ if (vma_is_anonymous(vma)) -+ return !walk->can_swap; -+ -+ if (WARN_ON_ONCE(!vma->vm_file || !vma->vm_file->f_mapping)) -+ return true; -+ -+ mapping = vma->vm_file->f_mapping; -+ if (mapping_unevictable(mapping)) -+ return true; -+ -+ if (shmem_mapping(mapping)) -+ return !walk->can_swap; -+ -+ /* to exclude special mappings like dax, etc. */ -+ return !mapping->a_ops->read_folio; -+} -+ -+/* -+ * Some userspace memory allocators map many single-page VMAs. Instead of -+ * returning back to the PGD table for each of such VMAs, finish an entire PMD -+ * table to reduce zigzags and improve cache performance. -+ */ -+static bool get_next_vma(unsigned long mask, unsigned long size, struct mm_walk *args, -+ unsigned long *vm_start, unsigned long *vm_end) -+{ -+ unsigned long start = round_up(*vm_end, size); -+ unsigned long end = (start | ~mask) + 1; -+ -+ VM_WARN_ON_ONCE(mask & size); -+ VM_WARN_ON_ONCE((start & mask) != (*vm_start & mask)); -+ -+ while (args->vma) { -+ if (start >= args->vma->vm_end) { -+ args->vma = args->vma->vm_next; -+ continue; -+ } -+ -+ if (end && end <= args->vma->vm_start) -+ return false; -+ -+ if (should_skip_vma(args->vma->vm_start, args->vma->vm_end, args)) { -+ args->vma = args->vma->vm_next; -+ continue; -+ } -+ -+ *vm_start = max(start, args->vma->vm_start); -+ *vm_end = min(end - 1, args->vma->vm_end - 1) + 1; -+ -+ return true; -+ } -+ -+ return false; -+} -+ - static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr) - { - unsigned long pfn = pte_pfn(pte); -@@ -3295,8 +3774,28 @@ static unsigned long get_pte_pfn(pte_t p - return pfn; - } - -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) -+static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned long addr) -+{ -+ unsigned long pfn = pmd_pfn(pmd); -+ -+ VM_WARN_ON_ONCE(addr < vma->vm_start || addr >= vma->vm_end); -+ -+ if (!pmd_present(pmd) || is_huge_zero_pmd(pmd)) -+ return -1; -+ -+ if (WARN_ON_ONCE(pmd_devmap(pmd))) -+ return -1; -+ -+ if (WARN_ON_ONCE(!pfn_valid(pfn))) -+ return -1; -+ -+ return pfn; -+} -+#endif -+ - static struct folio *get_pfn_folio(unsigned long pfn, struct mem_cgroup *memcg, -- struct pglist_data *pgdat) -+ struct pglist_data *pgdat, bool can_swap) - { - struct folio *folio; - -@@ -3311,9 +3810,375 @@ static struct folio *get_pfn_folio(unsig - if (folio_memcg_rcu(folio) != memcg) - return NULL; - -+ /* file VMAs can contain anon pages from COW */ -+ if (!folio_is_file_lru(folio) && !can_swap) -+ return NULL; -+ - return folio; - } - -+static bool suitable_to_scan(int total, int young) -+{ -+ int n = clamp_t(int, cache_line_size() / sizeof(pte_t), 2, 8); -+ -+ /* suitable if the average number of young PTEs per cacheline is >=1 */ -+ return young * n >= total; -+} -+ -+static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end, -+ struct mm_walk *args) -+{ -+ int i; -+ pte_t *pte; -+ spinlock_t *ptl; -+ unsigned long addr; -+ int total = 0; -+ int young = 0; -+ struct lru_gen_mm_walk *walk = args->private; -+ struct mem_cgroup *memcg = lruvec_memcg(walk->lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); -+ int old_gen, new_gen = lru_gen_from_seq(walk->max_seq); -+ -+ VM_WARN_ON_ONCE(pmd_leaf(*pmd)); -+ -+ ptl = pte_lockptr(args->mm, pmd); -+ if (!spin_trylock(ptl)) -+ return false; -+ -+ arch_enter_lazy_mmu_mode(); -+ -+ pte = pte_offset_map(pmd, start & PMD_MASK); -+restart: -+ for (i = pte_index(start), addr = start; addr != end; i++, addr += PAGE_SIZE) { -+ unsigned long pfn; -+ struct folio *folio; -+ -+ total++; -+ walk->mm_stats[MM_LEAF_TOTAL]++; -+ -+ pfn = get_pte_pfn(pte[i], args->vma, addr); -+ if (pfn == -1) -+ continue; -+ -+ if (!pte_young(pte[i])) { -+ walk->mm_stats[MM_LEAF_OLD]++; -+ continue; -+ } -+ -+ folio = get_pfn_folio(pfn, memcg, pgdat, walk->can_swap); -+ if (!folio) -+ continue; -+ -+ if (!ptep_test_and_clear_young(args->vma, addr, pte + i)) -+ VM_WARN_ON_ONCE(true); -+ -+ young++; -+ walk->mm_stats[MM_LEAF_YOUNG]++; -+ -+ if (pte_dirty(pte[i]) && !folio_test_dirty(folio) && -+ !(folio_test_anon(folio) && folio_test_swapbacked(folio) && -+ !folio_test_swapcache(folio))) -+ folio_mark_dirty(folio); -+ -+ old_gen = folio_update_gen(folio, new_gen); -+ if (old_gen >= 0 && old_gen != new_gen) -+ update_batch_size(walk, folio, old_gen, new_gen); -+ } -+ -+ if (i < PTRS_PER_PTE && get_next_vma(PMD_MASK, PAGE_SIZE, args, &start, &end)) -+ goto restart; -+ -+ pte_unmap(pte); -+ -+ arch_leave_lazy_mmu_mode(); -+ spin_unlock(ptl); -+ -+ return suitable_to_scan(total, young); -+} -+ -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) -+static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma, -+ struct mm_walk *args, unsigned long *bitmap, unsigned long *start) -+{ -+ int i; -+ pmd_t *pmd; -+ spinlock_t *ptl; -+ struct lru_gen_mm_walk *walk = args->private; -+ struct mem_cgroup *memcg = lruvec_memcg(walk->lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); -+ int old_gen, new_gen = lru_gen_from_seq(walk->max_seq); -+ -+ VM_WARN_ON_ONCE(pud_leaf(*pud)); -+ -+ /* try to batch at most 1+MIN_LRU_BATCH+1 entries */ -+ if (*start == -1) { -+ *start = next; -+ return; -+ } -+ -+ i = next == -1 ? 0 : pmd_index(next) - pmd_index(*start); -+ if (i && i <= MIN_LRU_BATCH) { -+ __set_bit(i - 1, bitmap); -+ return; -+ } -+ -+ pmd = pmd_offset(pud, *start); -+ -+ ptl = pmd_lockptr(args->mm, pmd); -+ if (!spin_trylock(ptl)) -+ goto done; -+ -+ arch_enter_lazy_mmu_mode(); -+ -+ do { -+ unsigned long pfn; -+ struct folio *folio; -+ unsigned long addr = i ? (*start & PMD_MASK) + i * PMD_SIZE : *start; -+ -+ pfn = get_pmd_pfn(pmd[i], vma, addr); -+ if (pfn == -1) -+ goto next; -+ -+ if (!pmd_trans_huge(pmd[i])) { -+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)) -+ pmdp_test_and_clear_young(vma, addr, pmd + i); -+ goto next; -+ } -+ -+ folio = get_pfn_folio(pfn, memcg, pgdat, walk->can_swap); -+ if (!folio) -+ goto next; -+ -+ if (!pmdp_test_and_clear_young(vma, addr, pmd + i)) -+ goto next; -+ -+ walk->mm_stats[MM_LEAF_YOUNG]++; -+ -+ if (pmd_dirty(pmd[i]) && !folio_test_dirty(folio) && -+ !(folio_test_anon(folio) && folio_test_swapbacked(folio) && -+ !folio_test_swapcache(folio))) -+ folio_mark_dirty(folio); -+ -+ old_gen = folio_update_gen(folio, new_gen); -+ if (old_gen >= 0 && old_gen != new_gen) -+ update_batch_size(walk, folio, old_gen, new_gen); -+next: -+ i = i > MIN_LRU_BATCH ? 0 : find_next_bit(bitmap, MIN_LRU_BATCH, i) + 1; -+ } while (i <= MIN_LRU_BATCH); -+ -+ arch_leave_lazy_mmu_mode(); -+ spin_unlock(ptl); -+done: -+ *start = -1; -+ bitmap_zero(bitmap, MIN_LRU_BATCH); -+} -+#else -+static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma, -+ struct mm_walk *args, unsigned long *bitmap, unsigned long *start) -+{ -+} -+#endif -+ -+static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end, -+ struct mm_walk *args) -+{ -+ int i; -+ pmd_t *pmd; -+ unsigned long next; -+ unsigned long addr; -+ struct vm_area_struct *vma; -+ unsigned long pos = -1; -+ struct lru_gen_mm_walk *walk = args->private; -+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; -+ -+ VM_WARN_ON_ONCE(pud_leaf(*pud)); -+ -+ /* -+ * Finish an entire PMD in two passes: the first only reaches to PTE -+ * tables to avoid taking the PMD lock; the second, if necessary, takes -+ * the PMD lock to clear the accessed bit in PMD entries. -+ */ -+ pmd = pmd_offset(pud, start & PUD_MASK); -+restart: -+ /* walk_pte_range() may call get_next_vma() */ -+ vma = args->vma; -+ for (i = pmd_index(start), addr = start; addr != end; i++, addr = next) { -+ pmd_t val = pmd_read_atomic(pmd + i); -+ -+ /* for pmd_read_atomic() */ -+ barrier(); -+ -+ next = pmd_addr_end(addr, end); -+ -+ if (!pmd_present(val) || is_huge_zero_pmd(val)) { -+ walk->mm_stats[MM_LEAF_TOTAL]++; -+ continue; -+ } -+ -+#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+ if (pmd_trans_huge(val)) { -+ unsigned long pfn = pmd_pfn(val); -+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); -+ -+ walk->mm_stats[MM_LEAF_TOTAL]++; -+ -+ if (!pmd_young(val)) { -+ walk->mm_stats[MM_LEAF_OLD]++; -+ continue; -+ } -+ -+ /* try to avoid unnecessary memory loads */ -+ if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) -+ continue; -+ -+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+ continue; -+ } -+#endif -+ walk->mm_stats[MM_NONLEAF_TOTAL]++; -+ -+#ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -+ if (!pmd_young(val)) -+ continue; -+ -+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+#endif -+ if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i)) -+ continue; -+ -+ walk->mm_stats[MM_NONLEAF_FOUND]++; -+ -+ if (!walk_pte_range(&val, addr, next, args)) -+ continue; -+ -+ walk->mm_stats[MM_NONLEAF_ADDED]++; -+ -+ /* carry over to the next generation */ -+ update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i); -+ } -+ -+ walk_pmd_range_locked(pud, -1, vma, args, bitmap, &pos); -+ -+ if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end)) -+ goto restart; -+} -+ -+static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end, -+ struct mm_walk *args) -+{ -+ int i; -+ pud_t *pud; -+ unsigned long addr; -+ unsigned long next; -+ struct lru_gen_mm_walk *walk = args->private; -+ -+ VM_WARN_ON_ONCE(p4d_leaf(*p4d)); -+ -+ pud = pud_offset(p4d, start & P4D_MASK); -+restart: -+ for (i = pud_index(start), addr = start; addr != end; i++, addr = next) { -+ pud_t val = READ_ONCE(pud[i]); -+ -+ next = pud_addr_end(addr, end); -+ -+ if (!pud_present(val) || WARN_ON_ONCE(pud_leaf(val))) -+ continue; -+ -+ walk_pmd_range(&val, addr, next, args); -+ -+ /* a racy check to curtail the waiting time */ -+ if (wq_has_sleeper(&walk->lruvec->mm_state.wait)) -+ return 1; -+ -+ if (need_resched() || walk->batched >= MAX_LRU_BATCH) { -+ end = (addr | ~PUD_MASK) + 1; -+ goto done; -+ } -+ } -+ -+ if (i < PTRS_PER_PUD && get_next_vma(P4D_MASK, PUD_SIZE, args, &start, &end)) -+ goto restart; -+ -+ end = round_up(end, P4D_SIZE); -+done: -+ if (!end || !args->vma) -+ return 1; -+ -+ walk->next_addr = max(end, args->vma->vm_start); -+ -+ return -EAGAIN; -+} -+ -+static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk) -+{ -+ static const struct mm_walk_ops mm_walk_ops = { -+ .test_walk = should_skip_vma, -+ .p4d_entry = walk_pud_range, -+ }; -+ -+ int err; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ -+ walk->next_addr = FIRST_USER_ADDRESS; -+ -+ do { -+ err = -EBUSY; -+ -+ /* folio_update_gen() requires stable folio_memcg() */ -+ if (!mem_cgroup_trylock_pages(memcg)) -+ break; -+ -+ /* the caller might be holding the lock for write */ -+ if (mmap_read_trylock(mm)) { -+ err = walk_page_range(mm, walk->next_addr, ULONG_MAX, &mm_walk_ops, walk); -+ -+ mmap_read_unlock(mm); -+ } -+ -+ mem_cgroup_unlock_pages(); -+ -+ if (walk->batched) { -+ spin_lock_irq(&lruvec->lru_lock); -+ reset_batch_size(lruvec, walk); -+ spin_unlock_irq(&lruvec->lru_lock); -+ } -+ -+ cond_resched(); -+ } while (err == -EAGAIN); -+} -+ -+static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat) -+{ -+ struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk; -+ -+ if (pgdat && current_is_kswapd()) { -+ VM_WARN_ON_ONCE(walk); -+ -+ walk = &pgdat->mm_walk; -+ } else if (!pgdat && !walk) { -+ VM_WARN_ON_ONCE(current_is_kswapd()); -+ -+ walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); -+ } -+ -+ current->reclaim_state->mm_walk = walk; -+ -+ return walk; -+} -+ -+static void clear_mm_walk(void) -+{ -+ struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk; -+ -+ VM_WARN_ON_ONCE(walk && memchr_inv(walk->nr_pages, 0, sizeof(walk->nr_pages))); -+ VM_WARN_ON_ONCE(walk && memchr_inv(walk->mm_stats, 0, sizeof(walk->mm_stats))); -+ -+ current->reclaim_state->mm_walk = NULL; -+ -+ if (!current_is_kswapd()) -+ kfree(walk); -+} -+ - static void inc_min_seq(struct lruvec *lruvec, int type) - { - struct lru_gen_struct *lrugen = &lruvec->lrugen; -@@ -3365,7 +4230,7 @@ next: - return success; - } - --static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, bool can_swap) -+static void inc_max_seq(struct lruvec *lruvec, bool can_swap) - { - int prev, next; - int type, zone; -@@ -3375,9 +4240,6 @@ static void inc_max_seq(struct lruvec *l - - VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); - -- if (max_seq != lrugen->max_seq) -- goto unlock; -- - for (type = ANON_AND_FILE - 1; type >= 0; type--) { - if (get_nr_gens(lruvec, type) != MAX_NR_GENS) - continue; -@@ -3415,10 +4277,74 @@ static void inc_max_seq(struct lruvec *l - - /* make sure preceding modifications appear */ - smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1); --unlock: -+ - spin_unlock_irq(&lruvec->lru_lock); - } - -+static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, -+ struct scan_control *sc, bool can_swap) -+{ -+ bool success; -+ struct lru_gen_mm_walk *walk; -+ struct mm_struct *mm = NULL; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq)); -+ -+ /* see the comment in iterate_mm_list() */ -+ if (max_seq <= READ_ONCE(lruvec->mm_state.seq)) { -+ success = false; -+ goto done; -+ } -+ -+ /* -+ * If the hardware doesn't automatically set the accessed bit, fallback -+ * to lru_gen_look_around(), which only clears the accessed bit in a -+ * handful of PTEs. Spreading the work out over a period of time usually -+ * is less efficient, but it avoids bursty page faults. -+ */ -+ if (!arch_has_hw_pte_young()) { -+ success = iterate_mm_list_nowalk(lruvec, max_seq); -+ goto done; -+ } -+ -+ walk = set_mm_walk(NULL); -+ if (!walk) { -+ success = iterate_mm_list_nowalk(lruvec, max_seq); -+ goto done; -+ } -+ -+ walk->lruvec = lruvec; -+ walk->max_seq = max_seq; -+ walk->can_swap = can_swap; -+ walk->force_scan = false; -+ -+ do { -+ success = iterate_mm_list(lruvec, walk, &mm); -+ if (mm) -+ walk_mm(lruvec, mm, walk); -+ -+ cond_resched(); -+ } while (mm); -+done: -+ if (!success) { -+ if (sc->priority <= DEF_PRIORITY - 2) -+ wait_event_killable(lruvec->mm_state.wait, -+ max_seq < READ_ONCE(lrugen->max_seq)); -+ -+ return max_seq < READ_ONCE(lrugen->max_seq); -+ } -+ -+ VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); -+ -+ inc_max_seq(lruvec, can_swap); -+ /* either this sees any waiters or they will see updated max_seq */ -+ if (wq_has_sleeper(&lruvec->mm_state.wait)) -+ wake_up_all(&lruvec->mm_state.wait); -+ -+ return true; -+} -+ - static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq, - struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) - { -@@ -3494,7 +4420,7 @@ static void age_lruvec(struct lruvec *lr - - need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); - if (need_aging) -- inc_max_seq(lruvec, max_seq, swappiness); -+ try_to_inc_max_seq(lruvec, max_seq, sc, swappiness); - } - - static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) -@@ -3503,6 +4429,8 @@ static void lru_gen_age_node(struct pgli - - VM_WARN_ON_ONCE(!current_is_kswapd()); - -+ set_mm_walk(pgdat); -+ - memcg = mem_cgroup_iter(NULL, NULL, NULL); - do { - struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -@@ -3511,11 +4439,16 @@ static void lru_gen_age_node(struct pgli - - cond_resched(); - } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+ -+ clear_mm_walk(); - } - - /* - * This function exploits spatial locality when shrink_page_list() walks the -- * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. -+ * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If -+ * the scan was done cacheline efficiently, it adds the PMD entry pointing to -+ * the PTE table to the Bloom filter. This forms a feedback loop between the -+ * eviction and the aging. - */ - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) - { -@@ -3524,6 +4457,8 @@ void lru_gen_look_around(struct page_vma - unsigned long start; - unsigned long end; - unsigned long addr; -+ struct lru_gen_mm_walk *walk; -+ int young = 0; - unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; - struct folio *folio = pfn_folio(pvmw->pfn); - struct mem_cgroup *memcg = folio_memcg(folio); -@@ -3538,6 +4473,9 @@ void lru_gen_look_around(struct page_vma - if (spin_is_contended(pvmw->ptl)) - return; - -+ /* avoid taking the LRU lock under the PTL when possible */ -+ walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL; -+ - start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start); - end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1; - -@@ -3567,13 +4505,15 @@ void lru_gen_look_around(struct page_vma - if (!pte_young(pte[i])) - continue; - -- folio = get_pfn_folio(pfn, memcg, pgdat); -+ folio = get_pfn_folio(pfn, memcg, pgdat, !walk || walk->can_swap); - if (!folio) - continue; - - if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i)) - VM_WARN_ON_ONCE(true); - -+ young++; -+ - if (pte_dirty(pte[i]) && !folio_test_dirty(folio) && - !(folio_test_anon(folio) && folio_test_swapbacked(folio) && - !folio_test_swapcache(folio))) -@@ -3589,7 +4529,11 @@ void lru_gen_look_around(struct page_vma - arch_leave_lazy_mmu_mode(); - rcu_read_unlock(); - -- if (bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) { -+ /* feedback from rmap walkers to page table walkers */ -+ if (suitable_to_scan(i, young)) -+ update_bloom_filter(lruvec, max_seq, pvmw->pmd); -+ -+ if (!walk && bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) { - for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { - folio = pfn_folio(pte_pfn(pte[i])); - folio_activate(folio); -@@ -3601,8 +4545,10 @@ void lru_gen_look_around(struct page_vma - if (!mem_cgroup_trylock_pages(memcg)) - return; - -- spin_lock_irq(&lruvec->lru_lock); -- new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq); -+ if (!walk) { -+ spin_lock_irq(&lruvec->lru_lock); -+ new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq); -+ } - - for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { - folio = pfn_folio(pte_pfn(pte[i])); -@@ -3613,10 +4559,14 @@ void lru_gen_look_around(struct page_vma - if (old_gen < 0 || old_gen == new_gen) - continue; - -- lru_gen_update_size(lruvec, folio, old_gen, new_gen); -+ if (walk) -+ update_batch_size(walk, folio, old_gen, new_gen); -+ else -+ lru_gen_update_size(lruvec, folio, old_gen, new_gen); - } - -- spin_unlock_irq(&lruvec->lru_lock); -+ if (!walk) -+ spin_unlock_irq(&lruvec->lru_lock); - - mem_cgroup_unlock_pages(); - } -@@ -3899,6 +4849,7 @@ static int evict_folios(struct lruvec *l - struct folio *folio; - enum vm_event_item item; - struct reclaim_stat stat; -+ struct lru_gen_mm_walk *walk; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - struct pglist_data *pgdat = lruvec_pgdat(lruvec); - -@@ -3935,6 +4886,10 @@ static int evict_folios(struct lruvec *l - - move_pages_to_lru(lruvec, &list); - -+ walk = current->reclaim_state->mm_walk; -+ if (walk && walk->batched) -+ reset_batch_size(lruvec, walk); -+ - item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT; - if (!cgroup_reclaim(sc)) - __count_vm_events(item, reclaimed); -@@ -3951,6 +4906,11 @@ static int evict_folios(struct lruvec *l - return scanned; - } - -+/* -+ * For future optimizations: -+ * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg -+ * reclaim. -+ */ - static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, - bool can_swap) - { -@@ -3976,7 +4936,8 @@ static unsigned long get_nr_to_scan(stru - if (current_is_kswapd()) - return 0; - -- inc_max_seq(lruvec, max_seq, can_swap); -+ if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap)) -+ return nr_to_scan; - done: - return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; - } -@@ -3990,6 +4951,8 @@ static void lru_gen_shrink_lruvec(struct - - blk_start_plug(&plug); - -+ set_mm_walk(lruvec_pgdat(lruvec)); -+ - while (true) { - int delta; - int swappiness; -@@ -4017,6 +4980,8 @@ static void lru_gen_shrink_lruvec(struct - cond_resched(); - } - -+ clear_mm_walk(); -+ - blk_finish_plug(&plug); - } - -@@ -4033,15 +4998,21 @@ void lru_gen_init_lruvec(struct lruvec * - - for_each_gen_type_zone(gen, type, zone) - INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -+ -+ lruvec->mm_state.seq = MIN_NR_GENS; -+ init_waitqueue_head(&lruvec->mm_state.wait); - } - - #ifdef CONFIG_MEMCG - void lru_gen_init_memcg(struct mem_cgroup *memcg) - { -+ INIT_LIST_HEAD(&memcg->mm_list.fifo); -+ spin_lock_init(&memcg->mm_list.lock); - } - - void lru_gen_exit_memcg(struct mem_cgroup *memcg) - { -+ int i; - int nid; - - for_each_node(nid) { -@@ -4049,6 +5020,11 @@ void lru_gen_exit_memcg(struct mem_cgrou - - VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, - sizeof(lruvec->lrugen.nr_pages))); -+ -+ for (i = 0; i < NR_BLOOM_FILTERS; i++) { -+ bitmap_free(lruvec->mm_state.filters[i]); -+ lruvec->mm_state.filters[i] = NULL; -+ } - } - } - #endif diff --git a/target/linux/generic/backport-6.0/108-mm-multi-gen-LRU-optimize-multiple-memcgs.patch b/target/linux/generic/backport-6.0/108-mm-multi-gen-LRU-optimize-multiple-memcgs.patch deleted file mode 100644 index 5430cc66e..000000000 --- a/target/linux/generic/backport-6.0/108-mm-multi-gen-LRU-optimize-multiple-memcgs.patch +++ /dev/null @@ -1,290 +0,0 @@ -From 6b9670b94ba2b49b289b997121062500e32fc3e4 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Thu, 27 Jan 2022 19:59:54 -0700 -Subject: [PATCH 09/14] mm: multi-gen LRU: optimize multiple memcgs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When multiple memcgs are available, it is possible to use generations -as a frame of reference to make better choices and improve overall -performance under global memory pressure. This patch adds a basic -optimization to select memcgs that can drop single-use unmapped clean -pages first. Doing so reduces the chance of going into the aging path -or swapping, which can be costly. - -A typical example that benefits from this optimization is a server -running mixed types of workloads, e.g., heavy anon workload in one -memcg and heavy buffered I/O workload in the other. - -Though this optimization can be applied to both kswapd and direct -reclaim, it is only added to kswapd to keep the patchset manageable. -Later improvements may cover the direct reclaim path. - -While ensuring certain fairness to all eligible memcgs, proportional -scans of individual memcgs also require proper backoff to avoid -overshooting their aggregate reclaim target by too much. Otherwise it -can cause high direct reclaim latency. The conditions for backoff are: -1. At low priorities, for direct reclaim, if aging fairness or direct - reclaim latency is at risk, i.e., aging one memcg multiple times or - swapping after the target is met. -2. At high priorities, for global reclaim, if per-zone free pages are - above respective watermarks. - -Server benchmark results: - Mixed workloads: - fio (buffered I/O): +[19, 21]% - IOPS BW - patch1-8: 1880k 7343MiB/s - patch1-9: 2252k 8796MiB/s - - memcached (anon): +[119, 123]% - Ops/sec KB/sec - patch1-8: 862768.65 33514.68 - patch1-9: 1911022.12 74234.54 - - Mixed workloads: - fio (buffered I/O): +[75, 77]% - IOPS BW - 5.19-rc1: 1279k 4996MiB/s - patch1-9: 2252k 8796MiB/s - - memcached (anon): +[13, 15]% - Ops/sec KB/sec - 5.19-rc1: 1673524.04 65008.87 - patch1-9: 1911022.12 74234.54 - - Configurations: - (changes since patch 6) - - cat mixed.sh - modprobe brd rd_nr=2 rd_size=56623104 - - swapoff -a - mkswap /dev/ram0 - swapon /dev/ram0 - - mkfs.ext4 /dev/ram1 - mount -t ext4 /dev/ram1 /mnt - - memtier_benchmark -S /var/run/memcached/memcached.sock \ - -P memcache_binary -n allkeys --key-minimum=1 \ - --key-maximum=50000000 --key-pattern=P:P -c 1 -t 36 \ - --ratio 1:0 --pipeline 8 -d 2000 - - fio -name=mglru --numjobs=36 --directory=/mnt --size=1408m \ - --buffered=1 --ioengine=io_uring --iodepth=128 \ - --iodepth_batch_submit=32 --iodepth_batch_complete=32 \ - --rw=randread --random_distribution=random --norandommap \ - --time_based --ramp_time=10m --runtime=90m --group_reporting & - pid=$! - - sleep 200 - - memtier_benchmark -S /var/run/memcached/memcached.sock \ - -P memcache_binary -n allkeys --key-minimum=1 \ - --key-maximum=50000000 --key-pattern=R:R -c 1 -t 36 \ - --ratio 0:1 --pipeline 8 --randomize --distinct-client-seed - - kill -INT $pid - wait - -Client benchmark results: - no change (CONFIG_MEMCG=n) - -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I7e00e0c733437e534ac98031cf8154a681becc00 ---- - mm/vmscan.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 95 insertions(+), 9 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -131,6 +131,12 @@ struct scan_control { - /* Always discard instead of demoting to lower tier memory */ - unsigned int no_demotion:1; - -+#ifdef CONFIG_LRU_GEN -+ /* help kswapd make better choices among multiple memcgs */ -+ unsigned int memcgs_need_aging:1; -+ unsigned long last_reclaimed; -+#endif -+ - /* Allocation order */ - s8 order; - -@@ -4429,6 +4435,19 @@ static void lru_gen_age_node(struct pgli - - VM_WARN_ON_ONCE(!current_is_kswapd()); - -+ sc->last_reclaimed = sc->nr_reclaimed; -+ -+ /* -+ * To reduce the chance of going into the aging path, which can be -+ * costly, optimistically skip it if the flag below was cleared in the -+ * eviction path. This improves the overall performance when multiple -+ * memcgs are available. -+ */ -+ if (!sc->memcgs_need_aging) { -+ sc->memcgs_need_aging = true; -+ return; -+ } -+ - set_mm_walk(pgdat); - - memcg = mem_cgroup_iter(NULL, NULL, NULL); -@@ -4840,7 +4859,8 @@ static int isolate_folios(struct lruvec - return scanned; - } - --static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness) -+static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness, -+ bool *need_swapping) - { - int type; - int scanned; -@@ -4903,6 +4923,9 @@ static int evict_folios(struct lruvec *l - - sc->nr_reclaimed += reclaimed; - -+ if (need_swapping && type == LRU_GEN_ANON) -+ *need_swapping = true; -+ - return scanned; - } - -@@ -4912,9 +4935,8 @@ static int evict_folios(struct lruvec *l - * reclaim. - */ - static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, -- bool can_swap) -+ bool can_swap, bool *need_aging) - { -- bool need_aging; - unsigned long nr_to_scan; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); -@@ -4924,8 +4946,8 @@ static unsigned long get_nr_to_scan(stru - (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) - return 0; - -- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); -- if (!need_aging) -+ *need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); -+ if (!*need_aging) - return nr_to_scan; - - /* skip the aging path at the default priority */ -@@ -4942,10 +4964,67 @@ done: - return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; - } - -+static bool should_abort_scan(struct lruvec *lruvec, unsigned long seq, -+ struct scan_control *sc, bool need_swapping) -+{ -+ int i; -+ DEFINE_MAX_SEQ(lruvec); -+ -+ if (!current_is_kswapd()) { -+ /* age each memcg at most once to ensure fairness */ -+ if (max_seq - seq > 1) -+ return true; -+ -+ /* over-swapping can increase allocation latency */ -+ if (sc->nr_reclaimed >= sc->nr_to_reclaim && need_swapping) -+ return true; -+ -+ /* give this thread a chance to exit and free its memory */ -+ if (fatal_signal_pending(current)) { -+ sc->nr_reclaimed += MIN_LRU_BATCH; -+ return true; -+ } -+ -+ if (cgroup_reclaim(sc)) -+ return false; -+ } else if (sc->nr_reclaimed - sc->last_reclaimed < sc->nr_to_reclaim) -+ return false; -+ -+ /* keep scanning at low priorities to ensure fairness */ -+ if (sc->priority > DEF_PRIORITY - 2) -+ return false; -+ -+ /* -+ * A minimum amount of work was done under global memory pressure. For -+ * kswapd, it may be overshooting. For direct reclaim, the allocation -+ * may succeed if all suitable zones are somewhat safe. In either case, -+ * it's better to stop now, and restart later if necessary. -+ */ -+ for (i = 0; i <= sc->reclaim_idx; i++) { -+ unsigned long wmark; -+ struct zone *zone = lruvec_pgdat(lruvec)->node_zones + i; -+ -+ if (!managed_zone(zone)) -+ continue; -+ -+ wmark = current_is_kswapd() ? high_wmark_pages(zone) : low_wmark_pages(zone); -+ if (wmark > zone_page_state(zone, NR_FREE_PAGES)) -+ return false; -+ } -+ -+ sc->nr_reclaimed += MIN_LRU_BATCH; -+ -+ return true; -+} -+ - static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - struct blk_plug plug; -+ bool need_aging = false; -+ bool need_swapping = false; - unsigned long scanned = 0; -+ unsigned long reclaimed = sc->nr_reclaimed; -+ DEFINE_MAX_SEQ(lruvec); - - lru_add_drain(); - -@@ -4965,21 +5044,28 @@ static void lru_gen_shrink_lruvec(struct - else - swappiness = 0; - -- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); -+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness, &need_aging); - if (!nr_to_scan) -- break; -+ goto done; - -- delta = evict_folios(lruvec, sc, swappiness); -+ delta = evict_folios(lruvec, sc, swappiness, &need_swapping); - if (!delta) -- break; -+ goto done; - - scanned += delta; - if (scanned >= nr_to_scan) - break; - -+ if (should_abort_scan(lruvec, max_seq, sc, need_swapping)) -+ break; -+ - cond_resched(); - } - -+ /* see the comment in lru_gen_age_node() */ -+ if (sc->nr_reclaimed - reclaimed >= MIN_LRU_BATCH && !need_aging) -+ sc->memcgs_need_aging = false; -+done: - clear_mm_walk(); - - blk_finish_plug(&plug); diff --git a/target/linux/generic/backport-6.0/109-mm-multi-gen-LRU-kill-switch.patch b/target/linux/generic/backport-6.0/109-mm-multi-gen-LRU-kill-switch.patch deleted file mode 100644 index 384365a33..000000000 --- a/target/linux/generic/backport-6.0/109-mm-multi-gen-LRU-kill-switch.patch +++ /dev/null @@ -1,475 +0,0 @@ -From ef61bb3622ee0f36e055dfd5006badff08f5ce61 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Thu, 27 Jan 2022 19:52:09 -0700 -Subject: [PATCH 10/14] mm: multi-gen LRU: kill switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add /sys/kernel/mm/lru_gen/enabled as a kill switch. Components that -can be disabled include: - 0x0001: the multi-gen LRU core - 0x0002: walking page table, when arch_has_hw_pte_young() returns - true - 0x0004: clearing the accessed bit in non-leaf PMD entries, when - CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y - [yYnN]: apply to all the components above -E.g., - echo y >/sys/kernel/mm/lru_gen/enabled - cat /sys/kernel/mm/lru_gen/enabled - 0x0007 - echo 5 >/sys/kernel/mm/lru_gen/enabled - cat /sys/kernel/mm/lru_gen/enabled - 0x0005 - -NB: the page table walks happen on the scale of seconds under heavy -memory pressure, in which case the mmap_lock contention is a lesser -concern, compared with the LRU lock contention and the I/O congestion. -So far the only well-known case of the mmap_lock contention happens on -Android, due to Scudo [1] which allocates several thousand VMAs for -merely a few hundred MBs. The SPF and the Maple Tree also have -provided their own assessments [2][3]. However, if walking page tables -does worsen the mmap_lock contention, the kill switch can be used to -disable it. In this case the multi-gen LRU will suffer a minor -performance degradation, as shown previously. - -Clearing the accessed bit in non-leaf PMD entries can also be -disabled, since this behavior was not tested on x86 varieties other -than Intel and AMD. - -[1] https://source.android.com/devices/tech/debug/scudo -[2] https://lore.kernel.org/r/20220128131006.67712-1-michel@lespinasse.org/ -[3] https://lore.kernel.org/r/20220426150616.3937571-1-Liam.Howlett@oracle.com/ - -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I4c909618e8fed7fb1337f6624bbe542ec920a515 ---- - include/linux/cgroup.h | 15 ++- - include/linux/mm_inline.h | 15 ++- - include/linux/mmzone.h | 9 ++ - kernel/cgroup/cgroup-internal.h | 1 - - mm/Kconfig | 6 + - mm/vmscan.c | 228 +++++++++++++++++++++++++++++++- - 6 files changed, 265 insertions(+), 9 deletions(-) - ---- a/include/linux/cgroup.h -+++ b/include/linux/cgroup.h -@@ -432,6 +432,18 @@ static inline void cgroup_put(struct cgr - css_put(&cgrp->self); - } - -+extern struct mutex cgroup_mutex; -+ -+static inline void cgroup_lock(void) -+{ -+ mutex_lock(&cgroup_mutex); -+} -+ -+static inline void cgroup_unlock(void) -+{ -+ mutex_unlock(&cgroup_mutex); -+} -+ - /** - * task_css_set_check - obtain a task's css_set with extra access conditions - * @task: the task to obtain css_set for -@@ -446,7 +458,6 @@ static inline void cgroup_put(struct cgr - * as locks used during the cgroup_subsys::attach() methods. - */ - #ifdef CONFIG_PROVE_RCU --extern struct mutex cgroup_mutex; - extern spinlock_t css_set_lock; - #define task_css_set_check(task, __c) \ - rcu_dereference_check((task)->cgroups, \ -@@ -708,6 +719,8 @@ struct cgroup; - static inline u64 cgroup_id(const struct cgroup *cgrp) { return 1; } - static inline void css_get(struct cgroup_subsys_state *css) {} - static inline void css_put(struct cgroup_subsys_state *css) {} -+static inline void cgroup_lock(void) {} -+static inline void cgroup_unlock(void) {} - static inline int cgroup_attach_task_all(struct task_struct *from, - struct task_struct *t) { return 0; } - static inline int cgroupstats_build(struct cgroupstats *stats, ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -106,10 +106,21 @@ static __always_inline enum lru_list fol - - #ifdef CONFIG_LRU_GEN - -+#ifdef CONFIG_LRU_GEN_ENABLED - static inline bool lru_gen_enabled(void) - { -- return true; -+ DECLARE_STATIC_KEY_TRUE(lru_gen_caps[NR_LRU_GEN_CAPS]); -+ -+ return static_branch_likely(&lru_gen_caps[LRU_GEN_CORE]); -+} -+#else -+static inline bool lru_gen_enabled(void) -+{ -+ DECLARE_STATIC_KEY_FALSE(lru_gen_caps[NR_LRU_GEN_CAPS]); -+ -+ return static_branch_unlikely(&lru_gen_caps[LRU_GEN_CORE]); - } -+#endif - - static inline bool lru_gen_in_fault(void) - { -@@ -222,7 +233,7 @@ static inline bool lru_gen_add_folio(str - - VM_WARN_ON_ONCE_FOLIO(gen != -1, folio); - -- if (folio_test_unevictable(folio)) -+ if (folio_test_unevictable(folio) || !lrugen->enabled) - return false; - /* - * There are three common cases for this page: ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -384,6 +384,13 @@ enum { - LRU_GEN_FILE, - }; - -+enum { -+ LRU_GEN_CORE, -+ LRU_GEN_MM_WALK, -+ LRU_GEN_NONLEAF_YOUNG, -+ NR_LRU_GEN_CAPS -+}; -+ - #define MIN_LRU_BATCH BITS_PER_LONG - #define MAX_LRU_BATCH (MIN_LRU_BATCH * 64) - -@@ -425,6 +432,8 @@ struct lru_gen_struct { - /* can be modified without holding the LRU lock */ - atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; - atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; -+ /* whether the multi-gen LRU is enabled */ -+ bool enabled; - }; - - enum { ---- a/kernel/cgroup/cgroup-internal.h -+++ b/kernel/cgroup/cgroup-internal.h -@@ -164,7 +164,6 @@ struct cgroup_mgctx { - #define DEFINE_CGROUP_MGCTX(name) \ - struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name) - --extern struct mutex cgroup_mutex; - extern spinlock_t css_set_lock; - extern struct cgroup_subsys *cgroup_subsys[]; - extern struct list_head cgroup_roots; ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -1133,6 +1133,12 @@ config LRU_GEN - help - A high performance LRU implementation to overcommit memory. - -+config LRU_GEN_ENABLED -+ bool "Enable by default" -+ depends on LRU_GEN -+ help -+ This option enables the multi-gen LRU by default. -+ - config LRU_GEN_STATS - bool "Full stats for debugging" - depends on LRU_GEN ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -51,6 +51,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -3070,6 +3071,14 @@ static bool can_age_anon_pages(struct pg - - #ifdef CONFIG_LRU_GEN - -+#ifdef CONFIG_LRU_GEN_ENABLED -+DEFINE_STATIC_KEY_ARRAY_TRUE(lru_gen_caps, NR_LRU_GEN_CAPS); -+#define get_cap(cap) static_branch_likely(&lru_gen_caps[cap]) -+#else -+DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_caps, NR_LRU_GEN_CAPS); -+#define get_cap(cap) static_branch_unlikely(&lru_gen_caps[cap]) -+#endif -+ - /****************************************************************************** - * shorthand helpers - ******************************************************************************/ -@@ -3946,7 +3955,8 @@ static void walk_pmd_range_locked(pud_t - goto next; - - if (!pmd_trans_huge(pmd[i])) { -- if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)) -+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && -+ get_cap(LRU_GEN_NONLEAF_YOUNG)) - pmdp_test_and_clear_young(vma, addr, pmd + i); - goto next; - } -@@ -4044,10 +4054,12 @@ restart: - walk->mm_stats[MM_NONLEAF_TOTAL]++; - - #ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -- if (!pmd_young(val)) -- continue; -+ if (get_cap(LRU_GEN_NONLEAF_YOUNG)) { -+ if (!pmd_young(val)) -+ continue; - -- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+ } - #endif - if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i)) - continue; -@@ -4309,7 +4321,7 @@ static bool try_to_inc_max_seq(struct lr - * handful of PTEs. Spreading the work out over a period of time usually - * is less efficient, but it avoids bursty page faults. - */ -- if (!arch_has_hw_pte_young()) { -+ if (!(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { - success = iterate_mm_list_nowalk(lruvec, max_seq); - goto done; - } -@@ -5072,6 +5084,208 @@ done: - } - - /****************************************************************************** -+ * state change -+ ******************************************************************************/ -+ -+static bool __maybe_unused state_is_valid(struct lruvec *lruvec) -+{ -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ if (lrugen->enabled) { -+ enum lru_list lru; -+ -+ for_each_evictable_lru(lru) { -+ if (!list_empty(&lruvec->lists[lru])) -+ return false; -+ } -+ } else { -+ int gen, type, zone; -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ if (!list_empty(&lrugen->lists[gen][type][zone])) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static bool fill_evictable(struct lruvec *lruvec) -+{ -+ enum lru_list lru; -+ int remaining = MAX_LRU_BATCH; -+ -+ for_each_evictable_lru(lru) { -+ int type = is_file_lru(lru); -+ bool active = is_active_lru(lru); -+ struct list_head *head = &lruvec->lists[lru]; -+ -+ while (!list_empty(head)) { -+ bool success; -+ struct folio *folio = lru_to_folio(head); -+ -+ VM_WARN_ON_ONCE_FOLIO(folio_test_unevictable(folio), folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_test_active(folio) != active, folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_is_file_lru(folio) != type, folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_lru_gen(folio) != -1, folio); -+ -+ lruvec_del_folio(lruvec, folio); -+ success = lru_gen_add_folio(lruvec, folio, false); -+ VM_WARN_ON_ONCE(!success); -+ -+ if (!--remaining) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static bool drain_evictable(struct lruvec *lruvec) -+{ -+ int gen, type, zone; -+ int remaining = MAX_LRU_BATCH; -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ struct list_head *head = &lruvec->lrugen.lists[gen][type][zone]; -+ -+ while (!list_empty(head)) { -+ bool success; -+ struct folio *folio = lru_to_folio(head); -+ -+ VM_WARN_ON_ONCE_FOLIO(folio_test_unevictable(folio), folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_test_active(folio), folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_is_file_lru(folio) != type, folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio); -+ -+ success = lru_gen_del_folio(lruvec, folio, false); -+ VM_WARN_ON_ONCE(!success); -+ lruvec_add_folio(lruvec, folio); -+ -+ if (!--remaining) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static void lru_gen_change_state(bool enabled) -+{ -+ static DEFINE_MUTEX(state_mutex); -+ -+ struct mem_cgroup *memcg; -+ -+ cgroup_lock(); -+ cpus_read_lock(); -+ get_online_mems(); -+ mutex_lock(&state_mutex); -+ -+ if (enabled == lru_gen_enabled()) -+ goto unlock; -+ -+ if (enabled) -+ static_branch_enable_cpuslocked(&lru_gen_caps[LRU_GEN_CORE]); -+ else -+ static_branch_disable_cpuslocked(&lru_gen_caps[LRU_GEN_CORE]); -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ int nid; -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ if (!lruvec) -+ continue; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -+ VM_WARN_ON_ONCE(!state_is_valid(lruvec)); -+ -+ lruvec->lrugen.enabled = enabled; -+ -+ while (!(enabled ? fill_evictable(lruvec) : drain_evictable(lruvec))) { -+ spin_unlock_irq(&lruvec->lru_lock); -+ cond_resched(); -+ spin_lock_irq(&lruvec->lru_lock); -+ } -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ } -+ -+ cond_resched(); -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+unlock: -+ mutex_unlock(&state_mutex); -+ put_online_mems(); -+ cpus_read_unlock(); -+ cgroup_unlock(); -+} -+ -+/****************************************************************************** -+ * sysfs interface -+ ******************************************************************************/ -+ -+static ssize_t show_enabled(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -+{ -+ unsigned int caps = 0; -+ -+ if (get_cap(LRU_GEN_CORE)) -+ caps |= BIT(LRU_GEN_CORE); -+ -+ if (arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK)) -+ caps |= BIT(LRU_GEN_MM_WALK); -+ -+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && get_cap(LRU_GEN_NONLEAF_YOUNG)) -+ caps |= BIT(LRU_GEN_NONLEAF_YOUNG); -+ -+ return snprintf(buf, PAGE_SIZE, "0x%04x\n", caps); -+} -+ -+static ssize_t store_enabled(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t len) -+{ -+ int i; -+ unsigned int caps; -+ -+ if (tolower(*buf) == 'n') -+ caps = 0; -+ else if (tolower(*buf) == 'y') -+ caps = -1; -+ else if (kstrtouint(buf, 0, &caps)) -+ return -EINVAL; -+ -+ for (i = 0; i < NR_LRU_GEN_CAPS; i++) { -+ bool enabled = caps & BIT(i); -+ -+ if (i == LRU_GEN_CORE) -+ lru_gen_change_state(enabled); -+ else if (enabled) -+ static_branch_enable(&lru_gen_caps[i]); -+ else -+ static_branch_disable(&lru_gen_caps[i]); -+ } -+ -+ return len; -+} -+ -+static struct kobj_attribute lru_gen_enabled_attr = __ATTR( -+ enabled, 0644, show_enabled, store_enabled -+); -+ -+static struct attribute *lru_gen_attrs[] = { -+ &lru_gen_enabled_attr.attr, -+ NULL -+}; -+ -+static struct attribute_group lru_gen_attr_group = { -+ .name = "lru_gen", -+ .attrs = lru_gen_attrs, -+}; -+ -+/****************************************************************************** - * initialization - ******************************************************************************/ - -@@ -5081,6 +5295,7 @@ void lru_gen_init_lruvec(struct lruvec * - struct lru_gen_struct *lrugen = &lruvec->lrugen; - - lrugen->max_seq = MIN_NR_GENS + 1; -+ lrugen->enabled = lru_gen_enabled(); - - for_each_gen_type_zone(gen, type, zone) - INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -@@ -5120,6 +5335,9 @@ static int __init init_lru_gen(void) - BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS); - BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS); - -+ if (sysfs_create_group(mm_kobj, &lru_gen_attr_group)) -+ pr_err("lru_gen: failed to create sysfs group\n"); -+ - return 0; - }; - late_initcall(init_lru_gen); diff --git a/target/linux/generic/backport-6.0/110-mm-multi-gen-LRU-thrashing-prevention.patch b/target/linux/generic/backport-6.0/110-mm-multi-gen-LRU-thrashing-prevention.patch deleted file mode 100644 index 58492dcff..000000000 --- a/target/linux/generic/backport-6.0/110-mm-multi-gen-LRU-thrashing-prevention.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 9d92c76fb8ac09ff195024139575d8c4db66b672 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Thu, 27 Jan 2022 20:08:50 -0700 -Subject: [PATCH 11/14] mm: multi-gen LRU: thrashing prevention -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add /sys/kernel/mm/lru_gen/min_ttl_ms for thrashing prevention, as -requested by many desktop users [1]. - -When set to value N, it prevents the working set of N milliseconds -from getting evicted. The OOM killer is triggered if this working set -cannot be kept in memory. Based on the average human detectable lag -(~100ms), N=1000 usually eliminates intolerable lags due to thrashing. -Larger values like N=3000 make lags less noticeable at the risk of -premature OOM kills. - -Compared with the size-based approach [2], this time-based approach -has the following advantages: -1. It is easier to configure because it is agnostic to applications - and memory sizes. -2. It is more reliable because it is directly wired to the OOM killer. - -[1] https://lore.kernel.org/r/Ydza%2FzXKY9ATRoh6@google.com/ -[2] https://lore.kernel.org/r/20101028191523.GA14972@google.com/ - -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I007499d7e47374b59fd620e8c3962940bc9f788e ---- - include/linux/mmzone.h | 2 ++ - mm/vmscan.c | 74 ++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 73 insertions(+), 3 deletions(-) - ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -419,6 +419,8 @@ struct lru_gen_struct { - unsigned long max_seq; - /* the eviction increments the oldest generation numbers */ - unsigned long min_seq[ANON_AND_FILE]; -+ /* the birth time of each generation in jiffies */ -+ unsigned long timestamps[MAX_NR_GENS]; - /* the multi-gen LRU lists, lazily sorted on eviction */ - struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; - /* the multi-gen LRU sizes, eventually consistent */ ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4293,6 +4293,7 @@ static void inc_max_seq(struct lruvec *l - for (type = 0; type < ANON_AND_FILE; type++) - reset_ctrl_pos(lruvec, type, false); - -+ WRITE_ONCE(lrugen->timestamps[next], jiffies); - /* make sure preceding modifications appear */ - smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1); - -@@ -4420,7 +4421,7 @@ static bool should_run_aging(struct lruv - return false; - } - --static void age_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned long min_ttl) - { - bool need_aging; - unsigned long nr_to_scan; -@@ -4434,16 +4435,36 @@ static void age_lruvec(struct lruvec *lr - mem_cgroup_calculate_protection(NULL, memcg); - - if (mem_cgroup_below_min(memcg)) -- return; -+ return false; - - need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); -+ -+ if (min_ttl) { -+ int gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); -+ unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); -+ -+ if (time_is_after_jiffies(birth + min_ttl)) -+ return false; -+ -+ /* the size is likely too small to be helpful */ -+ if (!nr_to_scan && sc->priority != DEF_PRIORITY) -+ return false; -+ } -+ - if (need_aging) - try_to_inc_max_seq(lruvec, max_seq, sc, swappiness); -+ -+ return true; - } - -+/* to protect the working set of the last N jiffies */ -+static unsigned long lru_gen_min_ttl __read_mostly; -+ - static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) - { - struct mem_cgroup *memcg; -+ bool success = false; -+ unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl); - - VM_WARN_ON_ONCE(!current_is_kswapd()); - -@@ -4466,12 +4487,32 @@ static void lru_gen_age_node(struct pgli - do { - struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); - -- age_lruvec(lruvec, sc); -+ if (age_lruvec(lruvec, sc, min_ttl)) -+ success = true; - - cond_resched(); - } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); - - clear_mm_walk(); -+ -+ /* check the order to exclude compaction-induced reclaim */ -+ if (success || !min_ttl || sc->order) -+ return; -+ -+ /* -+ * The main goal is to OOM kill if every generation from all memcgs is -+ * younger than min_ttl. However, another possibility is all memcgs are -+ * either below min or empty. -+ */ -+ if (mutex_trylock(&oom_lock)) { -+ struct oom_control oc = { -+ .gfp_mask = sc->gfp_mask, -+ }; -+ -+ out_of_memory(&oc); -+ -+ mutex_unlock(&oom_lock); -+ } - } - - /* -@@ -5228,6 +5269,28 @@ unlock: - * sysfs interface - ******************************************************************************/ - -+static ssize_t show_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%u\n", jiffies_to_msecs(READ_ONCE(lru_gen_min_ttl))); -+} -+ -+static ssize_t store_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t len) -+{ -+ unsigned int msecs; -+ -+ if (kstrtouint(buf, 0, &msecs)) -+ return -EINVAL; -+ -+ WRITE_ONCE(lru_gen_min_ttl, msecs_to_jiffies(msecs)); -+ -+ return len; -+} -+ -+static struct kobj_attribute lru_gen_min_ttl_attr = __ATTR( -+ min_ttl_ms, 0644, show_min_ttl, store_min_ttl -+); -+ - static ssize_t show_enabled(struct kobject *kobj, struct kobj_attribute *attr, char *buf) - { - unsigned int caps = 0; -@@ -5276,6 +5339,7 @@ static struct kobj_attribute lru_gen_ena - ); - - static struct attribute *lru_gen_attrs[] = { -+ &lru_gen_min_ttl_attr.attr, - &lru_gen_enabled_attr.attr, - NULL - }; -@@ -5291,12 +5355,16 @@ static struct attribute_group lru_gen_at - - void lru_gen_init_lruvec(struct lruvec *lruvec) - { -+ int i; - int gen, type, zone; - struct lru_gen_struct *lrugen = &lruvec->lrugen; - - lrugen->max_seq = MIN_NR_GENS + 1; - lrugen->enabled = lru_gen_enabled(); - -+ for (i = 0; i <= MIN_NR_GENS + 1; i++) -+ lrugen->timestamps[i] = jiffies; -+ - for_each_gen_type_zone(gen, type, zone) - INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); - diff --git a/target/linux/generic/backport-6.0/111-mm-multi-gen-LRU-debugfs-interface.patch b/target/linux/generic/backport-6.0/111-mm-multi-gen-LRU-debugfs-interface.patch deleted file mode 100644 index 2c63332f9..000000000 --- a/target/linux/generic/backport-6.0/111-mm-multi-gen-LRU-debugfs-interface.patch +++ /dev/null @@ -1,557 +0,0 @@ -From d1e0e5fcdea16d4ceead496a0ea2fdbb6bc5bfe4 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Thu, 27 Jan 2022 20:12:41 -0700 -Subject: [PATCH 12/14] mm: multi-gen LRU: debugfs interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add /sys/kernel/debug/lru_gen for working set estimation and proactive -reclaim. These techniques are commonly used to optimize job scheduling -(bin packing) in data centers [1][2]. - -Compared with the page table-based approach and the PFN-based -approach, this lruvec-based approach has the following advantages: -1. It offers better choices because it is aware of memcgs, NUMA nodes, - shared mappings and unmapped page cache. -2. It is more scalable because it is O(nr_hot_pages), whereas the - PFN-based approach is O(nr_total_pages). - -Add /sys/kernel/debug/lru_gen_full for debugging. - -[1] https://dl.acm.org/doi/10.1145/3297858.3304053 -[2] https://dl.acm.org/doi/10.1145/3503222.3507731 - -Signed-off-by: Yu Zhao -Reviewed-by: Qi Zheng -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I7bb06f14e0a94901a076cc3767d0855d4f1ea3ab ---- - include/linux/nodemask.h | 1 + - mm/vmscan.c | 411 ++++++++++++++++++++++++++++++++++++++- - 2 files changed, 402 insertions(+), 10 deletions(-) - ---- a/include/linux/nodemask.h -+++ b/include/linux/nodemask.h -@@ -493,6 +493,7 @@ static inline int num_node_state(enum no - #define first_online_node 0 - #define first_memory_node 0 - #define next_online_node(nid) (MAX_NUMNODES) -+#define next_memory_node(nid) (MAX_NUMNODES) - #define nr_node_ids 1U - #define nr_online_nodes 1U - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -52,6 +52,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -4197,12 +4198,40 @@ static void clear_mm_walk(void) - kfree(walk); - } - --static void inc_min_seq(struct lruvec *lruvec, int type) -+static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap) - { -+ int zone; -+ int remaining = MAX_LRU_BATCH; - struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ if (type == LRU_GEN_ANON && !can_swap) -+ goto done; -+ -+ /* prevent cold/hot inversion if force_scan is true */ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) { -+ struct list_head *head = &lrugen->lists[old_gen][type][zone]; -+ -+ while (!list_empty(head)) { -+ struct folio *folio = lru_to_folio(head); -+ -+ VM_WARN_ON_ONCE_FOLIO(folio_test_unevictable(folio), folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_test_active(folio), folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_is_file_lru(folio) != type, folio); -+ VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio); - -+ new_gen = folio_inc_gen(lruvec, folio, false); -+ list_move_tail(&folio->lru, &lrugen->lists[new_gen][type][zone]); -+ -+ if (!--remaining) -+ return false; -+ } -+ } -+done: - reset_ctrl_pos(lruvec, type, true); - WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1); -+ -+ return true; - } - - static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap) -@@ -4248,7 +4277,7 @@ next: - return success; - } - --static void inc_max_seq(struct lruvec *lruvec, bool can_swap) -+static void inc_max_seq(struct lruvec *lruvec, bool can_swap, bool force_scan) - { - int prev, next; - int type, zone; -@@ -4262,9 +4291,13 @@ static void inc_max_seq(struct lruvec *l - if (get_nr_gens(lruvec, type) != MAX_NR_GENS) - continue; - -- VM_WARN_ON_ONCE(type == LRU_GEN_FILE || can_swap); -+ VM_WARN_ON_ONCE(!force_scan && (type == LRU_GEN_FILE || can_swap)); - -- inc_min_seq(lruvec, type); -+ while (!inc_min_seq(lruvec, type, can_swap)) { -+ spin_unlock_irq(&lruvec->lru_lock); -+ cond_resched(); -+ spin_lock_irq(&lruvec->lru_lock); -+ } - } - - /* -@@ -4301,7 +4334,7 @@ static void inc_max_seq(struct lruvec *l - } - - static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, -- struct scan_control *sc, bool can_swap) -+ struct scan_control *sc, bool can_swap, bool force_scan) - { - bool success; - struct lru_gen_mm_walk *walk; -@@ -4322,7 +4355,7 @@ static bool try_to_inc_max_seq(struct lr - * handful of PTEs. Spreading the work out over a period of time usually - * is less efficient, but it avoids bursty page faults. - */ -- if (!(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { -+ if (!force_scan && !(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { - success = iterate_mm_list_nowalk(lruvec, max_seq); - goto done; - } -@@ -4336,7 +4369,7 @@ static bool try_to_inc_max_seq(struct lr - walk->lruvec = lruvec; - walk->max_seq = max_seq; - walk->can_swap = can_swap; -- walk->force_scan = false; -+ walk->force_scan = force_scan; - - do { - success = iterate_mm_list(lruvec, walk, &mm); -@@ -4356,7 +4389,7 @@ done: - - VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); - -- inc_max_seq(lruvec, can_swap); -+ inc_max_seq(lruvec, can_swap, force_scan); - /* either this sees any waiters or they will see updated max_seq */ - if (wq_has_sleeper(&lruvec->mm_state.wait)) - wake_up_all(&lruvec->mm_state.wait); -@@ -4452,7 +4485,7 @@ static bool age_lruvec(struct lruvec *lr - } - - if (need_aging) -- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness); -+ try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false); - - return true; - } -@@ -5011,7 +5044,7 @@ static unsigned long get_nr_to_scan(stru - if (current_is_kswapd()) - return 0; - -- if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap)) -+ if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false)) - return nr_to_scan; - done: - return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; -@@ -5350,6 +5383,361 @@ static struct attribute_group lru_gen_at - }; - - /****************************************************************************** -+ * debugfs interface -+ ******************************************************************************/ -+ -+static void *lru_gen_seq_start(struct seq_file *m, loff_t *pos) -+{ -+ struct mem_cgroup *memcg; -+ loff_t nr_to_skip = *pos; -+ -+ m->private = kvmalloc(PATH_MAX, GFP_KERNEL); -+ if (!m->private) -+ return ERR_PTR(-ENOMEM); -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ int nid; -+ -+ for_each_node_state(nid, N_MEMORY) { -+ if (!nr_to_skip--) -+ return get_lruvec(memcg, nid); -+ } -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+ -+ return NULL; -+} -+ -+static void lru_gen_seq_stop(struct seq_file *m, void *v) -+{ -+ if (!IS_ERR_OR_NULL(v)) -+ mem_cgroup_iter_break(NULL, lruvec_memcg(v)); -+ -+ kvfree(m->private); -+ m->private = NULL; -+} -+ -+static void *lru_gen_seq_next(struct seq_file *m, void *v, loff_t *pos) -+{ -+ int nid = lruvec_pgdat(v)->node_id; -+ struct mem_cgroup *memcg = lruvec_memcg(v); -+ -+ ++*pos; -+ -+ nid = next_memory_node(nid); -+ if (nid == MAX_NUMNODES) { -+ memcg = mem_cgroup_iter(NULL, memcg, NULL); -+ if (!memcg) -+ return NULL; -+ -+ nid = first_memory_node; -+ } -+ -+ return get_lruvec(memcg, nid); -+} -+ -+static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec, -+ unsigned long max_seq, unsigned long *min_seq, -+ unsigned long seq) -+{ -+ int i; -+ int type, tier; -+ int hist = lru_hist_from_seq(seq); -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ for (tier = 0; tier < MAX_NR_TIERS; tier++) { -+ seq_printf(m, " %10d", tier); -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ const char *s = " "; -+ unsigned long n[3] = {}; -+ -+ if (seq == max_seq) { -+ s = "RT "; -+ n[0] = READ_ONCE(lrugen->avg_refaulted[type][tier]); -+ n[1] = READ_ONCE(lrugen->avg_total[type][tier]); -+ } else if (seq == min_seq[type] || NR_HIST_GENS > 1) { -+ s = "rep"; -+ n[0] = atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ n[1] = atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ n[2] = READ_ONCE(lrugen->protected[hist][type][tier - 1]); -+ } -+ -+ for (i = 0; i < 3; i++) -+ seq_printf(m, " %10lu%c", n[i], s[i]); -+ } -+ seq_putc(m, '\n'); -+ } -+ -+ seq_puts(m, " "); -+ for (i = 0; i < NR_MM_STATS; i++) { -+ const char *s = " "; -+ unsigned long n = 0; -+ -+ if (seq == max_seq && NR_HIST_GENS == 1) { -+ s = "LOYNFA"; -+ n = READ_ONCE(lruvec->mm_state.stats[hist][i]); -+ } else if (seq != max_seq && NR_HIST_GENS > 1) { -+ s = "loynfa"; -+ n = READ_ONCE(lruvec->mm_state.stats[hist][i]); -+ } -+ -+ seq_printf(m, " %10lu%c", n, s[i]); -+ } -+ seq_putc(m, '\n'); -+} -+ -+static int lru_gen_seq_show(struct seq_file *m, void *v) -+{ -+ unsigned long seq; -+ bool full = !debugfs_real_fops(m->file)->write; -+ struct lruvec *lruvec = v; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ int nid = lruvec_pgdat(lruvec)->node_id; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (nid == first_memory_node) { -+ const char *path = memcg ? m->private : ""; -+ -+#ifdef CONFIG_MEMCG -+ if (memcg) -+ cgroup_path(memcg->css.cgroup, m->private, PATH_MAX); -+#endif -+ seq_printf(m, "memcg %5hu %s\n", mem_cgroup_id(memcg), path); -+ } -+ -+ seq_printf(m, " node %5d\n", nid); -+ -+ if (!full) -+ seq = min_seq[LRU_GEN_ANON]; -+ else if (max_seq >= MAX_NR_GENS) -+ seq = max_seq - MAX_NR_GENS + 1; -+ else -+ seq = 0; -+ -+ for (; seq <= max_seq; seq++) { -+ int type, zone; -+ int gen = lru_gen_from_seq(seq); -+ unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); -+ -+ seq_printf(m, " %10lu %10u", seq, jiffies_to_msecs(jiffies - birth)); -+ -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ unsigned long size = 0; -+ char mark = full && seq < min_seq[type] ? 'x' : ' '; -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -+ -+ seq_printf(m, " %10lu%c", size, mark); -+ } -+ -+ seq_putc(m, '\n'); -+ -+ if (full) -+ lru_gen_seq_show_full(m, lruvec, max_seq, min_seq, seq); -+ } -+ -+ return 0; -+} -+ -+static const struct seq_operations lru_gen_seq_ops = { -+ .start = lru_gen_seq_start, -+ .stop = lru_gen_seq_stop, -+ .next = lru_gen_seq_next, -+ .show = lru_gen_seq_show, -+}; -+ -+static int run_aging(struct lruvec *lruvec, unsigned long seq, struct scan_control *sc, -+ bool can_swap, bool force_scan) -+{ -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (seq < max_seq) -+ return 0; -+ -+ if (seq > max_seq) -+ return -EINVAL; -+ -+ if (!force_scan && min_seq[!can_swap] + MAX_NR_GENS - 1 <= max_seq) -+ return -ERANGE; -+ -+ try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, force_scan); -+ -+ return 0; -+} -+ -+static int run_eviction(struct lruvec *lruvec, unsigned long seq, struct scan_control *sc, -+ int swappiness, unsigned long nr_to_reclaim) -+{ -+ DEFINE_MAX_SEQ(lruvec); -+ -+ if (seq + MIN_NR_GENS > max_seq) -+ return -EINVAL; -+ -+ sc->nr_reclaimed = 0; -+ -+ while (!signal_pending(current)) { -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (seq < min_seq[!swappiness]) -+ return 0; -+ -+ if (sc->nr_reclaimed >= nr_to_reclaim) -+ return 0; -+ -+ if (!evict_folios(lruvec, sc, swappiness, NULL)) -+ return 0; -+ -+ cond_resched(); -+ } -+ -+ return -EINTR; -+} -+ -+static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq, -+ struct scan_control *sc, int swappiness, unsigned long opt) -+{ -+ struct lruvec *lruvec; -+ int err = -EINVAL; -+ struct mem_cgroup *memcg = NULL; -+ -+ if (nid < 0 || nid >= MAX_NUMNODES || !node_state(nid, N_MEMORY)) -+ return -EINVAL; -+ -+ if (!mem_cgroup_disabled()) { -+ rcu_read_lock(); -+ memcg = mem_cgroup_from_id(memcg_id); -+#ifdef CONFIG_MEMCG -+ if (memcg && !css_tryget(&memcg->css)) -+ memcg = NULL; -+#endif -+ rcu_read_unlock(); -+ -+ if (!memcg) -+ return -EINVAL; -+ } -+ -+ if (memcg_id != mem_cgroup_id(memcg)) -+ goto done; -+ -+ lruvec = get_lruvec(memcg, nid); -+ -+ if (swappiness < 0) -+ swappiness = get_swappiness(lruvec, sc); -+ else if (swappiness > 200) -+ goto done; -+ -+ switch (cmd) { -+ case '+': -+ err = run_aging(lruvec, seq, sc, swappiness, opt); -+ break; -+ case '-': -+ err = run_eviction(lruvec, seq, sc, swappiness, opt); -+ break; -+ } -+done: -+ mem_cgroup_put(memcg); -+ -+ return err; -+} -+ -+static ssize_t lru_gen_seq_write(struct file *file, const char __user *src, -+ size_t len, loff_t *pos) -+{ -+ void *buf; -+ char *cur, *next; -+ unsigned int flags; -+ struct blk_plug plug; -+ int err = -EINVAL; -+ struct scan_control sc = { -+ .may_writepage = true, -+ .may_unmap = true, -+ .may_swap = true, -+ .reclaim_idx = MAX_NR_ZONES - 1, -+ .gfp_mask = GFP_KERNEL, -+ }; -+ -+ buf = kvmalloc(len + 1, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (copy_from_user(buf, src, len)) { -+ kvfree(buf); -+ return -EFAULT; -+ } -+ -+ set_task_reclaim_state(current, &sc.reclaim_state); -+ flags = memalloc_noreclaim_save(); -+ blk_start_plug(&plug); -+ if (!set_mm_walk(NULL)) { -+ err = -ENOMEM; -+ goto done; -+ } -+ -+ next = buf; -+ next[len] = '\0'; -+ -+ while ((cur = strsep(&next, ",;\n"))) { -+ int n; -+ int end; -+ char cmd; -+ unsigned int memcg_id; -+ unsigned int nid; -+ unsigned long seq; -+ unsigned int swappiness = -1; -+ unsigned long opt = -1; -+ -+ cur = skip_spaces(cur); -+ if (!*cur) -+ continue; -+ -+ n = sscanf(cur, "%c %u %u %lu %n %u %n %lu %n", &cmd, &memcg_id, &nid, -+ &seq, &end, &swappiness, &end, &opt, &end); -+ if (n < 4 || cur[end]) { -+ err = -EINVAL; -+ break; -+ } -+ -+ err = run_cmd(cmd, memcg_id, nid, seq, &sc, swappiness, opt); -+ if (err) -+ break; -+ } -+done: -+ clear_mm_walk(); -+ blk_finish_plug(&plug); -+ memalloc_noreclaim_restore(flags); -+ set_task_reclaim_state(current, NULL); -+ -+ kvfree(buf); -+ -+ return err ? : len; -+} -+ -+static int lru_gen_seq_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &lru_gen_seq_ops); -+} -+ -+static const struct file_operations lru_gen_rw_fops = { -+ .open = lru_gen_seq_open, -+ .read = seq_read, -+ .write = lru_gen_seq_write, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+static const struct file_operations lru_gen_ro_fops = { -+ .open = lru_gen_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+/****************************************************************************** - * initialization - ******************************************************************************/ - -@@ -5406,6 +5794,9 @@ static int __init init_lru_gen(void) - if (sysfs_create_group(mm_kobj, &lru_gen_attr_group)) - pr_err("lru_gen: failed to create sysfs group\n"); - -+ debugfs_create_file("lru_gen", 0644, NULL, NULL, &lru_gen_rw_fops); -+ debugfs_create_file("lru_gen_full", 0444, NULL, NULL, &lru_gen_ro_fops); -+ - return 0; - }; - late_initcall(init_lru_gen); diff --git a/target/linux/generic/backport-6.0/112-mm-multi-gen-LRU-admin-guide.patch b/target/linux/generic/backport-6.0/112-mm-multi-gen-LRU-admin-guide.patch deleted file mode 100644 index bbf418b84..000000000 --- a/target/linux/generic/backport-6.0/112-mm-multi-gen-LRU-admin-guide.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 22199c9b30ffcc332be643577709a2af960e6786 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 23 Jan 2022 16:44:43 -0700 -Subject: [PATCH 13/14] mm: multi-gen LRU: admin guide -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add an admin guide. - -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I1902178bcbb5adfa0a748c4d284a6456059bdd7e ---- - Documentation/admin-guide/mm/index.rst | 1 + - Documentation/admin-guide/mm/multigen_lru.rst | 162 ++++++++++++++++++ - mm/Kconfig | 3 +- - mm/vmscan.c | 4 + - 4 files changed, 169 insertions(+), 1 deletion(-) - create mode 100644 Documentation/admin-guide/mm/multigen_lru.rst - ---- a/Documentation/admin-guide/mm/index.rst -+++ b/Documentation/admin-guide/mm/index.rst -@@ -32,6 +32,7 @@ the Linux memory management. - idle_page_tracking - ksm - memory-hotplug -+ multigen_lru - nommu-mmap - numa_memory_policy - numaperf ---- /dev/null -+++ b/Documentation/admin-guide/mm/multigen_lru.rst -@@ -0,0 +1,162 @@ -+.. SPDX-License-Identifier: GPL-2.0 -+ -+============= -+Multi-Gen LRU -+============= -+The multi-gen LRU is an alternative LRU implementation that optimizes -+page reclaim and improves performance under memory pressure. Page -+reclaim decides the kernel's caching policy and ability to overcommit -+memory. It directly impacts the kswapd CPU usage and RAM efficiency. -+ -+Quick start -+=========== -+Build the kernel with the following configurations. -+ -+* ``CONFIG_LRU_GEN=y`` -+* ``CONFIG_LRU_GEN_ENABLED=y`` -+ -+All set! -+ -+Runtime options -+=============== -+``/sys/kernel/mm/lru_gen/`` contains stable ABIs described in the -+following subsections. -+ -+Kill switch -+----------- -+``enabled`` accepts different values to enable or disable the -+following components. Its default value depends on -+``CONFIG_LRU_GEN_ENABLED``. All the components should be enabled -+unless some of them have unforeseen side effects. Writing to -+``enabled`` has no effect when a component is not supported by the -+hardware, and valid values will be accepted even when the main switch -+is off. -+ -+====== =============================================================== -+Values Components -+====== =============================================================== -+0x0001 The main switch for the multi-gen LRU. -+0x0002 Clearing the accessed bit in leaf page table entries in large -+ batches, when MMU sets it (e.g., on x86). This behavior can -+ theoretically worsen lock contention (mmap_lock). If it is -+ disabled, the multi-gen LRU will suffer a minor performance -+ degradation for workloads that contiguously map hot pages, -+ whose accessed bits can be otherwise cleared by fewer larger -+ batches. -+0x0004 Clearing the accessed bit in non-leaf page table entries as -+ well, when MMU sets it (e.g., on x86). This behavior was not -+ verified on x86 varieties other than Intel and AMD. If it is -+ disabled, the multi-gen LRU will suffer a negligible -+ performance degradation. -+[yYnN] Apply to all the components above. -+====== =============================================================== -+ -+E.g., -+:: -+ -+ echo y >/sys/kernel/mm/lru_gen/enabled -+ cat /sys/kernel/mm/lru_gen/enabled -+ 0x0007 -+ echo 5 >/sys/kernel/mm/lru_gen/enabled -+ cat /sys/kernel/mm/lru_gen/enabled -+ 0x0005 -+ -+Thrashing prevention -+-------------------- -+Personal computers are more sensitive to thrashing because it can -+cause janks (lags when rendering UI) and negatively impact user -+experience. The multi-gen LRU offers thrashing prevention to the -+majority of laptop and desktop users who do not have ``oomd``. -+ -+Users can write ``N`` to ``min_ttl_ms`` to prevent the working set of -+``N`` milliseconds from getting evicted. The OOM killer is triggered -+if this working set cannot be kept in memory. In other words, this -+option works as an adjustable pressure relief valve, and when open, it -+terminates applications that are hopefully not being used. -+ -+Based on the average human detectable lag (~100ms), ``N=1000`` usually -+eliminates intolerable janks due to thrashing. Larger values like -+``N=3000`` make janks less noticeable at the risk of premature OOM -+kills. -+ -+The default value ``0`` means disabled. -+ -+Experimental features -+===================== -+``/sys/kernel/debug/lru_gen`` accepts commands described in the -+following subsections. Multiple command lines are supported, so does -+concatenation with delimiters ``,`` and ``;``. -+ -+``/sys/kernel/debug/lru_gen_full`` provides additional stats for -+debugging. ``CONFIG_LRU_GEN_STATS=y`` keeps historical stats from -+evicted generations in this file. -+ -+Working set estimation -+---------------------- -+Working set estimation measures how much memory an application needs -+in a given time interval, and it is usually done with little impact on -+the performance of the application. E.g., data centers want to -+optimize job scheduling (bin packing) to improve memory utilizations. -+When a new job comes in, the job scheduler needs to find out whether -+each server it manages can allocate a certain amount of memory for -+this new job before it can pick a candidate. To do so, the job -+scheduler needs to estimate the working sets of the existing jobs. -+ -+When it is read, ``lru_gen`` returns a histogram of numbers of pages -+accessed over different time intervals for each memcg and node. -+``MAX_NR_GENS`` decides the number of bins for each histogram. The -+histograms are noncumulative. -+:: -+ -+ memcg memcg_id memcg_path -+ node node_id -+ min_gen_nr age_in_ms nr_anon_pages nr_file_pages -+ ... -+ max_gen_nr age_in_ms nr_anon_pages nr_file_pages -+ -+Each bin contains an estimated number of pages that have been accessed -+within ``age_in_ms``. E.g., ``min_gen_nr`` contains the coldest pages -+and ``max_gen_nr`` contains the hottest pages, since ``age_in_ms`` of -+the former is the largest and that of the latter is the smallest. -+ -+Users can write the following command to ``lru_gen`` to create a new -+generation ``max_gen_nr+1``: -+ -+ ``+ memcg_id node_id max_gen_nr [can_swap [force_scan]]`` -+ -+``can_swap`` defaults to the swap setting and, if it is set to ``1``, -+it forces the scan of anon pages when swap is off, and vice versa. -+``force_scan`` defaults to ``1`` and, if it is set to ``0``, it -+employs heuristics to reduce the overhead, which is likely to reduce -+the coverage as well. -+ -+A typical use case is that a job scheduler runs this command at a -+certain time interval to create new generations, and it ranks the -+servers it manages based on the sizes of their cold pages defined by -+this time interval. -+ -+Proactive reclaim -+----------------- -+Proactive reclaim induces page reclaim when there is no memory -+pressure. It usually targets cold pages only. E.g., when a new job -+comes in, the job scheduler wants to proactively reclaim cold pages on -+the server it selected, to improve the chance of successfully landing -+this new job. -+ -+Users can write the following command to ``lru_gen`` to evict -+generations less than or equal to ``min_gen_nr``. -+ -+ ``- memcg_id node_id min_gen_nr [swappiness [nr_to_reclaim]]`` -+ -+``min_gen_nr`` should be less than ``max_gen_nr-1``, since -+``max_gen_nr`` and ``max_gen_nr-1`` are not fully aged (equivalent to -+the active list) and therefore cannot be evicted. ``swappiness`` -+overrides the default value in ``/proc/sys/vm/swappiness``. -+``nr_to_reclaim`` limits the number of pages to evict. -+ -+A typical use case is that a job scheduler runs this command before it -+tries to land a new job on a server. If it fails to materialize enough -+cold pages because of the overestimation, it retries on the next -+server according to the ranking result obtained from the working set -+estimation step. This less forceful approach limits the impacts on the -+existing jobs. ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -1131,7 +1131,8 @@ config LRU_GEN - # make sure folio->flags has enough spare bits - depends on 64BIT || !SPARSEMEM || SPARSEMEM_VMEMMAP - help -- A high performance LRU implementation to overcommit memory. -+ A high performance LRU implementation to overcommit memory. See -+ Documentation/admin-guide/mm/multigen_lru.rst for details. - - config LRU_GEN_ENABLED - bool "Enable by default" ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -5307,6 +5307,7 @@ static ssize_t show_min_ttl(struct kobje - return sprintf(buf, "%u\n", jiffies_to_msecs(READ_ONCE(lru_gen_min_ttl))); - } - -+/* see Documentation/admin-guide/mm/multigen_lru.rst for details */ - static ssize_t store_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t len) - { -@@ -5340,6 +5341,7 @@ static ssize_t show_enabled(struct kobje - return snprintf(buf, PAGE_SIZE, "0x%04x\n", caps); - } - -+/* see Documentation/admin-guide/mm/multigen_lru.rst for details */ - static ssize_t store_enabled(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t len) - { -@@ -5487,6 +5489,7 @@ static void lru_gen_seq_show_full(struct - seq_putc(m, '\n'); - } - -+/* see Documentation/admin-guide/mm/multigen_lru.rst for details */ - static int lru_gen_seq_show(struct seq_file *m, void *v) - { - unsigned long seq; -@@ -5645,6 +5648,7 @@ done: - return err; - } - -+/* see Documentation/admin-guide/mm/multigen_lru.rst for details */ - static ssize_t lru_gen_seq_write(struct file *file, const char __user *src, - size_t len, loff_t *pos) - { diff --git a/target/linux/generic/backport-6.0/113-mm-multi-gen-LRU-design-doc.patch b/target/linux/generic/backport-6.0/113-mm-multi-gen-LRU-design-doc.patch deleted file mode 100644 index bf1dc061c..000000000 --- a/target/linux/generic/backport-6.0/113-mm-multi-gen-LRU-design-doc.patch +++ /dev/null @@ -1,202 +0,0 @@ -From bd82a74f6b5c0a75ef61be5e9be34319bb17328f Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 6 Mar 2022 20:35:00 -0700 -Subject: [PATCH 14/14] mm: multi-gen LRU: design doc -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a design doc. - -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Change-Id: I958afcabf5abc37b3e58f72638d35a349c31b98d ---- - Documentation/mm/index.rst | 1 + - Documentation/mm/multigen_lru.rst | 159 ++++++++++++++++++++++++++++++ - 2 files changed, 160 insertions(+) - create mode 100644 Documentation/mm/multigen_lru.rst - ---- a/Documentation/mm/index.rst -+++ b/Documentation/mm/index.rst -@@ -51,6 +51,7 @@ above structured documentation, or delet - ksm - memory-model - mmu_notifier -+ multigen_lru - numa - overcommit-accounting - page_migration ---- /dev/null -+++ b/Documentation/mm/multigen_lru.rst -@@ -0,0 +1,159 @@ -+.. SPDX-License-Identifier: GPL-2.0 -+ -+============= -+Multi-Gen LRU -+============= -+The multi-gen LRU is an alternative LRU implementation that optimizes -+page reclaim and improves performance under memory pressure. Page -+reclaim decides the kernel's caching policy and ability to overcommit -+memory. It directly impacts the kswapd CPU usage and RAM efficiency. -+ -+Design overview -+=============== -+Objectives -+---------- -+The design objectives are: -+ -+* Good representation of access recency -+* Try to profit from spatial locality -+* Fast paths to make obvious choices -+* Simple self-correcting heuristics -+ -+The representation of access recency is at the core of all LRU -+implementations. In the multi-gen LRU, each generation represents a -+group of pages with similar access recency. Generations establish a -+(time-based) common frame of reference and therefore help make better -+choices, e.g., between different memcgs on a computer or different -+computers in a data center (for job scheduling). -+ -+Exploiting spatial locality improves efficiency when gathering the -+accessed bit. A rmap walk targets a single page and does not try to -+profit from discovering a young PTE. A page table walk can sweep all -+the young PTEs in an address space, but the address space can be too -+sparse to make a profit. The key is to optimize both methods and use -+them in combination. -+ -+Fast paths reduce code complexity and runtime overhead. Unmapped pages -+do not require TLB flushes; clean pages do not require writeback. -+These facts are only helpful when other conditions, e.g., access -+recency, are similar. With generations as a common frame of reference, -+additional factors stand out. But obvious choices might not be good -+choices; thus self-correction is necessary. -+ -+The benefits of simple self-correcting heuristics are self-evident. -+Again, with generations as a common frame of reference, this becomes -+attainable. Specifically, pages in the same generation can be -+categorized based on additional factors, and a feedback loop can -+statistically compare the refault percentages across those categories -+and infer which of them are better choices. -+ -+Assumptions -+----------- -+The protection of hot pages and the selection of cold pages are based -+on page access channels and patterns. There are two access channels: -+ -+* Accesses through page tables -+* Accesses through file descriptors -+ -+The protection of the former channel is by design stronger because: -+ -+1. The uncertainty in determining the access patterns of the former -+ channel is higher due to the approximation of the accessed bit. -+2. The cost of evicting the former channel is higher due to the TLB -+ flushes required and the likelihood of encountering the dirty bit. -+3. The penalty of underprotecting the former channel is higher because -+ applications usually do not prepare themselves for major page -+ faults like they do for blocked I/O. E.g., GUI applications -+ commonly use dedicated I/O threads to avoid blocking rendering -+ threads. -+ -+There are also two access patterns: -+ -+* Accesses exhibiting temporal locality -+* Accesses not exhibiting temporal locality -+ -+For the reasons listed above, the former channel is assumed to follow -+the former pattern unless ``VM_SEQ_READ`` or ``VM_RAND_READ`` is -+present, and the latter channel is assumed to follow the latter -+pattern unless outlying refaults have been observed. -+ -+Workflow overview -+================= -+Evictable pages are divided into multiple generations for each -+``lruvec``. The youngest generation number is stored in -+``lrugen->max_seq`` for both anon and file types as they are aged on -+an equal footing. The oldest generation numbers are stored in -+``lrugen->min_seq[]`` separately for anon and file types as clean file -+pages can be evicted regardless of swap constraints. These three -+variables are monotonically increasing. -+ -+Generation numbers are truncated into ``order_base_2(MAX_NR_GENS+1)`` -+bits in order to fit into the gen counter in ``folio->flags``. Each -+truncated generation number is an index to ``lrugen->lists[]``. The -+sliding window technique is used to track at least ``MIN_NR_GENS`` and -+at most ``MAX_NR_GENS`` generations. The gen counter stores a value -+within ``[1, MAX_NR_GENS]`` while a page is on one of -+``lrugen->lists[]``; otherwise it stores zero. -+ -+Each generation is divided into multiple tiers. A page accessed ``N`` -+times through file descriptors is in tier ``order_base_2(N)``. Unlike -+generations, tiers do not have dedicated ``lrugen->lists[]``. In -+contrast to moving across generations, which requires the LRU lock, -+moving across tiers only involves atomic operations on -+``folio->flags`` and therefore has a negligible cost. A feedback loop -+modeled after the PID controller monitors refaults over all the tiers -+from anon and file types and decides which tiers from which types to -+evict or protect. -+ -+There are two conceptually independent procedures: the aging and the -+eviction. They form a closed-loop system, i.e., the page reclaim. -+ -+Aging -+----- -+The aging produces young generations. Given an ``lruvec``, it -+increments ``max_seq`` when ``max_seq-min_seq+1`` approaches -+``MIN_NR_GENS``. The aging promotes hot pages to the youngest -+generation when it finds them accessed through page tables; the -+demotion of cold pages happens consequently when it increments -+``max_seq``. The aging uses page table walks and rmap walks to find -+young PTEs. For the former, it iterates ``lruvec_memcg()->mm_list`` -+and calls ``walk_page_range()`` with each ``mm_struct`` on this list -+to scan PTEs, and after each iteration, it increments ``max_seq``. For -+the latter, when the eviction walks the rmap and finds a young PTE, -+the aging scans the adjacent PTEs. For both, on finding a young PTE, -+the aging clears the accessed bit and updates the gen counter of the -+page mapped by this PTE to ``(max_seq%MAX_NR_GENS)+1``. -+ -+Eviction -+-------- -+The eviction consumes old generations. Given an ``lruvec``, it -+increments ``min_seq`` when ``lrugen->lists[]`` indexed by -+``min_seq%MAX_NR_GENS`` becomes empty. To select a type and a tier to -+evict from, it first compares ``min_seq[]`` to select the older type. -+If both types are equally old, it selects the one whose first tier has -+a lower refault percentage. The first tier contains single-use -+unmapped clean pages, which are the best bet. The eviction sorts a -+page according to its gen counter if the aging has found this page -+accessed through page tables and updated its gen counter. It also -+moves a page to the next generation, i.e., ``min_seq+1``, if this page -+was accessed multiple times through file descriptors and the feedback -+loop has detected outlying refaults from the tier this page is in. To -+this end, the feedback loop uses the first tier as the baseline, for -+the reason stated earlier. -+ -+Summary -+------- -+The multi-gen LRU can be disassembled into the following parts: -+ -+* Generations -+* Rmap walks -+* Page table walks -+* Bloom filters -+* PID controller -+ -+The aging and the eviction form a producer-consumer model; -+specifically, the latter drives the former by the sliding window over -+generations. Within the aging, rmap walks drive page table walks by -+inserting hot densely populated page tables to the Bloom filters. -+Within the eviction, the PID controller uses refaults as the feedback -+to select types to evict and tiers to protect. diff --git a/target/linux/generic/backport-6.1/100-net-add-netdev_sw_irq_coalesce_default_on.patch b/target/linux/generic/backport-6.1/100-net-add-netdev_sw_irq_coalesce_default_on.patch new file mode 100644 index 000000000..f3ada6abc --- /dev/null +++ b/target/linux/generic/backport-6.1/100-net-add-netdev_sw_irq_coalesce_default_on.patch @@ -0,0 +1,59 @@ +From e9aef3d90b4bd11fccbde3741f2396ea05a9f386 Mon Sep 17 00:00:00 2001 +From: Heiner Kallweit +Date: Wed, 30 Nov 2022 23:28:26 +0100 +Subject: [PATCH] net: add netdev_sw_irq_coalesce_default_on() + +Add a helper for drivers wanting to set SW IRQ coalescing +by default. The related sysfs attributes can be used to +override the default values. + +Follow Jakub's suggestion and put this functionality into +net core so that drivers wanting to use software interrupt +coalescing per default don't have to open-code it. + +Note that this function needs to be called before the +netdevice is registered. + +Suggested-by: Jakub Kicinski +Signed-off-by: Heiner Kallweit +Signed-off-by: David S. Miller +--- + include/linux/netdevice.h | 1 + + net/core/dev.c | 16 ++++++++++++++++ + 2 files changed, 17 insertions(+) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -78,6 +78,7 @@ struct xdp_buff; + void synchronize_net(void); + void netdev_set_default_ethtool_ops(struct net_device *dev, + const struct ethtool_ops *ops); ++void netdev_sw_irq_coalesce_default_on(struct net_device *dev); + + /* Backlog congestion levels */ + #define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -10535,6 +10535,22 @@ void netdev_set_default_ethtool_ops(stru + } + EXPORT_SYMBOL_GPL(netdev_set_default_ethtool_ops); + ++/** ++ * netdev_sw_irq_coalesce_default_on() - enable SW IRQ coalescing by default ++ * @dev: netdev to enable the IRQ coalescing on ++ * ++ * Sets a conservative default for SW IRQ coalescing. Users can use ++ * sysfs attributes to override the default values. ++ */ ++void netdev_sw_irq_coalesce_default_on(struct net_device *dev) ++{ ++ WARN_ON(dev->reg_state == NETREG_REGISTERED); ++ ++ dev->gro_flush_timeout = 20000; ++ dev->napi_defer_hard_irqs = 1; ++} ++EXPORT_SYMBOL_GPL(netdev_sw_irq_coalesce_default_on); ++ + void netdev_freemem(struct net_device *dev) + { + char *addr = (char *)dev - dev->padded; diff --git a/target/linux/generic/backport-6.1/101-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch b/target/linux/generic/backport-6.1/101-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch new file mode 100644 index 000000000..4b4f42acf --- /dev/null +++ b/target/linux/generic/backport-6.1/101-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch @@ -0,0 +1,2022 @@ +From 7517d0e76196beffd845985612570b5f3f6f6d9b Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Wed, 26 Oct 2022 15:22:14 +0200 +Subject: [PATCH 1/4] net: Remove the obsolte u64_stats_fetch_*_irq() users + (drivers). + +Now that the 32bit UP oddity is gone and 32bit uses always a sequence +count, there is no need for the fetch_irq() variants anymore. + +Convert to the regular interface. + +Signed-off-by: Thomas Gleixner +Signed-off-by: Sebastian Andrzej Siewior +Acked-by: Peter Zijlstra (Intel) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/alacritech/slic.h | 12 +++---- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 4 +-- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 12 +++---- + .../net/ethernet/aquantia/atlantic/aq_ring.c | 8 ++--- + drivers/net/ethernet/asix/ax88796c_main.c | 4 +-- + drivers/net/ethernet/broadcom/b44.c | 8 ++--- + drivers/net/ethernet/broadcom/bcmsysport.c | 12 +++---- + drivers/net/ethernet/cortina/gemini.c | 24 +++++++------- + .../net/ethernet/emulex/benet/be_ethtool.c | 12 +++---- + drivers/net/ethernet/emulex/benet/be_main.c | 16 +++++----- + .../ethernet/fungible/funeth/funeth_txrx.h | 4 +-- + drivers/net/ethernet/google/gve/gve_ethtool.c | 16 +++++----- + drivers/net/ethernet/google/gve/gve_main.c | 12 +++---- + .../net/ethernet/hisilicon/hns3/hns3_enet.c | 4 +-- + drivers/net/ethernet/huawei/hinic/hinic_rx.c | 4 +-- + drivers/net/ethernet/huawei/hinic/hinic_tx.c | 4 +-- + .../net/ethernet/intel/fm10k/fm10k_netdev.c | 8 ++--- + .../net/ethernet/intel/i40e/i40e_ethtool.c | 8 ++--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 20 ++++++------ + .../net/ethernet/intel/iavf/iavf_ethtool.c | 8 ++--- + drivers/net/ethernet/intel/ice/ice_main.c | 4 +-- + drivers/net/ethernet/intel/igb/igb_ethtool.c | 12 +++---- + drivers/net/ethernet/intel/igb/igb_main.c | 8 ++--- + drivers/net/ethernet/intel/igc/igc_ethtool.c | 12 +++---- + drivers/net/ethernet/intel/igc/igc_main.c | 8 ++--- + .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 8 ++--- + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++--- + drivers/net/ethernet/intel/ixgbevf/ethtool.c | 12 +++---- + .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 8 ++--- + drivers/net/ethernet/marvell/mvneta.c | 8 ++--- + .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 8 ++--- + drivers/net/ethernet/marvell/sky2.c | 8 ++--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++--- + .../net/ethernet/mellanox/mlxsw/spectrum.c | 4 +-- + drivers/net/ethernet/microsoft/mana/mana_en.c | 8 ++--- + .../ethernet/microsoft/mana/mana_ethtool.c | 8 ++--- + .../ethernet/netronome/nfp/nfp_net_common.c | 8 ++--- + .../ethernet/netronome/nfp/nfp_net_ethtool.c | 8 ++--- + .../net/ethernet/netronome/nfp/nfp_net_repr.c | 4 +-- + drivers/net/ethernet/nvidia/forcedeth.c | 8 ++--- + .../net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 4 +-- + drivers/net/ethernet/realtek/8139too.c | 8 ++--- + drivers/net/ethernet/socionext/sni_ave.c | 8 ++--- + drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 +-- + drivers/net/ethernet/ti/netcp_core.c | 8 ++--- + drivers/net/ethernet/via/via-rhine.c | 8 ++--- + .../net/ethernet/xilinx/xilinx_axienet_main.c | 8 ++--- + drivers/net/hyperv/netvsc_drv.c | 32 +++++++++---------- + drivers/net/ifb.c | 12 +++---- + drivers/net/ipvlan/ipvlan_main.c | 4 +-- + drivers/net/loopback.c | 4 +-- + drivers/net/macsec.c | 12 +++---- + drivers/net/macvlan.c | 4 +-- + drivers/net/mhi_net.c | 8 ++--- + drivers/net/netdevsim/netdev.c | 4 +-- + drivers/net/team/team.c | 4 +-- + drivers/net/team/team_mode_loadbalance.c | 4 +-- + drivers/net/veth.c | 12 +++---- + drivers/net/virtio_net.c | 16 +++++----- + drivers/net/vrf.c | 4 +-- + drivers/net/vxlan/vxlan_vnifilter.c | 4 +-- + drivers/net/wwan/mhi_wwan_mbim.c | 8 ++--- + drivers/net/xen-netfront.c | 8 ++--- + 63 files changed, 274 insertions(+), 274 deletions(-) + +--- a/drivers/net/ethernet/alacritech/slic.h ++++ b/drivers/net/ethernet/alacritech/slic.h +@@ -288,13 +288,13 @@ do { \ + u64_stats_update_end(&(st)->syncp); \ + } while (0) + +-#define SLIC_GET_STATS_COUNTER(newst, st, counter) \ +-{ \ +- unsigned int start; \ ++#define SLIC_GET_STATS_COUNTER(newst, st, counter) \ ++{ \ ++ unsigned int start; \ + do { \ +- start = u64_stats_fetch_begin_irq(&(st)->syncp); \ +- newst = (st)->counter; \ +- } while (u64_stats_fetch_retry_irq(&(st)->syncp, start)); \ ++ start = u64_stats_fetch_begin(&(st)->syncp); \ ++ newst = (st)->counter; \ ++ } while (u64_stats_fetch_retry(&(st)->syncp, start)); \ + } + + struct slic_upr { +--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -118,9 +118,9 @@ static void ena_safe_update_stat(u64 *sr + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + *(dst) = *src; +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + } + + static void ena_queue_stats(struct ena_adapter *adapter, u64 **data) +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3268,10 +3268,10 @@ static void ena_get_stats64(struct net_d + tx_ring = &adapter->tx_ring[i]; + + do { +- start = u64_stats_fetch_begin_irq(&tx_ring->syncp); ++ start = u64_stats_fetch_begin(&tx_ring->syncp); + packets = tx_ring->tx_stats.cnt; + bytes = tx_ring->tx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_ring->syncp, start)); + + stats->tx_packets += packets; + stats->tx_bytes += bytes; +@@ -3279,20 +3279,20 @@ static void ena_get_stats64(struct net_d + rx_ring = &adapter->rx_ring[i]; + + do { +- start = u64_stats_fetch_begin_irq(&rx_ring->syncp); ++ start = u64_stats_fetch_begin(&rx_ring->syncp); + packets = rx_ring->rx_stats.cnt; + bytes = rx_ring->rx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_ring->syncp, start)); + + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } + + do { +- start = u64_stats_fetch_begin_irq(&adapter->syncp); ++ start = u64_stats_fetch_begin(&adapter->syncp); + rx_drops = adapter->dev_stats.rx_drops; + tx_drops = adapter->dev_stats.tx_drops; +- } while (u64_stats_fetch_retry_irq(&adapter->syncp, start)); ++ } while (u64_stats_fetch_retry(&adapter->syncp, start)); + + stats->rx_dropped = rx_drops; + stats->tx_dropped = tx_drops; +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +@@ -934,7 +934,7 @@ unsigned int aq_ring_fill_stats_data(str + /* This data should mimic aq_ethtool_queue_rx_stat_names structure */ + do { + count = 0; +- start = u64_stats_fetch_begin_irq(&self->stats.rx.syncp); ++ start = u64_stats_fetch_begin(&self->stats.rx.syncp); + data[count] = self->stats.rx.packets; + data[++count] = self->stats.rx.jumbo_packets; + data[++count] = self->stats.rx.lro_packets; +@@ -951,15 +951,15 @@ unsigned int aq_ring_fill_stats_data(str + data[++count] = self->stats.rx.xdp_tx; + data[++count] = self->stats.rx.xdp_invalid; + data[++count] = self->stats.rx.xdp_redirect; +- } while (u64_stats_fetch_retry_irq(&self->stats.rx.syncp, start)); ++ } while (u64_stats_fetch_retry(&self->stats.rx.syncp, start)); + } else { + /* This data should mimic aq_ethtool_queue_tx_stat_names structure */ + do { + count = 0; +- start = u64_stats_fetch_begin_irq(&self->stats.tx.syncp); ++ start = u64_stats_fetch_begin(&self->stats.tx.syncp); + data[count] = self->stats.tx.packets; + data[++count] = self->stats.tx.queue_restarts; +- } while (u64_stats_fetch_retry_irq(&self->stats.tx.syncp, start)); ++ } while (u64_stats_fetch_retry(&self->stats.tx.syncp, start)); + } + + return ++count; +--- a/drivers/net/ethernet/asix/ax88796c_main.c ++++ b/drivers/net/ethernet/asix/ax88796c_main.c +@@ -662,12 +662,12 @@ static void ax88796c_get_stats64(struct + s = per_cpu_ptr(ax_local->stats, cpu); + + do { +- start = u64_stats_fetch_begin_irq(&s->syncp); ++ start = u64_stats_fetch_begin(&s->syncp); + rx_packets = u64_stats_read(&s->rx_packets); + rx_bytes = u64_stats_read(&s->rx_bytes); + tx_packets = u64_stats_read(&s->tx_packets); + tx_bytes = u64_stats_read(&s->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&s->syncp, start)); ++ } while (u64_stats_fetch_retry(&s->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +--- a/drivers/net/ethernet/broadcom/b44.c ++++ b/drivers/net/ethernet/broadcom/b44.c +@@ -1680,7 +1680,7 @@ static void b44_get_stats64(struct net_d + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&hwstat->syncp); ++ start = u64_stats_fetch_begin(&hwstat->syncp); + + /* Convert HW stats into rtnl_link_stats64 stats. */ + nstat->rx_packets = hwstat->rx_pkts; +@@ -1714,7 +1714,7 @@ static void b44_get_stats64(struct net_d + /* Carrier lost counter seems to be broken for some devices */ + nstat->tx_carrier_errors = hwstat->tx_carrier_lost; + #endif +- } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start)); ++ } while (u64_stats_fetch_retry(&hwstat->syncp, start)); + + } + +@@ -2082,12 +2082,12 @@ static void b44_get_ethtool_stats(struct + do { + data_src = &hwstat->tx_good_octets; + data_dst = data; +- start = u64_stats_fetch_begin_irq(&hwstat->syncp); ++ start = u64_stats_fetch_begin(&hwstat->syncp); + + for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) + *data_dst++ = *data_src++; + +- } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start)); ++ } while (u64_stats_fetch_retry(&hwstat->syncp, start)); + } + + static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +--- a/drivers/net/ethernet/broadcom/bcmsysport.c ++++ b/drivers/net/ethernet/broadcom/bcmsysport.c +@@ -457,10 +457,10 @@ static void bcm_sysport_update_tx_stats( + for (q = 0; q < priv->netdev->num_tx_queues; q++) { + ring = &priv->tx_rings[q]; + do { +- start = u64_stats_fetch_begin_irq(&priv->syncp); ++ start = u64_stats_fetch_begin(&priv->syncp); + bytes = ring->bytes; + packets = ring->packets; +- } while (u64_stats_fetch_retry_irq(&priv->syncp, start)); ++ } while (u64_stats_fetch_retry(&priv->syncp, start)); + + *tx_bytes += bytes; + *tx_packets += packets; +@@ -504,9 +504,9 @@ static void bcm_sysport_get_stats(struct + if (s->stat_sizeof == sizeof(u64) && + s->type == BCM_SYSPORT_STAT_NETDEV64) { + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + data[i] = *(u64 *)p; +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + } else + data[i] = *(u32 *)p; + j++; +@@ -1878,10 +1878,10 @@ static void bcm_sysport_get_stats64(stru + &stats->tx_packets); + + do { +- start = u64_stats_fetch_begin_irq(&priv->syncp); ++ start = u64_stats_fetch_begin(&priv->syncp); + stats->rx_packets = stats64->rx_packets; + stats->rx_bytes = stats64->rx_bytes; +- } while (u64_stats_fetch_retry_irq(&priv->syncp, start)); ++ } while (u64_stats_fetch_retry(&priv->syncp, start)); + } + + static void bcm_sysport_netif_start(struct net_device *dev) +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -1919,7 +1919,7 @@ static void gmac_get_stats64(struct net_ + + /* Racing with RX NAPI */ + do { +- start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp); ++ start = u64_stats_fetch_begin(&port->rx_stats_syncp); + + stats->rx_packets = port->stats.rx_packets; + stats->rx_bytes = port->stats.rx_bytes; +@@ -1931,11 +1931,11 @@ static void gmac_get_stats64(struct net_ + stats->rx_crc_errors = port->stats.rx_crc_errors; + stats->rx_frame_errors = port->stats.rx_frame_errors; + +- } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); + + /* Racing with MIB and TX completion interrupts */ + do { +- start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp); ++ start = u64_stats_fetch_begin(&port->ir_stats_syncp); + + stats->tx_errors = port->stats.tx_errors; + stats->tx_packets = port->stats.tx_packets; +@@ -1945,15 +1945,15 @@ static void gmac_get_stats64(struct net_ + stats->rx_missed_errors = port->stats.rx_missed_errors; + stats->rx_fifo_errors = port->stats.rx_fifo_errors; + +- } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); + + /* Racing with hard_start_xmit */ + do { +- start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp); ++ start = u64_stats_fetch_begin(&port->tx_stats_syncp); + + stats->tx_dropped = port->stats.tx_dropped; + +- } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); + + stats->rx_dropped += stats->rx_missed_errors; + } +@@ -2031,18 +2031,18 @@ static void gmac_get_ethtool_stats(struc + /* Racing with MIB interrupt */ + do { + p = values; +- start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp); ++ start = u64_stats_fetch_begin(&port->ir_stats_syncp); + + for (i = 0; i < RX_STATS_NUM; i++) + *p++ = port->hw_stats[i]; + +- } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); + values = p; + + /* Racing with RX NAPI */ + do { + p = values; +- start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp); ++ start = u64_stats_fetch_begin(&port->rx_stats_syncp); + + for (i = 0; i < RX_STATUS_NUM; i++) + *p++ = port->rx_stats[i]; +@@ -2050,13 +2050,13 @@ static void gmac_get_ethtool_stats(struc + *p++ = port->rx_csum_stats[i]; + *p++ = port->rx_napi_exits; + +- } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); + values = p; + + /* Racing with TX start_xmit */ + do { + p = values; +- start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp); ++ start = u64_stats_fetch_begin(&port->tx_stats_syncp); + + for (i = 0; i < TX_MAX_FRAGS; i++) { + *values++ = port->tx_frag_stats[i]; +@@ -2065,7 +2065,7 @@ static void gmac_get_ethtool_stats(struc + *values++ = port->tx_frags_linearized; + *values++ = port->tx_hw_csummed; + +- } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); + } + + static int gmac_get_ksettings(struct net_device *netdev, +--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c ++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c +@@ -389,10 +389,10 @@ static void be_get_ethtool_stats(struct + struct be_rx_stats *stats = rx_stats(rxo); + + do { +- start = u64_stats_fetch_begin_irq(&stats->sync); ++ start = u64_stats_fetch_begin(&stats->sync); + data[base] = stats->rx_bytes; + data[base + 1] = stats->rx_pkts; +- } while (u64_stats_fetch_retry_irq(&stats->sync, start)); ++ } while (u64_stats_fetch_retry(&stats->sync, start)); + + for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) { + p = (u8 *)stats + et_rx_stats[i].offset; +@@ -405,19 +405,19 @@ static void be_get_ethtool_stats(struct + struct be_tx_stats *stats = tx_stats(txo); + + do { +- start = u64_stats_fetch_begin_irq(&stats->sync_compl); ++ start = u64_stats_fetch_begin(&stats->sync_compl); + data[base] = stats->tx_compl; +- } while (u64_stats_fetch_retry_irq(&stats->sync_compl, start)); ++ } while (u64_stats_fetch_retry(&stats->sync_compl, start)); + + do { +- start = u64_stats_fetch_begin_irq(&stats->sync); ++ start = u64_stats_fetch_begin(&stats->sync); + for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) { + p = (u8 *)stats + et_tx_stats[i].offset; + data[base + i] = + (et_tx_stats[i].size == sizeof(u64)) ? + *(u64 *)p : *(u32 *)p; + } +- } while (u64_stats_fetch_retry_irq(&stats->sync, start)); ++ } while (u64_stats_fetch_retry(&stats->sync, start)); + base += ETHTOOL_TXSTATS_NUM; + } + } +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -665,10 +665,10 @@ static void be_get_stats64(struct net_de + const struct be_rx_stats *rx_stats = rx_stats(rxo); + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->sync); ++ start = u64_stats_fetch_begin(&rx_stats->sync); + pkts = rx_stats(rxo)->rx_pkts; + bytes = rx_stats(rxo)->rx_bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->sync, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->sync, start)); + stats->rx_packets += pkts; + stats->rx_bytes += bytes; + stats->multicast += rx_stats(rxo)->rx_mcast_pkts; +@@ -680,10 +680,10 @@ static void be_get_stats64(struct net_de + const struct be_tx_stats *tx_stats = tx_stats(txo); + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->sync); ++ start = u64_stats_fetch_begin(&tx_stats->sync); + pkts = tx_stats(txo)->tx_pkts; + bytes = tx_stats(txo)->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->sync, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->sync, start)); + stats->tx_packets += pkts; + stats->tx_bytes += bytes; + } +@@ -2155,16 +2155,16 @@ static int be_get_new_eqd(struct be_eq_o + + for_all_rx_queues_on_eq(adapter, eqo, rxo, i) { + do { +- start = u64_stats_fetch_begin_irq(&rxo->stats.sync); ++ start = u64_stats_fetch_begin(&rxo->stats.sync); + rx_pkts += rxo->stats.rx_pkts; +- } while (u64_stats_fetch_retry_irq(&rxo->stats.sync, start)); ++ } while (u64_stats_fetch_retry(&rxo->stats.sync, start)); + } + + for_all_tx_queues_on_eq(adapter, eqo, txo, i) { + do { +- start = u64_stats_fetch_begin_irq(&txo->stats.sync); ++ start = u64_stats_fetch_begin(&txo->stats.sync); + tx_pkts += txo->stats.tx_reqs; +- } while (u64_stats_fetch_retry_irq(&txo->stats.sync, start)); ++ } while (u64_stats_fetch_retry(&txo->stats.sync, start)); + } + + /* Skip, if wrapped around or first calculation */ +--- a/drivers/net/ethernet/fungible/funeth/funeth_txrx.h ++++ b/drivers/net/ethernet/fungible/funeth/funeth_txrx.h +@@ -206,9 +206,9 @@ struct funeth_rxq { + + #define FUN_QSTAT_READ(q, seq, stats_copy) \ + do { \ +- seq = u64_stats_fetch_begin_irq(&(q)->syncp); \ ++ seq = u64_stats_fetch_begin(&(q)->syncp); \ + stats_copy = (q)->stats; \ +- } while (u64_stats_fetch_retry_irq(&(q)->syncp, (seq))) ++ } while (u64_stats_fetch_retry(&(q)->syncp, (seq))) + + #define FUN_INT_NAME_LEN (IFNAMSIZ + 16) + +--- a/drivers/net/ethernet/google/gve/gve_ethtool.c ++++ b/drivers/net/ethernet/google/gve/gve_ethtool.c +@@ -177,14 +177,14 @@ gve_get_ethtool_stats(struct net_device + struct gve_rx_ring *rx = &priv->rx[ring]; + + start = +- u64_stats_fetch_begin_irq(&priv->rx[ring].statss); ++ u64_stats_fetch_begin(&priv->rx[ring].statss); + tmp_rx_pkts = rx->rpackets; + tmp_rx_bytes = rx->rbytes; + tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail; + tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail; + tmp_rx_desc_err_dropped_pkt = + rx->rx_desc_err_dropped_pkt; +- } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); + rx_pkts += tmp_rx_pkts; + rx_bytes += tmp_rx_bytes; +@@ -198,10 +198,10 @@ gve_get_ethtool_stats(struct net_device + if (priv->tx) { + do { + start = +- u64_stats_fetch_begin_irq(&priv->tx[ring].statss); ++ u64_stats_fetch_begin(&priv->tx[ring].statss); + tmp_tx_pkts = priv->tx[ring].pkt_done; + tmp_tx_bytes = priv->tx[ring].bytes_done; +- } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->tx[ring].statss, + start)); + tx_pkts += tmp_tx_pkts; + tx_bytes += tmp_tx_bytes; +@@ -259,13 +259,13 @@ gve_get_ethtool_stats(struct net_device + data[i++] = rx->fill_cnt - rx->cnt; + do { + start = +- u64_stats_fetch_begin_irq(&priv->rx[ring].statss); ++ u64_stats_fetch_begin(&priv->rx[ring].statss); + tmp_rx_bytes = rx->rbytes; + tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail; + tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail; + tmp_rx_desc_err_dropped_pkt = + rx->rx_desc_err_dropped_pkt; +- } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); + data[i++] = tmp_rx_bytes; + data[i++] = rx->rx_cont_packet_cnt; +@@ -331,9 +331,9 @@ gve_get_ethtool_stats(struct net_device + } + do { + start = +- u64_stats_fetch_begin_irq(&priv->tx[ring].statss); ++ u64_stats_fetch_begin(&priv->tx[ring].statss); + tmp_tx_bytes = tx->bytes_done; +- } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->tx[ring].statss, + start)); + data[i++] = tmp_tx_bytes; + data[i++] = tx->wake_queue; +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -51,10 +51,10 @@ static void gve_get_stats(struct net_dev + for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) { + do { + start = +- u64_stats_fetch_begin_irq(&priv->rx[ring].statss); ++ u64_stats_fetch_begin(&priv->rx[ring].statss); + packets = priv->rx[ring].rpackets; + bytes = priv->rx[ring].rbytes; +- } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); + s->rx_packets += packets; + s->rx_bytes += bytes; +@@ -64,10 +64,10 @@ static void gve_get_stats(struct net_dev + for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) { + do { + start = +- u64_stats_fetch_begin_irq(&priv->tx[ring].statss); ++ u64_stats_fetch_begin(&priv->tx[ring].statss); + packets = priv->tx[ring].pkt_done; + bytes = priv->tx[ring].bytes_done; +- } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->tx[ring].statss, + start)); + s->tx_packets += packets; + s->tx_bytes += bytes; +@@ -1273,9 +1273,9 @@ void gve_handle_report_stats(struct gve_ + } + + do { +- start = u64_stats_fetch_begin_irq(&priv->tx[idx].statss); ++ start = u64_stats_fetch_begin(&priv->tx[idx].statss); + tx_bytes = priv->tx[idx].bytes_done; +- } while (u64_stats_fetch_retry_irq(&priv->tx[idx].statss, start)); ++ } while (u64_stats_fetch_retry(&priv->tx[idx].statss, start)); + stats[stats_idx++] = (struct stats) { + .stat_name = cpu_to_be32(TX_WAKE_CNT), + .value = cpu_to_be64(priv->tx[idx].wake_queue), +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -2488,7 +2488,7 @@ static void hns3_fetch_stats(struct rtnl + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + if (is_tx) { + stats->tx_bytes += ring->stats.tx_bytes; + stats->tx_packets += ring->stats.tx_pkts; +@@ -2522,7 +2522,7 @@ static void hns3_fetch_stats(struct rtnl + stats->multicast += ring->stats.rx_multicast; + stats->rx_length_errors += ring->stats.err_pkt_len; + } +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + } + + static void hns3_nic_get_stats64(struct net_device *netdev, +--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c +@@ -74,14 +74,14 @@ void hinic_rxq_get_stats(struct hinic_rx + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&rxq_stats->syncp); ++ start = u64_stats_fetch_begin(&rxq_stats->syncp); + stats->pkts = rxq_stats->pkts; + stats->bytes = rxq_stats->bytes; + stats->errors = rxq_stats->csum_errors + + rxq_stats->other_errors; + stats->csum_errors = rxq_stats->csum_errors; + stats->other_errors = rxq_stats->other_errors; +- } while (u64_stats_fetch_retry_irq(&rxq_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); + } + + /** +--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c +@@ -99,14 +99,14 @@ void hinic_txq_get_stats(struct hinic_tx + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&txq_stats->syncp); ++ start = u64_stats_fetch_begin(&txq_stats->syncp); + stats->pkts = txq_stats->pkts; + stats->bytes = txq_stats->bytes; + stats->tx_busy = txq_stats->tx_busy; + stats->tx_wake = txq_stats->tx_wake; + stats->tx_dropped = txq_stats->tx_dropped; + stats->big_frags_pkts = txq_stats->big_frags_pkts; +- } while (u64_stats_fetch_retry_irq(&txq_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); + } + + /** +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -1229,10 +1229,10 @@ static void fm10k_get_stats64(struct net + continue; + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + + stats->rx_packets += packets; + stats->rx_bytes += bytes; +@@ -1245,10 +1245,10 @@ static void fm10k_get_stats64(struct net + continue; + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + + stats->tx_packets += packets; + stats->tx_bytes += bytes; +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -154,7 +154,7 @@ __i40e_add_ethtool_stats(u64 **data, voi + * @ring: the ring to copy + * + * Queue statistics must be copied while protected by +- * u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats. ++ * u64_stats_fetch_begin, so we can't directly use i40e_add_ethtool_stats. + * Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the + * ring pointer is null, zero out the queue stat values and update the data + * pointer. Otherwise safely copy the stats from the ring into the supplied +@@ -172,16 +172,16 @@ i40e_add_queue_stats(u64 **data, struct + + /* To avoid invalid statistics values, ensure that we keep retrying + * the copy until we get a consistent value according to +- * u64_stats_fetch_retry_irq. But first, make sure our ring is ++ * u64_stats_fetch_retry. But first, make sure our ring is + * non-null before attempting to access its syncp. + */ + do { +- start = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp); ++ start = !ring ? 0 : u64_stats_fetch_begin(&ring->syncp); + for (i = 0; i < size; i++) { + i40e_add_one_ethtool_stat(&(*data)[i], ring, + &stats[i]); + } +- } while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (ring && u64_stats_fetch_retry(&ring->syncp, start)); + + /* Once we successfully copy the stats in, update the data pointer */ + *data += size; +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -419,10 +419,10 @@ static void i40e_get_netdev_stats_struct + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + + stats->tx_packets += packets; + stats->tx_bytes += bytes; +@@ -472,10 +472,10 @@ static void i40e_get_netdev_stats_struct + if (!ring) + continue; + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + + stats->rx_packets += packets; + stats->rx_bytes += bytes; +@@ -897,10 +897,10 @@ static void i40e_update_vsi_stats(struct + continue; + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + packets = p->stats.packets; + bytes = p->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + tx_b += bytes; + tx_p += packets; + tx_restart += p->tx_stats.restart_queue; +@@ -915,10 +915,10 @@ static void i40e_update_vsi_stats(struct + continue; + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + packets = p->stats.packets; + bytes = p->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + rx_b += bytes; + rx_p += packets; + rx_buf += p->rx_stats.alloc_buff_failed; +@@ -935,10 +935,10 @@ static void i40e_update_vsi_stats(struct + continue; + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + packets = p->stats.packets; + bytes = p->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + tx_b += bytes; + tx_p += packets; + tx_restart += p->tx_stats.restart_queue; +--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +@@ -147,7 +147,7 @@ __iavf_add_ethtool_stats(u64 **data, voi + * @ring: the ring to copy + * + * Queue statistics must be copied while protected by +- * u64_stats_fetch_begin_irq, so we can't directly use iavf_add_ethtool_stats. ++ * u64_stats_fetch_begin, so we can't directly use iavf_add_ethtool_stats. + * Assumes that queue stats are defined in iavf_gstrings_queue_stats. If the + * ring pointer is null, zero out the queue stat values and update the data + * pointer. Otherwise safely copy the stats from the ring into the supplied +@@ -165,14 +165,14 @@ iavf_add_queue_stats(u64 **data, struct + + /* To avoid invalid statistics values, ensure that we keep retrying + * the copy until we get a consistent value according to +- * u64_stats_fetch_retry_irq. But first, make sure our ring is ++ * u64_stats_fetch_retry. But first, make sure our ring is + * non-null before attempting to access its syncp. + */ + do { +- start = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp); ++ start = !ring ? 0 : u64_stats_fetch_begin(&ring->syncp); + for (i = 0; i < size; i++) + iavf_add_one_ethtool_stat(&(*data)[i], ring, &stats[i]); +- } while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (ring && u64_stats_fetch_retry(&ring->syncp, start)); + + /* Once we successfully copy the stats in, update the data pointer */ + *data += size; +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -6370,10 +6370,10 @@ ice_fetch_u64_stats_per_ring(struct u64_ + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + *pkts = stats.pkts; + *bytes = stats.bytes; +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + } + + /** +--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c ++++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c +@@ -2313,15 +2313,15 @@ static void igb_get_ethtool_stats(struct + + ring = adapter->tx_ring[j]; + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp); ++ start = u64_stats_fetch_begin(&ring->tx_syncp); + data[i] = ring->tx_stats.packets; + data[i+1] = ring->tx_stats.bytes; + data[i+2] = ring->tx_stats.restart_queue; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp, start)); + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp2); ++ start = u64_stats_fetch_begin(&ring->tx_syncp2); + restart2 = ring->tx_stats.restart_queue2; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp2, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp2, start)); + data[i+2] += restart2; + + i += IGB_TX_QUEUE_STATS_LEN; +@@ -2329,13 +2329,13 @@ static void igb_get_ethtool_stats(struct + for (j = 0; j < adapter->num_rx_queues; j++) { + ring = adapter->rx_ring[j]; + do { +- start = u64_stats_fetch_begin_irq(&ring->rx_syncp); ++ start = u64_stats_fetch_begin(&ring->rx_syncp); + data[i] = ring->rx_stats.packets; + data[i+1] = ring->rx_stats.bytes; + data[i+2] = ring->rx_stats.drops; + data[i+3] = ring->rx_stats.csum_err; + data[i+4] = ring->rx_stats.alloc_failed; +- } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->rx_syncp, start)); + i += IGB_RX_QUEUE_STATS_LEN; + } + spin_unlock(&adapter->stats64_lock); +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -6632,10 +6632,10 @@ void igb_update_stats(struct igb_adapter + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->rx_syncp); ++ start = u64_stats_fetch_begin(&ring->rx_syncp); + _bytes = ring->rx_stats.bytes; + _packets = ring->rx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->rx_syncp, start)); + bytes += _bytes; + packets += _packets; + } +@@ -6648,10 +6648,10 @@ void igb_update_stats(struct igb_adapter + for (i = 0; i < adapter->num_tx_queues; i++) { + struct igb_ring *ring = adapter->tx_ring[i]; + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp); ++ start = u64_stats_fetch_begin(&ring->tx_syncp); + _bytes = ring->tx_stats.bytes; + _packets = ring->tx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp, start)); + bytes += _bytes; + packets += _packets; + } +--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c ++++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c +@@ -839,15 +839,15 @@ static void igc_ethtool_get_stats(struct + + ring = adapter->tx_ring[j]; + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp); ++ start = u64_stats_fetch_begin(&ring->tx_syncp); + data[i] = ring->tx_stats.packets; + data[i + 1] = ring->tx_stats.bytes; + data[i + 2] = ring->tx_stats.restart_queue; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp, start)); + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp2); ++ start = u64_stats_fetch_begin(&ring->tx_syncp2); + restart2 = ring->tx_stats.restart_queue2; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp2, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp2, start)); + data[i + 2] += restart2; + + i += IGC_TX_QUEUE_STATS_LEN; +@@ -855,13 +855,13 @@ static void igc_ethtool_get_stats(struct + for (j = 0; j < adapter->num_rx_queues; j++) { + ring = adapter->rx_ring[j]; + do { +- start = u64_stats_fetch_begin_irq(&ring->rx_syncp); ++ start = u64_stats_fetch_begin(&ring->rx_syncp); + data[i] = ring->rx_stats.packets; + data[i + 1] = ring->rx_stats.bytes; + data[i + 2] = ring->rx_stats.drops; + data[i + 3] = ring->rx_stats.csum_err; + data[i + 4] = ring->rx_stats.alloc_failed; +- } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->rx_syncp, start)); + i += IGC_RX_QUEUE_STATS_LEN; + } + spin_unlock(&adapter->stats64_lock); +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -4682,10 +4682,10 @@ void igc_update_stats(struct igc_adapter + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->rx_syncp); ++ start = u64_stats_fetch_begin(&ring->rx_syncp); + _bytes = ring->rx_stats.bytes; + _packets = ring->rx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->rx_syncp, start)); + bytes += _bytes; + packets += _packets; + } +@@ -4699,10 +4699,10 @@ void igc_update_stats(struct igc_adapter + struct igc_ring *ring = adapter->tx_ring[i]; + + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp); ++ start = u64_stats_fetch_begin(&ring->tx_syncp); + _bytes = ring->tx_stats.bytes; + _packets = ring->tx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp, start)); + bytes += _bytes; + packets += _packets; + } +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +@@ -1335,10 +1335,10 @@ static void ixgbe_get_ethtool_stats(stru + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i+1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) { +@@ -1351,10 +1351,10 @@ static void ixgbe_get_ethtool_stats(stru + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i+1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -9041,10 +9041,10 @@ static void ixgbe_get_ring_stats64(struc + + if (ring) { + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->tx_packets += packets; + stats->tx_bytes += bytes; + } +@@ -9064,10 +9064,10 @@ static void ixgbe_get_stats64(struct net + + if (ring) { + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } +--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c +@@ -458,10 +458,10 @@ static void ixgbevf_get_ethtool_stats(st + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i + 1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + +@@ -475,10 +475,10 @@ static void ixgbevf_get_ethtool_stats(st + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i + 1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + +@@ -492,10 +492,10 @@ static void ixgbevf_get_ethtool_stats(st + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i + 1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + } +--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +@@ -4350,10 +4350,10 @@ static void ixgbevf_get_tx_ring_stats(st + + if (ring) { + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + bytes = ring->stats.bytes; + packets = ring->stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->tx_bytes += bytes; + stats->tx_packets += packets; + } +@@ -4376,10 +4376,10 @@ static void ixgbevf_get_stats(struct net + for (i = 0; i < adapter->num_rx_queues; i++) { + ring = adapter->rx_ring[i]; + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + bytes = ring->stats.bytes; + packets = ring->stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->rx_bytes += bytes; + stats->rx_packets += packets; + } +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -813,14 +813,14 @@ mvneta_get_stats64(struct net_device *de + + cpu_stats = per_cpu_ptr(pp->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + rx_packets = cpu_stats->es.ps.rx_packets; + rx_bytes = cpu_stats->es.ps.rx_bytes; + rx_dropped = cpu_stats->rx_dropped; + rx_errors = cpu_stats->rx_errors; + tx_packets = cpu_stats->es.ps.tx_packets; + tx_bytes = cpu_stats->es.ps.tx_bytes; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +@@ -4762,7 +4762,7 @@ mvneta_ethtool_update_pcpu_stats(struct + + stats = per_cpu_ptr(pp->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + skb_alloc_error = stats->es.skb_alloc_error; + refill_error = stats->es.refill_error; + xdp_redirect = stats->es.ps.xdp_redirect; +@@ -4772,7 +4772,7 @@ mvneta_ethtool_update_pcpu_stats(struct + xdp_xmit_err = stats->es.ps.xdp_xmit_err; + xdp_tx = stats->es.ps.xdp_tx; + xdp_tx_err = stats->es.ps.xdp_tx_err; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + es->skb_alloc_error += skb_alloc_error; + es->refill_error += refill_error; +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -2008,7 +2008,7 @@ mvpp2_get_xdp_stats(struct mvpp2_port *p + + cpu_stats = per_cpu_ptr(port->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + xdp_redirect = cpu_stats->xdp_redirect; + xdp_pass = cpu_stats->xdp_pass; + xdp_drop = cpu_stats->xdp_drop; +@@ -2016,7 +2016,7 @@ mvpp2_get_xdp_stats(struct mvpp2_port *p + xdp_xmit_err = cpu_stats->xdp_xmit_err; + xdp_tx = cpu_stats->xdp_tx; + xdp_tx_err = cpu_stats->xdp_tx_err; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + xdp_stats->xdp_redirect += xdp_redirect; + xdp_stats->xdp_pass += xdp_pass; +@@ -5115,12 +5115,12 @@ mvpp2_get_stats64(struct net_device *dev + + cpu_stats = per_cpu_ptr(port->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + rx_packets = cpu_stats->rx_packets; + rx_bytes = cpu_stats->rx_bytes; + tx_packets = cpu_stats->tx_packets; + tx_bytes = cpu_stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -3894,19 +3894,19 @@ static void sky2_get_stats(struct net_de + u64 _bytes, _packets; + + do { +- start = u64_stats_fetch_begin_irq(&sky2->rx_stats.syncp); ++ start = u64_stats_fetch_begin(&sky2->rx_stats.syncp); + _bytes = sky2->rx_stats.bytes; + _packets = sky2->rx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&sky2->rx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&sky2->rx_stats.syncp, start)); + + stats->rx_packets = _packets; + stats->rx_bytes = _bytes; + + do { +- start = u64_stats_fetch_begin_irq(&sky2->tx_stats.syncp); ++ start = u64_stats_fetch_begin(&sky2->tx_stats.syncp); + _bytes = sky2->tx_stats.bytes; + _packets = sky2->tx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&sky2->tx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&sky2->tx_stats.syncp, start)); + + stats->tx_packets = _packets; + stats->tx_bytes = _bytes; +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -865,7 +865,7 @@ static void mtk_get_stats64(struct net_d + } + + do { +- start = u64_stats_fetch_begin_irq(&hw_stats->syncp); ++ start = u64_stats_fetch_begin(&hw_stats->syncp); + storage->rx_packets = hw_stats->rx_packets; + storage->tx_packets = hw_stats->tx_packets; + storage->rx_bytes = hw_stats->rx_bytes; +@@ -877,7 +877,7 @@ static void mtk_get_stats64(struct net_d + storage->rx_crc_errors = hw_stats->rx_fcs_errors; + storage->rx_errors = hw_stats->rx_checksum_errors; + storage->tx_aborted_errors = hw_stats->tx_skip; +- } while (u64_stats_fetch_retry_irq(&hw_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&hw_stats->syncp, start)); + + storage->tx_errors = dev->stats.tx_errors; + storage->rx_dropped = dev->stats.rx_dropped; +@@ -3688,13 +3688,13 @@ static void mtk_get_ethtool_stats(struct + + do { + data_dst = data; +- start = u64_stats_fetch_begin_irq(&hwstats->syncp); ++ start = u64_stats_fetch_begin(&hwstats->syncp); + + for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) + *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset); + if (mtk_page_pool_enabled(mac->hw)) + mtk_ethtool_pp_stats(mac->hw, data_dst); +- } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start)); ++ } while (u64_stats_fetch_retry(&hwstats->syncp, start)); + } + + static int mtk_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +@@ -827,12 +827,12 @@ mlxsw_sp_port_get_sw_stats64(const struc + for_each_possible_cpu(i) { + p = per_cpu_ptr(mlxsw_sp_port->pcpu_stats, i); + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + rx_packets = p->rx_packets; + rx_bytes = p->rx_bytes; + tx_packets = p->tx_packets; + tx_bytes = p->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -315,10 +315,10 @@ static void mana_get_stats64(struct net_ + rx_stats = &apc->rxqs[q]->stats; + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + st->rx_packets += packets; + st->rx_bytes += bytes; +@@ -328,10 +328,10 @@ static void mana_get_stats64(struct net_ + tx_stats = &apc->tx_qp[q].txq.stats; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + st->tx_packets += packets; + st->tx_bytes += bytes; +--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +@@ -90,13 +90,13 @@ static void mana_get_ethtool_stats(struc + rx_stats = &apc->rxqs[q]->stats; + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; + xdp_drop = rx_stats->xdp_drop; + xdp_tx = rx_stats->xdp_tx; + xdp_redirect = rx_stats->xdp_redirect; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + data[i++] = packets; + data[i++] = bytes; +@@ -109,11 +109,11 @@ static void mana_get_ethtool_stats(struc + tx_stats = &apc->tx_qp[q].txq.stats; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; + xdp_xmit = tx_stats->xdp_xmit; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + data[i++] = packets; + data[i++] = bytes; +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +@@ -1631,21 +1631,21 @@ static void nfp_net_stat64(struct net_de + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&r_vec->rx_sync); ++ start = u64_stats_fetch_begin(&r_vec->rx_sync); + data[0] = r_vec->rx_pkts; + data[1] = r_vec->rx_bytes; + data[2] = r_vec->rx_drops; +- } while (u64_stats_fetch_retry_irq(&r_vec->rx_sync, start)); ++ } while (u64_stats_fetch_retry(&r_vec->rx_sync, start)); + stats->rx_packets += data[0]; + stats->rx_bytes += data[1]; + stats->rx_dropped += data[2]; + + do { +- start = u64_stats_fetch_begin_irq(&r_vec->tx_sync); ++ start = u64_stats_fetch_begin(&r_vec->tx_sync); + data[0] = r_vec->tx_pkts; + data[1] = r_vec->tx_bytes; + data[2] = r_vec->tx_errors; +- } while (u64_stats_fetch_retry_irq(&r_vec->tx_sync, start)); ++ } while (u64_stats_fetch_retry(&r_vec->tx_sync, start)); + stats->tx_packets += data[0]; + stats->tx_bytes += data[1]; + stats->tx_errors += data[2]; +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +@@ -686,7 +686,7 @@ static u64 *nfp_vnic_get_sw_stats(struct + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].rx_sync); ++ start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync); + data[0] = nn->r_vecs[i].rx_pkts; + tmp[0] = nn->r_vecs[i].hw_csum_rx_ok; + tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok; +@@ -694,10 +694,10 @@ static u64 *nfp_vnic_get_sw_stats(struct + tmp[3] = nn->r_vecs[i].hw_csum_rx_error; + tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail; + tmp[5] = nn->r_vecs[i].hw_tls_rx; +- } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].rx_sync, start)); ++ } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start)); + + do { +- start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].tx_sync); ++ start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync); + data[1] = nn->r_vecs[i].tx_pkts; + data[2] = nn->r_vecs[i].tx_busy; + tmp[6] = nn->r_vecs[i].hw_csum_tx; +@@ -707,7 +707,7 @@ static u64 *nfp_vnic_get_sw_stats(struct + tmp[10] = nn->r_vecs[i].hw_tls_tx; + tmp[11] = nn->r_vecs[i].tls_tx_fallback; + tmp[12] = nn->r_vecs[i].tls_tx_no_fallback; +- } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].tx_sync, start)); ++ } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start)); + + data += NN_RVEC_PER_Q_STATS; + +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +@@ -134,13 +134,13 @@ nfp_repr_get_host_stats64(const struct n + + repr_stats = per_cpu_ptr(repr->stats, i); + do { +- start = u64_stats_fetch_begin_irq(&repr_stats->syncp); ++ start = u64_stats_fetch_begin(&repr_stats->syncp); + tbytes = repr_stats->tx_bytes; + tpkts = repr_stats->tx_packets; + tdrops = repr_stats->tx_drops; + rbytes = repr_stats->rx_bytes; + rpkts = repr_stats->rx_packets; +- } while (u64_stats_fetch_retry_irq(&repr_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&repr_stats->syncp, start)); + + stats->tx_bytes += tbytes; + stats->tx_packets += tpkts; +--- a/drivers/net/ethernet/nvidia/forcedeth.c ++++ b/drivers/net/ethernet/nvidia/forcedeth.c +@@ -1734,12 +1734,12 @@ static void nv_get_stats(int cpu, struct + u64 tx_packets, tx_bytes, tx_dropped; + + do { +- syncp_start = u64_stats_fetch_begin_irq(&np->swstats_rx_syncp); ++ syncp_start = u64_stats_fetch_begin(&np->swstats_rx_syncp); + rx_packets = src->stat_rx_packets; + rx_bytes = src->stat_rx_bytes; + rx_dropped = src->stat_rx_dropped; + rx_missed_errors = src->stat_rx_missed_errors; +- } while (u64_stats_fetch_retry_irq(&np->swstats_rx_syncp, syncp_start)); ++ } while (u64_stats_fetch_retry(&np->swstats_rx_syncp, syncp_start)); + + storage->rx_packets += rx_packets; + storage->rx_bytes += rx_bytes; +@@ -1747,11 +1747,11 @@ static void nv_get_stats(int cpu, struct + storage->rx_missed_errors += rx_missed_errors; + + do { +- syncp_start = u64_stats_fetch_begin_irq(&np->swstats_tx_syncp); ++ syncp_start = u64_stats_fetch_begin(&np->swstats_tx_syncp); + tx_packets = src->stat_tx_packets; + tx_bytes = src->stat_tx_bytes; + tx_dropped = src->stat_tx_dropped; +- } while (u64_stats_fetch_retry_irq(&np->swstats_tx_syncp, syncp_start)); ++ } while (u64_stats_fetch_retry(&np->swstats_tx_syncp, syncp_start)); + + storage->tx_packets += tx_packets; + storage->tx_bytes += tx_bytes; +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +@@ -135,9 +135,9 @@ static void rmnet_get_stats64(struct net + pcpu_ptr = per_cpu_ptr(priv->pcpu_stats, cpu); + + do { +- start = u64_stats_fetch_begin_irq(&pcpu_ptr->syncp); ++ start = u64_stats_fetch_begin(&pcpu_ptr->syncp); + snapshot = pcpu_ptr->stats; /* struct assignment */ +- } while (u64_stats_fetch_retry_irq(&pcpu_ptr->syncp, start)); ++ } while (u64_stats_fetch_retry(&pcpu_ptr->syncp, start)); + + total_stats.rx_pkts += snapshot.rx_pkts; + total_stats.rx_bytes += snapshot.rx_bytes; +--- a/drivers/net/ethernet/realtek/8139too.c ++++ b/drivers/net/ethernet/realtek/8139too.c +@@ -2532,16 +2532,16 @@ rtl8139_get_stats64(struct net_device *d + netdev_stats_to_stats64(stats, &dev->stats); + + do { +- start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp); ++ start = u64_stats_fetch_begin(&tp->rx_stats.syncp); + stats->rx_packets = tp->rx_stats.packets; + stats->rx_bytes = tp->rx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&tp->rx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&tp->rx_stats.syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&tp->tx_stats.syncp); ++ start = u64_stats_fetch_begin(&tp->tx_stats.syncp); + stats->tx_packets = tp->tx_stats.packets; + stats->tx_bytes = tp->tx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&tp->tx_stats.syncp, start)); + } + + /* Set or clear the multicast filter for this adaptor. +--- a/drivers/net/ethernet/socionext/sni_ave.c ++++ b/drivers/net/ethernet/socionext/sni_ave.c +@@ -1508,16 +1508,16 @@ static void ave_get_stats64(struct net_d + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&priv->stats_rx.syncp); ++ start = u64_stats_fetch_begin(&priv->stats_rx.syncp); + stats->rx_packets = priv->stats_rx.packets; + stats->rx_bytes = priv->stats_rx.bytes; +- } while (u64_stats_fetch_retry_irq(&priv->stats_rx.syncp, start)); ++ } while (u64_stats_fetch_retry(&priv->stats_rx.syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&priv->stats_tx.syncp); ++ start = u64_stats_fetch_begin(&priv->stats_tx.syncp); + stats->tx_packets = priv->stats_tx.packets; + stats->tx_bytes = priv->stats_tx.bytes; +- } while (u64_stats_fetch_retry_irq(&priv->stats_tx.syncp, start)); ++ } while (u64_stats_fetch_retry(&priv->stats_tx.syncp, start)); + + stats->rx_errors = priv->stats_rx.errors; + stats->tx_errors = priv->stats_tx.errors; +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -1362,12 +1362,12 @@ static void am65_cpsw_nuss_ndo_get_stats + + cpu_stats = per_cpu_ptr(ndev_priv->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + rx_packets = cpu_stats->rx_packets; + rx_bytes = cpu_stats->rx_bytes; + tx_packets = cpu_stats->tx_packets; + tx_bytes = cpu_stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +--- a/drivers/net/ethernet/ti/netcp_core.c ++++ b/drivers/net/ethernet/ti/netcp_core.c +@@ -1916,16 +1916,16 @@ netcp_get_stats(struct net_device *ndev, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp_rx); ++ start = u64_stats_fetch_begin(&p->syncp_rx); + rxpackets = p->rx_packets; + rxbytes = p->rx_bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp_rx, start)); ++ } while (u64_stats_fetch_retry(&p->syncp_rx, start)); + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp_tx); ++ start = u64_stats_fetch_begin(&p->syncp_tx); + txpackets = p->tx_packets; + txbytes = p->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp_tx, start)); ++ } while (u64_stats_fetch_retry(&p->syncp_tx, start)); + + stats->rx_packets = rxpackets; + stats->rx_bytes = rxbytes; +--- a/drivers/net/ethernet/via/via-rhine.c ++++ b/drivers/net/ethernet/via/via-rhine.c +@@ -2217,16 +2217,16 @@ rhine_get_stats64(struct net_device *dev + netdev_stats_to_stats64(stats, &dev->stats); + + do { +- start = u64_stats_fetch_begin_irq(&rp->rx_stats.syncp); ++ start = u64_stats_fetch_begin(&rp->rx_stats.syncp); + stats->rx_packets = rp->rx_stats.packets; + stats->rx_bytes = rp->rx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&rp->rx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&rp->rx_stats.syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&rp->tx_stats.syncp); ++ start = u64_stats_fetch_begin(&rp->tx_stats.syncp); + stats->tx_packets = rp->tx_stats.packets; + stats->tx_bytes = rp->tx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&rp->tx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&rp->tx_stats.syncp, start)); + } + + static void rhine_set_rx_mode(struct net_device *dev) +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1305,16 +1305,16 @@ axienet_get_stats64(struct net_device *d + netdev_stats_to_stats64(stats, &dev->stats); + + do { +- start = u64_stats_fetch_begin_irq(&lp->rx_stat_sync); ++ start = u64_stats_fetch_begin(&lp->rx_stat_sync); + stats->rx_packets = u64_stats_read(&lp->rx_packets); + stats->rx_bytes = u64_stats_read(&lp->rx_bytes); +- } while (u64_stats_fetch_retry_irq(&lp->rx_stat_sync, start)); ++ } while (u64_stats_fetch_retry(&lp->rx_stat_sync, start)); + + do { +- start = u64_stats_fetch_begin_irq(&lp->tx_stat_sync); ++ start = u64_stats_fetch_begin(&lp->tx_stat_sync); + stats->tx_packets = u64_stats_read(&lp->tx_packets); + stats->tx_bytes = u64_stats_read(&lp->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&lp->tx_stat_sync, start)); ++ } while (u64_stats_fetch_retry(&lp->tx_stat_sync, start)); + } + + static const struct net_device_ops axienet_netdev_ops = { +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -1264,12 +1264,12 @@ static void netvsc_get_vf_stats(struct n + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + rx_packets = stats->rx_packets; + tx_packets = stats->tx_packets; + rx_bytes = stats->rx_bytes; + tx_bytes = stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + tot->rx_packets += rx_packets; + tot->tx_packets += tx_packets; +@@ -1294,12 +1294,12 @@ static void netvsc_get_pcpu_stats(struct + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + this_tot->vf_rx_packets = stats->rx_packets; + this_tot->vf_tx_packets = stats->tx_packets; + this_tot->vf_rx_bytes = stats->rx_bytes; + this_tot->vf_tx_bytes = stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + this_tot->rx_packets = this_tot->vf_rx_packets; + this_tot->tx_packets = this_tot->vf_tx_packets; + this_tot->rx_bytes = this_tot->vf_rx_bytes; +@@ -1318,20 +1318,20 @@ static void netvsc_get_pcpu_stats(struct + + tx_stats = &nvchan->tx_stats; + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + this_tot->tx_bytes += bytes; + this_tot->tx_packets += packets; + + rx_stats = &nvchan->rx_stats; + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + this_tot->rx_bytes += bytes; + this_tot->rx_packets += packets; +@@ -1370,21 +1370,21 @@ static void netvsc_get_stats64(struct ne + + tx_stats = &nvchan->tx_stats; + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + t->tx_bytes += bytes; + t->tx_packets += packets; + + rx_stats = &nvchan->rx_stats; + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; + multicast = rx_stats->multicast + rx_stats->broadcast; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + t->rx_bytes += bytes; + t->rx_packets += packets; +@@ -1527,24 +1527,24 @@ static void netvsc_get_ethtool_stats(str + tx_stats = &nvdev->chan_table[j].tx_stats; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; + xdp_xmit = tx_stats->xdp_xmit; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + data[i++] = packets; + data[i++] = bytes; + data[i++] = xdp_xmit; + + rx_stats = &nvdev->chan_table[j].rx_stats; + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; + xdp_drop = rx_stats->xdp_drop; + xdp_redirect = rx_stats->xdp_redirect; + xdp_tx = rx_stats->xdp_tx; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + data[i++] = packets; + data[i++] = bytes; + data[i++] = xdp_drop; +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -162,18 +162,18 @@ static void ifb_stats64(struct net_devic + + for (i = 0; i < dev->num_tx_queues; i++,txp++) { + do { +- start = u64_stats_fetch_begin_irq(&txp->rx_stats.sync); ++ start = u64_stats_fetch_begin(&txp->rx_stats.sync); + packets = txp->rx_stats.packets; + bytes = txp->rx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&txp->rx_stats.sync, start)); ++ } while (u64_stats_fetch_retry(&txp->rx_stats.sync, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; + + do { +- start = u64_stats_fetch_begin_irq(&txp->tx_stats.sync); ++ start = u64_stats_fetch_begin(&txp->tx_stats.sync); + packets = txp->tx_stats.packets; + bytes = txp->tx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&txp->tx_stats.sync, start)); ++ } while (u64_stats_fetch_retry(&txp->tx_stats.sync, start)); + stats->tx_packets += packets; + stats->tx_bytes += bytes; + } +@@ -245,12 +245,12 @@ static void ifb_fill_stats_data(u64 **da + int j; + + do { +- start = u64_stats_fetch_begin_irq(&q_stats->sync); ++ start = u64_stats_fetch_begin(&q_stats->sync); + for (j = 0; j < IFB_Q_STATS_LEN; j++) { + offset = ifb_q_stats_desc[j].offset; + (*data)[j] = *(u64 *)(stats_base + offset); + } +- } while (u64_stats_fetch_retry_irq(&q_stats->sync, start)); ++ } while (u64_stats_fetch_retry(&q_stats->sync, start)); + + *data += IFB_Q_STATS_LEN; + } +--- a/drivers/net/ipvlan/ipvlan_main.c ++++ b/drivers/net/ipvlan/ipvlan_main.c +@@ -301,13 +301,13 @@ static void ipvlan_get_stats64(struct ne + for_each_possible_cpu(idx) { + pcptr = per_cpu_ptr(ipvlan->pcpu_stats, idx); + do { +- strt= u64_stats_fetch_begin_irq(&pcptr->syncp); ++ strt = u64_stats_fetch_begin(&pcptr->syncp); + rx_pkts = u64_stats_read(&pcptr->rx_pkts); + rx_bytes = u64_stats_read(&pcptr->rx_bytes); + rx_mcast = u64_stats_read(&pcptr->rx_mcast); + tx_pkts = u64_stats_read(&pcptr->tx_pkts); + tx_bytes = u64_stats_read(&pcptr->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&pcptr->syncp, ++ } while (u64_stats_fetch_retry(&pcptr->syncp, + strt)); + + s->rx_packets += rx_pkts; +--- a/drivers/net/loopback.c ++++ b/drivers/net/loopback.c +@@ -106,10 +106,10 @@ void dev_lstats_read(struct net_device * + + lb_stats = per_cpu_ptr(dev->lstats, i); + do { +- start = u64_stats_fetch_begin_irq(&lb_stats->syncp); ++ start = u64_stats_fetch_begin(&lb_stats->syncp); + tpackets = u64_stats_read(&lb_stats->packets); + tbytes = u64_stats_read(&lb_stats->bytes); +- } while (u64_stats_fetch_retry_irq(&lb_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&lb_stats->syncp, start)); + *bytes += tbytes; + *packets += tpackets; + } +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -2793,9 +2793,9 @@ static void get_rx_sc_stats(struct net_d + + stats = per_cpu_ptr(rx_sc->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + memcpy(&tmp, &stats->stats, sizeof(tmp)); +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + sum->InOctetsValidated += tmp.InOctetsValidated; + sum->InOctetsDecrypted += tmp.InOctetsDecrypted; +@@ -2874,9 +2874,9 @@ static void get_tx_sc_stats(struct net_d + + stats = per_cpu_ptr(macsec_priv(dev)->secy.tx_sc.stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + memcpy(&tmp, &stats->stats, sizeof(tmp)); +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + sum->OutPktsProtected += tmp.OutPktsProtected; + sum->OutPktsEncrypted += tmp.OutPktsEncrypted; +@@ -2930,9 +2930,9 @@ static void get_secy_stats(struct net_de + + stats = per_cpu_ptr(macsec_priv(dev)->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + memcpy(&tmp, &stats->stats, sizeof(tmp)); +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + sum->OutPktsUntagged += tmp.OutPktsUntagged; + sum->InPktsUntagged += tmp.InPktsUntagged; +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -948,13 +948,13 @@ static void macvlan_dev_get_stats64(stru + for_each_possible_cpu(i) { + p = per_cpu_ptr(vlan->pcpu_stats, i); + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + rx_packets = u64_stats_read(&p->rx_packets); + rx_bytes = u64_stats_read(&p->rx_bytes); + rx_multicast = u64_stats_read(&p->rx_multicast); + tx_packets = u64_stats_read(&p->tx_packets); + tx_bytes = u64_stats_read(&p->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +--- a/drivers/net/mhi_net.c ++++ b/drivers/net/mhi_net.c +@@ -104,19 +104,19 @@ static void mhi_ndo_get_stats64(struct n + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&mhi_netdev->stats.rx_syncp); ++ start = u64_stats_fetch_begin(&mhi_netdev->stats.rx_syncp); + stats->rx_packets = u64_stats_read(&mhi_netdev->stats.rx_packets); + stats->rx_bytes = u64_stats_read(&mhi_netdev->stats.rx_bytes); + stats->rx_errors = u64_stats_read(&mhi_netdev->stats.rx_errors); +- } while (u64_stats_fetch_retry_irq(&mhi_netdev->stats.rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&mhi_netdev->stats.rx_syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&mhi_netdev->stats.tx_syncp); ++ start = u64_stats_fetch_begin(&mhi_netdev->stats.tx_syncp); + stats->tx_packets = u64_stats_read(&mhi_netdev->stats.tx_packets); + stats->tx_bytes = u64_stats_read(&mhi_netdev->stats.tx_bytes); + stats->tx_errors = u64_stats_read(&mhi_netdev->stats.tx_errors); + stats->tx_dropped = u64_stats_read(&mhi_netdev->stats.tx_dropped); +- } while (u64_stats_fetch_retry_irq(&mhi_netdev->stats.tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&mhi_netdev->stats.tx_syncp, start)); + } + + static const struct net_device_ops mhi_netdev_ops = { +--- a/drivers/net/netdevsim/netdev.c ++++ b/drivers/net/netdevsim/netdev.c +@@ -67,10 +67,10 @@ nsim_get_stats64(struct net_device *dev, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&ns->syncp); ++ start = u64_stats_fetch_begin(&ns->syncp); + stats->tx_bytes = ns->tx_bytes; + stats->tx_packets = ns->tx_packets; +- } while (u64_stats_fetch_retry_irq(&ns->syncp, start)); ++ } while (u64_stats_fetch_retry(&ns->syncp, start)); + } + + static int +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -1865,13 +1865,13 @@ team_get_stats64(struct net_device *dev, + for_each_possible_cpu(i) { + p = per_cpu_ptr(team->pcpu_stats, i); + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + rx_packets = u64_stats_read(&p->rx_packets); + rx_bytes = u64_stats_read(&p->rx_bytes); + rx_multicast = u64_stats_read(&p->rx_multicast); + tx_packets = u64_stats_read(&p->tx_packets); + tx_bytes = u64_stats_read(&p->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +--- a/drivers/net/team/team_mode_loadbalance.c ++++ b/drivers/net/team/team_mode_loadbalance.c +@@ -466,9 +466,9 @@ static void __lb_one_cpu_stats_add(struc + struct lb_stats tmp; + + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + tmp.tx_bytes = cpu_stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + acc_stats->tx_bytes += tmp.tx_bytes; + } + +--- a/drivers/net/veth.c ++++ b/drivers/net/veth.c +@@ -182,12 +182,12 @@ static void veth_get_ethtool_stats(struc + size_t offset; + + do { +- start = u64_stats_fetch_begin_irq(&rq_stats->syncp); ++ start = u64_stats_fetch_begin(&rq_stats->syncp); + for (j = 0; j < VETH_RQ_STATS_LEN; j++) { + offset = veth_rq_stats_desc[j].offset; + data[idx + j] = *(u64 *)(stats_base + offset); + } +- } while (u64_stats_fetch_retry_irq(&rq_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rq_stats->syncp, start)); + idx += VETH_RQ_STATS_LEN; + } + +@@ -203,12 +203,12 @@ static void veth_get_ethtool_stats(struc + + tx_idx += (i % dev->real_num_tx_queues) * VETH_TQ_STATS_LEN; + do { +- start = u64_stats_fetch_begin_irq(&rq_stats->syncp); ++ start = u64_stats_fetch_begin(&rq_stats->syncp); + for (j = 0; j < VETH_TQ_STATS_LEN; j++) { + offset = veth_tq_stats_desc[j].offset; + data[tx_idx + j] += *(u64 *)(base + offset); + } +- } while (u64_stats_fetch_retry_irq(&rq_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rq_stats->syncp, start)); + } + } + +@@ -379,13 +379,13 @@ static void veth_stats_rx(struct veth_st + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + peer_tq_xdp_xmit_err = stats->vs.peer_tq_xdp_xmit_err; + xdp_tx_err = stats->vs.xdp_tx_err; + packets = stats->vs.xdp_packets; + bytes = stats->vs.xdp_bytes; + drops = stats->vs.rx_drops; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + result->peer_tq_xdp_xmit_err += peer_tq_xdp_xmit_err; + result->xdp_tx_err += xdp_tx_err; + result->xdp_packets += packets; +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -2069,18 +2069,18 @@ static void virtnet_stats(struct net_dev + struct send_queue *sq = &vi->sq[i]; + + do { +- start = u64_stats_fetch_begin_irq(&sq->stats.syncp); ++ start = u64_stats_fetch_begin(&sq->stats.syncp); + tpackets = sq->stats.packets; + tbytes = sq->stats.bytes; + terrors = sq->stats.tx_timeouts; +- } while (u64_stats_fetch_retry_irq(&sq->stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&rq->stats.syncp); ++ start = u64_stats_fetch_begin(&rq->stats.syncp); + rpackets = rq->stats.packets; + rbytes = rq->stats.bytes; + rdrops = rq->stats.drops; +- } while (u64_stats_fetch_retry_irq(&rq->stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&rq->stats.syncp, start)); + + tot->rx_packets += rpackets; + tot->tx_packets += tpackets; +@@ -2691,12 +2691,12 @@ static void virtnet_get_ethtool_stats(st + + stats_base = (u8 *)&rq->stats; + do { +- start = u64_stats_fetch_begin_irq(&rq->stats.syncp); ++ start = u64_stats_fetch_begin(&rq->stats.syncp); + for (j = 0; j < VIRTNET_RQ_STATS_LEN; j++) { + offset = virtnet_rq_stats_desc[j].offset; + data[idx + j] = *(u64 *)(stats_base + offset); + } +- } while (u64_stats_fetch_retry_irq(&rq->stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&rq->stats.syncp, start)); + idx += VIRTNET_RQ_STATS_LEN; + } + +@@ -2705,12 +2705,12 @@ static void virtnet_get_ethtool_stats(st + + stats_base = (u8 *)&sq->stats; + do { +- start = u64_stats_fetch_begin_irq(&sq->stats.syncp); ++ start = u64_stats_fetch_begin(&sq->stats.syncp); + for (j = 0; j < VIRTNET_SQ_STATS_LEN; j++) { + offset = virtnet_sq_stats_desc[j].offset; + data[idx + j] = *(u64 *)(stats_base + offset); + } +- } while (u64_stats_fetch_retry_irq(&sq->stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); + idx += VIRTNET_SQ_STATS_LEN; + } + } +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -159,13 +159,13 @@ static void vrf_get_stats64(struct net_d + + dstats = per_cpu_ptr(dev->dstats, i); + do { +- start = u64_stats_fetch_begin_irq(&dstats->syncp); ++ start = u64_stats_fetch_begin(&dstats->syncp); + tbytes = dstats->tx_bytes; + tpkts = dstats->tx_pkts; + tdrops = dstats->tx_drps; + rbytes = dstats->rx_bytes; + rpkts = dstats->rx_pkts; +- } while (u64_stats_fetch_retry_irq(&dstats->syncp, start)); ++ } while (u64_stats_fetch_retry(&dstats->syncp, start)); + stats->tx_bytes += tbytes; + stats->tx_packets += tpkts; + stats->tx_dropped += tdrops; +--- a/drivers/net/vxlan/vxlan_vnifilter.c ++++ b/drivers/net/vxlan/vxlan_vnifilter.c +@@ -129,9 +129,9 @@ static void vxlan_vnifilter_stats_get(co + + pstats = per_cpu_ptr(vninode->stats, i); + do { +- start = u64_stats_fetch_begin_irq(&pstats->syncp); ++ start = u64_stats_fetch_begin(&pstats->syncp); + memcpy(&temp, &pstats->stats, sizeof(temp)); +- } while (u64_stats_fetch_retry_irq(&pstats->syncp, start)); ++ } while (u64_stats_fetch_retry(&pstats->syncp, start)); + + dest->rx_packets += temp.rx_packets; + dest->rx_bytes += temp.rx_bytes; +--- a/drivers/net/wwan/mhi_wwan_mbim.c ++++ b/drivers/net/wwan/mhi_wwan_mbim.c +@@ -456,19 +456,19 @@ static void mhi_mbim_ndo_get_stats64(str + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&link->rx_syncp); ++ start = u64_stats_fetch_begin(&link->rx_syncp); + stats->rx_packets = u64_stats_read(&link->rx_packets); + stats->rx_bytes = u64_stats_read(&link->rx_bytes); + stats->rx_errors = u64_stats_read(&link->rx_errors); +- } while (u64_stats_fetch_retry_irq(&link->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&link->rx_syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&link->tx_syncp); ++ start = u64_stats_fetch_begin(&link->tx_syncp); + stats->tx_packets = u64_stats_read(&link->tx_packets); + stats->tx_bytes = u64_stats_read(&link->tx_bytes); + stats->tx_errors = u64_stats_read(&link->tx_errors); + stats->tx_dropped = u64_stats_read(&link->tx_dropped); +- } while (u64_stats_fetch_retry_irq(&link->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&link->tx_syncp, start)); + } + + static void mhi_mbim_ul_callback(struct mhi_device *mhi_dev, +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1392,16 +1392,16 @@ static void xennet_get_stats64(struct ne + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + tx_packets = tx_stats->packets; + tx_bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + rx_packets = rx_stats->packets; + rx_bytes = rx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + tot->rx_packets += rx_packets; + tot->tx_packets += tx_packets; diff --git a/target/linux/generic/backport-6.1/102-drivers-net-convert-to-boolean-for-the-mac_managed_p.patch b/target/linux/generic/backport-6.1/102-drivers-net-convert-to-boolean-for-the-mac_managed_p.patch new file mode 100644 index 000000000..62715a3db --- /dev/null +++ b/target/linux/generic/backport-6.1/102-drivers-net-convert-to-boolean-for-the-mac_managed_p.patch @@ -0,0 +1,56 @@ +From fd4f7a449938ffd21bf2f5a1708d811cc5f3daa5 Mon Sep 17 00:00:00 2001 +From: Denis Kirjanov +Date: Thu, 27 Oct 2022 21:45:02 +0300 +Subject: [PATCH 2/4] drivers: net: convert to boolean for the mac_managed_pm + flag + +Signed-off-by: Dennis Kirjanov +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/freescale/fec_main.c | 2 +- + drivers/net/ethernet/realtek/r8169_main.c | 2 +- + drivers/net/usb/asix_devices.c | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -2226,7 +2226,7 @@ static int fec_enet_mii_probe(struct net + fep->link = 0; + fep->full_duplex = 0; + +- phy_dev->mac_managed_pm = 1; ++ phy_dev->mac_managed_pm = true; + + phy_attached_info(phy_dev); + +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -5018,7 +5018,7 @@ static int r8169_mdio_register(struct rt + return -EUNATCH; + } + +- tp->phydev->mac_managed_pm = 1; ++ tp->phydev->mac_managed_pm = true; + + phy_support_asym_pause(tp->phydev); + +--- a/drivers/net/usb/asix_devices.c ++++ b/drivers/net/usb/asix_devices.c +@@ -700,7 +700,7 @@ static int ax88772_init_phy(struct usbne + } + + phy_suspend(priv->phydev); +- priv->phydev->mac_managed_pm = 1; ++ priv->phydev->mac_managed_pm = true; + + phy_attached_info(priv->phydev); + +@@ -720,7 +720,7 @@ static int ax88772_init_phy(struct usbne + return -ENODEV; + } + +- priv->phydev_int->mac_managed_pm = 1; ++ priv->phydev_int->mac_managed_pm = true; + phy_suspend(priv->phydev_int); + + return 0; diff --git a/target/linux/generic/backport-6.1/103-r8169-use-tp_to_dev-instead-of-open-code.patch b/target/linux/generic/backport-6.1/103-r8169-use-tp_to_dev-instead-of-open-code.patch new file mode 100644 index 000000000..e151cc6dd --- /dev/null +++ b/target/linux/generic/backport-6.1/103-r8169-use-tp_to_dev-instead-of-open-code.patch @@ -0,0 +1,38 @@ +From fd149c4ab09b01136c7e80db020eed59a3385d24 Mon Sep 17 00:00:00 2001 +From: Juhee Kang +Date: Wed, 30 Nov 2022 01:12:44 +0900 +Subject: [PATCH 3/4] r8169: use tp_to_dev instead of open code + +The open code is defined as a helper function(tp_to_dev) on r8169_main.c, +which the open code is &tp->pci_dev->dev. The helper function was added +in commit 1e1205b7d3e9 ("r8169: add helper tp_to_dev"). And then later, +commit f1e911d5d0df ("r8169: add basic phylib support") added +r8169_phylink_handler function but it didn't use the helper function. +Thus, tp_to_dev() replaces the open code. This patch doesn't change logic. + +Signed-off-by: Juhee Kang +Reviewed-by: Heiner Kallweit +Link: https://lore.kernel.org/r/20221129161244.5356-1-claudiajkang@gmail.com +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/realtek/r8169_main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -4559,12 +4559,13 @@ static int rtl8169_poll(struct napi_stru + static void r8169_phylink_handler(struct net_device *ndev) + { + struct rtl8169_private *tp = netdev_priv(ndev); ++ struct device *d = tp_to_dev(tp); + + if (netif_carrier_ok(ndev)) { + rtl_link_chg_patch(tp); +- pm_request_resume(&tp->pci_dev->dev); ++ pm_request_resume(d); + } else { +- pm_runtime_idle(&tp->pci_dev->dev); ++ pm_runtime_idle(d); + } + + phy_print_status(tp->phydev); diff --git a/target/linux/generic/backport-6.1/104-r8169-enable-GRO-software-interrupt-coalescing-per-d.patch b/target/linux/generic/backport-6.1/104-r8169-enable-GRO-software-interrupt-coalescing-per-d.patch new file mode 100644 index 000000000..5108e82df --- /dev/null +++ b/target/linux/generic/backport-6.1/104-r8169-enable-GRO-software-interrupt-coalescing-per-d.patch @@ -0,0 +1,33 @@ +From 74ec605a11b7ecf68036c3f086f684bbe7381353 Mon Sep 17 00:00:00 2001 +From: Heiner Kallweit +Date: Wed, 30 Nov 2022 23:30:15 +0100 +Subject: [PATCH 4/4] r8169: enable GRO software interrupt coalescing per + default + +There are reports about r8169 not reaching full line speed on certain +systems (e.g. SBC's) with a 2.5Gbps link. +There was a time when hardware interrupt coalescing was enabled per +default, but this was changed due to ASPM-related issues on few systems. +So let's use software interrupt coalescing instead and enable it +using new function netdev_sw_irq_coalesce_default_on(). + +Even with these conservative settings interrupt load on my 1Gbps test +system reduced significantly. + +Signed-off-by: Heiner Kallweit +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/realtek/r8169_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -5283,6 +5283,8 @@ static int rtl_init_one(struct pci_dev * + dev->hw_features |= NETIF_F_RXALL; + dev->hw_features |= NETIF_F_RXFCS; + ++ netdev_sw_irq_coalesce_default_on(dev); ++ + /* configure chip for default features */ + rtl8169_set_features(dev, dev->features); + diff --git a/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch b/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch new file mode 100644 index 000000000..eb6be5ed0 --- /dev/null +++ b/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch @@ -0,0 +1,65 @@ +From 63db0cb35e1cb3b3c134906d1062f65513fdda2d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 4 Oct 2022 10:37:09 +0200 +Subject: [PATCH] mtd: core: simplify (a bit) code find partition-matching + dynamic OF node +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1. Don't hardcode "partition-" string twice +2. Use simpler logic & use ->name to avoid of_property_read_string() +3. Use mtd_get_of_node() helper + +Cc: Christian Marangi +Signed-off-by: RafaÅ‚ MiÅ‚ecki +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-1-zajec5@gmail.com +--- + drivers/mtd/mtdcore.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -551,18 +551,16 @@ static void mtd_check_of_node(struct mtd + struct device_node *partitions, *parent_dn, *mtd_dn = NULL; + const char *pname, *prefix = "partition-"; + int plen, mtd_name_len, offset, prefix_len; +- struct mtd_info *parent; + bool found = false; + + /* Check if MTD already has a device node */ +- if (dev_of_node(&mtd->dev)) ++ if (mtd_get_of_node(mtd)) + return; + + /* Check if a partitions node exist */ + if (!mtd_is_partition(mtd)) + return; +- parent = mtd->parent; +- parent_dn = of_node_get(dev_of_node(&parent->dev)); ++ parent_dn = of_node_get(mtd_get_of_node(mtd->parent)); + if (!parent_dn) + return; + +@@ -575,15 +573,15 @@ static void mtd_check_of_node(struct mtd + + /* Search if a partition is defined with the same name */ + for_each_child_of_node(partitions, mtd_dn) { +- offset = 0; +- + /* Skip partition with no/wrong prefix */ +- if (!of_node_name_prefix(mtd_dn, "partition-")) ++ if (!of_node_name_prefix(mtd_dn, prefix)) + continue; + + /* Label have priority. Check that first */ +- if (of_property_read_string(mtd_dn, "label", &pname)) { +- of_property_read_string(mtd_dn, "name", &pname); ++ if (!of_property_read_string(mtd_dn, "label", &pname)) { ++ offset = 0; ++ } else { ++ pname = mtd_dn->name; + offset = prefix_len; + } + diff --git a/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch b/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch new file mode 100644 index 000000000..f8d3a370d --- /dev/null +++ b/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch @@ -0,0 +1,84 @@ +From ddb8cefb7af288950447ca6eeeafb09977dab56f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 4 Oct 2022 10:37:10 +0200 +Subject: [PATCH] mtd: core: try to find OF node for every MTD partition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So far this feature was limited to the top-level "nvmem-cells" node. +There are multiple parsers creating partitions and subpartitions +dynamically. Extend that code to handle them too. + +This allows finding partition-* node for every MTD (sub)partition. + +Random example: + +partitions { + compatible = "brcm,bcm947xx-cfe-partitions"; + + partition-firmware { + compatible = "brcm,trx"; + + partition-loader { + }; + }; +}; + +Cc: Christian Marangi +Signed-off-by: RafaÅ‚ MiÅ‚ecki +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-2-zajec5@gmail.com +--- + drivers/mtd/mtdcore.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -551,20 +551,22 @@ static void mtd_check_of_node(struct mtd + struct device_node *partitions, *parent_dn, *mtd_dn = NULL; + const char *pname, *prefix = "partition-"; + int plen, mtd_name_len, offset, prefix_len; +- bool found = false; + + /* Check if MTD already has a device node */ + if (mtd_get_of_node(mtd)) + return; + +- /* Check if a partitions node exist */ + if (!mtd_is_partition(mtd)) + return; ++ + parent_dn = of_node_get(mtd_get_of_node(mtd->parent)); + if (!parent_dn) + return; + +- partitions = of_get_child_by_name(parent_dn, "partitions"); ++ if (mtd_is_partition(mtd->parent)) ++ partitions = of_node_get(parent_dn); ++ else ++ partitions = of_get_child_by_name(parent_dn, "partitions"); + if (!partitions) + goto exit_parent; + +@@ -588,19 +590,11 @@ static void mtd_check_of_node(struct mtd + plen = strlen(pname) - offset; + if (plen == mtd_name_len && + !strncmp(mtd->name, pname + offset, plen)) { +- found = true; ++ mtd_set_of_node(mtd, mtd_dn); + break; + } + } + +- if (!found) +- goto exit_partitions; +- +- /* Set of_node only for nvmem */ +- if (of_device_is_compatible(mtd_dn, "nvmem-cells")) +- mtd_set_of_node(mtd, mtd_dn); +- +-exit_partitions: + of_node_put(partitions); + exit_parent: + of_node_put(parent_dn); diff --git a/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch b/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch new file mode 100644 index 000000000..e570564a0 --- /dev/null +++ b/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch @@ -0,0 +1,229 @@ +From aec4d5f5ffd0f0092bd9dc21ea90e0bc237d4b74 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sat, 15 Oct 2022 11:29:50 +0200 +Subject: [PATCH] mtd: parsers: add TP-Link SafeLoader partitions table parser +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This parser deals with most TP-Link home routers. It reads info about +partitions and registers them in the MTD subsystem. + +Example from TP-Link Archer C5 V2: + +spi-nor spi0.0: s25fl128s1 (16384 Kbytes) +15 tplink-safeloader partitions found on MTD device spi0.0 +Creating 15 MTD partitions on "spi0.0": +0x000000000000-0x000000040000 : "fs-uboot" +0x000000040000-0x000000440000 : "os-image" +0x000000440000-0x000000e40000 : "rootfs" +0x000000e40000-0x000000e40200 : "default-mac" +0x000000e40200-0x000000e40400 : "pin" +0x000000e40400-0x000000e40600 : "product-info" +0x000000e50000-0x000000e60000 : "partition-table" +0x000000e60000-0x000000e60200 : "soft-version" +0x000000e61000-0x000000e70000 : "support-list" +0x000000e70000-0x000000e80000 : "profile" +0x000000e80000-0x000000e90000 : "default-config" +0x000000e90000-0x000000ee0000 : "user-config" +0x000000ee0000-0x000000fe0000 : "log" +0x000000fe0000-0x000000ff0000 : "radio_bk" +0x000000ff0000-0x000001000000 : "radio" + +Signed-off-by: RafaÅ‚ MiÅ‚ecki +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com +--- + drivers/mtd/parsers/Kconfig | 15 +++ + drivers/mtd/parsers/Makefile | 1 + + drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++ + 3 files changed, 166 insertions(+) + create mode 100644 drivers/mtd/parsers/tplink_safeloader.c + +--- a/drivers/mtd/parsers/Kconfig ++++ b/drivers/mtd/parsers/Kconfig +@@ -123,6 +123,21 @@ config MTD_AFS_PARTS + for your particular device. It won't happen automatically. The + 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. + ++config MTD_PARSER_TPLINK_SAFELOADER ++ tristate "TP-Link Safeloader partitions parser" ++ depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST) ++ help ++ TP-Link home routers use flash partitions to store various data. Info ++ about flash space layout is stored in a partitions table using a ++ custom ASCII-based format. ++ ++ That format was first found in devices with SafeLoader bootloader and ++ was named after it. Later it was adapted to CFE and U-Boot ++ bootloaders. ++ ++ This driver reads partitions table, parses it and creates MTD ++ partitions. ++ + config MTD_PARSER_TRX + tristate "Parser for TRX format partitions" + depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST) +--- a/drivers/mtd/parsers/Makefile ++++ b/drivers/mtd/parsers/Makefile +@@ -10,6 +10,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += + ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o + obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o ++obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o + obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o + obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o + obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o +--- /dev/null ++++ b/drivers/mtd/parsers/tplink_safeloader.c +@@ -0,0 +1,150 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright © 2022 RafaÅ‚ MiÅ‚ecki ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define TPLINK_SAFELOADER_DATA_OFFSET 4 ++#define TPLINK_SAFELOADER_MAX_PARTS 32 ++ ++struct safeloader_cmn_header { ++ __be32 size; ++ uint32_t unused; ++} __packed; ++ ++static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) ++{ ++ struct safeloader_cmn_header hdr; ++ struct device_node *np; ++ size_t bytes_read; ++ size_t offset; ++ size_t size; ++ char *buf; ++ int err; ++ ++ np = mtd_get_of_node(mtd); ++ if (mtd_is_partition(mtd)) ++ of_node_get(np); ++ else ++ np = of_get_child_by_name(np, "partitions"); ++ ++ if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) { ++ pr_err("Failed to get partitions table offset\n"); ++ goto err_put; ++ } ++ ++ err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr); ++ if (err && !mtd_is_bitflip(err)) { ++ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset); ++ goto err_put; ++ } ++ ++ size = be32_to_cpu(hdr.size); ++ ++ buf = kmalloc(size + 1, GFP_KERNEL); ++ if (!buf) ++ goto err_put; ++ ++ err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf); ++ if (err && !mtd_is_bitflip(err)) { ++ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr)); ++ goto err_kfree; ++ } ++ ++ buf[size] = '\0'; ++ ++ of_node_put(np); ++ ++ return buf; ++ ++err_kfree: ++ kfree(buf); ++err_put: ++ of_node_put(np); ++ return NULL; ++} ++ ++static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd, ++ const struct mtd_partition **pparts, ++ struct mtd_part_parser_data *data) ++{ ++ struct mtd_partition *parts; ++ char name[65]; ++ size_t offset; ++ size_t bytes; ++ char *buf; ++ int idx; ++ int err; ++ ++ parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL); ++ if (!parts) { ++ err = -ENOMEM; ++ goto err_out; ++ } ++ ++ buf = mtd_parser_tplink_safeloader_read_table(mtd); ++ if (!buf) { ++ err = -ENOENT; ++ goto err_out; ++ } ++ ++ for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET; ++ idx < TPLINK_SAFELOADER_MAX_PARTS && ++ sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n", ++ name, &parts[idx].offset, &parts[idx].size, &bytes) == 3; ++ idx++, offset += bytes + 1) { ++ parts[idx].name = kstrdup(name, GFP_KERNEL); ++ if (!parts[idx].name) { ++ err = -ENOMEM; ++ goto err_free; ++ } ++ } ++ ++ if (idx == TPLINK_SAFELOADER_MAX_PARTS) ++ pr_warn("Reached maximum number of partitions!\n"); ++ ++ kfree(buf); ++ ++ *pparts = parts; ++ ++ return idx; ++ ++err_free: ++ for (idx -= 1; idx >= 0; idx--) ++ kfree(parts[idx].name); ++err_out: ++ return err; ++}; ++ ++static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts, ++ int nr_parts) ++{ ++ int i; ++ ++ for (i = 0; i < nr_parts; i++) ++ kfree(pparts[i].name); ++ ++ kfree(pparts); ++} ++ ++static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = { ++ { .compatible = "tplink,safeloader-partitions" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table); ++ ++static struct mtd_part_parser mtd_parser_tplink_safeloader = { ++ .parse_fn = mtd_parser_tplink_safeloader_parse, ++ .cleanup = mtd_parser_tplink_safeloader_cleanup, ++ .name = "tplink-safeloader", ++ .of_match_table = mtd_parser_tplink_safeloader_of_match_table, ++}; ++module_mtd_part_parser(mtd_parser_tplink_safeloader); ++ ++MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/config-6.0 b/target/linux/generic/config-6.1 similarity index 94% rename from target/linux/generic/config-6.0 rename to target/linux/generic/config-6.1 index f5bb5afa8..4c9ec4263 100644 --- a/target/linux/generic/config-6.0 +++ b/target/linux/generic/config-6.1 @@ -18,6 +18,7 @@ CONFIG_64BIT_TIME=y # CONFIG_ACORN_PARTITION is not set # CONFIG_ACPI_ALS is not set # CONFIG_ACPI_APEI is not set +# CONFIG_ACPI_APEI_PCIEAER is not set # CONFIG_ACPI_BUTTON is not set # CONFIG_ACPI_CONFIGFS is not set # CONFIG_ACPI_CUSTOM_METHOD is not set @@ -30,7 +31,9 @@ CONFIG_64BIT_TIME=y # CONFIG_AD2S1200 is not set # CONFIG_AD2S1210 is not set # CONFIG_AD2S90 is not set +# CONFIG_AD3552R is not set # CONFIG_AD5064 is not set +# CONFIG_AD5110 is not set # CONFIG_AD525X_DPOT is not set # CONFIG_AD5272 is not set # CONFIG_AD5360 is not set @@ -62,8 +65,10 @@ CONFIG_64BIT_TIME=y # CONFIG_AD7280 is not set # CONFIG_AD7291 is not set # CONFIG_AD7292 is not set +# CONFIG_AD7293 is not set # CONFIG_AD7298 is not set # CONFIG_AD7303 is not set +# CONFIG_AD74413R is not set # CONFIG_AD7476 is not set # CONFIG_AD7606 is not set # CONFIG_AD7606_IFACE_PARALLEL is not set @@ -85,12 +90,14 @@ CONFIG_64BIT_TIME=y # CONFIG_AD9523 is not set # CONFIG_AD9832 is not set # CONFIG_AD9834 is not set +# CONFIG_ADA4250 is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_ADE7854 is not set # CONFIG_ADF4350 is not set # CONFIG_ADF4371 is not set # CONFIG_ADFS_FS is not set # CONFIG_ADIN1100_PHY is not set +# CONFIG_ADIN1110 is not set # CONFIG_ADIN_PHY is not set # CONFIG_ADIS16080 is not set # CONFIG_ADIS16130 is not set @@ -108,12 +115,23 @@ CONFIG_64BIT_TIME=y # CONFIG_ADJD_S311 is not set # CONFIG_ADM6996_PHY is not set # CONFIG_ADM8211 is not set +# CONFIG_ADMV1013 is not set +# CONFIG_ADMV1014 is not set +# CONFIG_ADMV4420 is not set +# CONFIG_ADMV8818 is not set +# CONFIG_ADRF6780 is not set # CONFIG_ADT7316 is not set # CONFIG_ADUX1020 is not set CONFIG_ADVISE_SYSCALLS=y # CONFIG_ADV_SWBUTTON is not set +# CONFIG_ADXL313_I2C is not set +# CONFIG_ADXL313_SPI is not set # CONFIG_ADXL345_I2C is not set # CONFIG_ADXL345_SPI is not set +# CONFIG_ADXL355_I2C is not set +# CONFIG_ADXL355_SPI is not set +# CONFIG_ADXL367_I2C is not set +# CONFIG_ADXL367_SPI is not set # CONFIG_ADXL372_I2C is not set # CONFIG_ADXL372_SPI is not set # CONFIG_ADXRS290 is not set @@ -128,12 +146,14 @@ CONFIG_AEABI=y # CONFIG_AF_RXRPC is not set # CONFIG_AF_RXRPC_INJECT_LOSS is not set # CONFIG_AF_RXRPC_IPV6 is not set -# CONFIG_AF_UNIX_OOB is not set +CONFIG_AF_UNIX_OOB=y # CONFIG_AGP is not set # CONFIG_AHCI_CEVA is not set +# CONFIG_AHCI_DWC is not set # CONFIG_AHCI_IMX is not set # CONFIG_AHCI_MVEBU is not set # CONFIG_AHCI_QORIQ is not set +# CONFIG_AHCI_XGENE is not set CONFIG_AIO=y # CONFIG_AIRO is not set # CONFIG_AIRO_CS is not set @@ -169,6 +189,7 @@ CONFIG_ANON_INODES=y # CONFIG_APDS9300 is not set # CONFIG_APDS9802ALS is not set # CONFIG_APDS9960 is not set +# CONFIG_APERTURE_HELPERS is not set # CONFIG_APM8018X is not set # CONFIG_APM_EMULATION is not set # CONFIG_APPLE_AIC is not set @@ -184,6 +205,7 @@ CONFIG_ANON_INODES=y # CONFIG_AR8216_PHY_LEDS is not set # CONFIG_ARCH_ACTIONS is not set # CONFIG_ARCH_AGILEX is not set +# CONFIG_ARCH_AIROHA is not set # CONFIG_ARCH_ALPINE is not set # CONFIG_ARCH_APPLE is not set # CONFIG_ARCH_ARTPEC is not set @@ -204,6 +226,7 @@ CONFIG_ANON_INODES=y # CONFIG_ARCH_BCM_IPROC is not set # CONFIG_ARCH_BCM_NSP is not set # CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS is not set CONFIG_ARCH_BINFMT_ELF_STATE=y # CONFIG_ARCH_BITMAIN is not set # CONFIG_ARCH_BRCMSTB is not set @@ -223,6 +246,7 @@ CONFIG_ARCH_FLATMEM_ENABLE=y # CONFIG_ARCH_HI3xxx is not set # CONFIG_ARCH_HIGHBANK is not set # CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_HPE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_INTEL_SOCFPGA is not set # CONFIG_ARCH_IOP13XX is not set @@ -240,7 +264,7 @@ CONFIG_ARCH_FLATMEM_ENABLE=y # CONFIG_ARCH_MESON is not set # CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE is not set # CONFIG_ARCH_MILBEAUT is not set -CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS=8 CONFIG_ARCH_MMAP_RND_BITS_MAX=16 CONFIG_ARCH_MMAP_RND_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 @@ -259,6 +283,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_NPCM is not set # CONFIG_ARCH_NSPIRE is not set +# CONFIG_ARCH_NXP is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_OMAP1 is not set # CONFIG_ARCH_OMAP2 is not set @@ -292,6 +317,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARCH_STI is not set # CONFIG_ARCH_STM32 is not set # CONFIG_ARCH_STRATIX10 is not set +# CONFIG_ARCH_SUNPLUS is not set # CONFIG_ARCH_SUNXI is not set # CONFIG_ARCH_SYNQUACER is not set # CONFIG_ARCH_TANGO is not set @@ -342,7 +368,9 @@ CONFIG_ARM64_4K_PAGES=y # CONFIG_ARM64_ERRATUM_2054223 is not set # CONFIG_ARM64_ERRATUM_2067961 is not set # CONFIG_ARM64_ERRATUM_2077057 is not set +# CONFIG_ARM64_ERRATUM_2441007 is not set # CONFIG_ARM64_ERRATUM_2441009 is not set +# CONFIG_ARM64_ERRATUM_2658417 is not set # CONFIG_ARM64_ERRATUM_819472 is not set # CONFIG_ARM64_ERRATUM_824069 is not set # CONFIG_ARM64_ERRATUM_826319 is not set @@ -376,6 +404,8 @@ CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_ARM64_VA_BITS_39=y # CONFIG_ARM64_VA_BITS_48 is not set # CONFIG_ARM64_VHE is not set +# CONFIG_ARM64_WORKAROUND_REPEAT_TLBI is not set +# CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE is not set # CONFIG_ARM_APPENDED_DTB is not set # CONFIG_ARM_ARCH_TIMER is not set # CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set @@ -406,6 +436,7 @@ CONFIG_ARM_DMA_MEM_BUFFERABLE=y # CONFIG_ARM_ERRATA_751472 is not set # CONFIG_ARM_ERRATA_754322 is not set # CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764319 is not set # CONFIG_ARM_ERRATA_764369 is not set # CONFIG_ARM_ERRATA_773022 is not set # CONFIG_ARM_ERRATA_775420 is not set @@ -424,6 +455,7 @@ CONFIG_ARM_GIC_MAX_NR=1 # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set # CONFIG_ARM_KPROBES_TEST is not set # CONFIG_ARM_LPAE is not set +# CONFIG_ARM_MEDIATEK_CPUFREQ_HW is not set # CONFIG_ARM_MHU is not set # CONFIG_ARM_MHU_V2 is not set # CONFIG_ARM_MODULE_PLTS is not set @@ -435,7 +467,6 @@ CONFIG_ARM_GIC_MAX_NR=1 # CONFIG_ARM_SBSA_WATCHDOG is not set # CONFIG_ARM_SCMI_AVOID_FASTCHANNELS is not set # CONFIG_ARM_SCMI_POWER_CONTROL is not set -# CONFIG_ARM_SCMI_POWER_DOMAIN is not set # CONFIG_ARM_SCMI_PROTOCOL is not set # CONFIG_ARM_SCPI_PROTOCOL is not set # CONFIG_ARM_SDE_INTERFACE is not set @@ -535,6 +566,11 @@ CONFIG_ATM_CLIP_NO_ICMP=y # CONFIG_B43LEGACY is not set # CONFIG_B44 is not set # CONFIG_B53 is not set +# CONFIG_B53_MDIO_DRIVER is not set +# CONFIG_B53_MMAP_DRIVER is not set +# CONFIG_B53_SERDES is not set +# CONFIG_B53_SPI_DRIVER is not set +# CONFIG_B53_SRAB_DRIVER is not set # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set # CONFIG_BACKLIGHT_APPLE is not set @@ -557,6 +593,7 @@ CONFIG_ATM_CLIP_NO_ICMP=y # CONFIG_BACKLIGHT_RPI is not set # CONFIG_BACKLIGHT_SAHARA is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_BACKTRACE_VERBOSE is not set # CONFIG_BAREUDP is not set CONFIG_BASE_FULL=y CONFIG_BASE_SMALL=0 @@ -609,7 +646,7 @@ CONFIG_BCMA_POSSIBLE=y # CONFIG_BH1780 is not set # CONFIG_BIG_KEYS is not set # CONFIG_BIG_LITTLE is not set -# CONFIG_BINARY_PRINTF is not set +CONFIG_BINARY_PRINTF=y # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_ELF_FDPIC is not set @@ -644,6 +681,7 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_DELKIN is not set +# CONFIG_BLK_DEV_DM is not set # CONFIG_BLK_DEV_DRBD is not set # CONFIG_BLK_DEV_DTC2278 is not set # CONFIG_BLK_DEV_FD is not set @@ -667,6 +705,7 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_LOOP is not set CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_NULL_BLK is not set @@ -705,6 +744,7 @@ CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 # CONFIG_BLK_DEV_ZONED is not set # CONFIG_BLK_INLINE_ENCRYPTION is not set # CONFIG_BLK_SED_OPAL is not set +# CONFIG_BLK_USE_PIN_USER_PAGES_FOR_DIO is not set # CONFIG_BLK_WBT is not set CONFIG_BLOCK=y # CONFIG_BLOCK_LEGACY_AUTOLOAD is not set @@ -736,6 +776,8 @@ CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 # CONFIG_BOOT_CONFIG is not set # CONFIG_BOOT_PRINTK_DELAY is not set CONFIG_BOOT_RAW=y +# CONFIG_BOSCH_BNO055_I2C is not set +# CONFIG_BOSCH_BNO055_SERIAL is not set # CONFIG_BOUNCE is not set CONFIG_BPF=y # CONFIG_BPFILTER is not set @@ -832,6 +874,7 @@ CONFIG_BT_HCIUART_H4=y # CONFIG_BT_RFCOMM is not set CONFIG_BT_RFCOMM_TTY=y # CONFIG_BT_SELFTEST is not set +# CONFIG_BT_VIRTIO is not set CONFIG_BUG=y # CONFIG_BUG_ON_DATA_CORRUPTION is not set CONFIG_BUILDTIME_EXTABLE_SORT=y @@ -844,8 +887,12 @@ CONFIG_CACHE_L2X0_PMU=y # CONFIG_CAIF is not set # CONFIG_CAN is not set # CONFIG_CAN_BCM is not set +# CONFIG_CAN_CAN327 is not set +# CONFIG_CAN_CTUCANFD_PCI is not set +# CONFIG_CAN_CTUCANFD_PLATFORM is not set # CONFIG_CAN_DEBUG_DEVICES is not set # CONFIG_CAN_DEV is not set +# CONFIG_CAN_ESD_USB is not set # CONFIG_CAN_ETAS_ES58X is not set # CONFIG_CAN_GS_USB is not set # CONFIG_CAN_GW is not set @@ -857,6 +904,7 @@ CONFIG_CACHE_L2X0_PMU=y # CONFIG_CAN_MCBA_USB is not set # CONFIG_CAN_MCP251XFD is not set # CONFIG_CAN_M_CAN is not set +# CONFIG_CAN_NETLINK is not set # CONFIG_CAN_PEAK_PCIEFD is not set # CONFIG_CAN_RAW is not set # CONFIG_CAN_RCAR is not set @@ -894,6 +942,7 @@ CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CEPH_LIB is not set # CONFIG_CFG80211 is not set # CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_HEADERS=y # CONFIG_CGROUPS is not set # CONFIG_CGROUP_FAVOR_DYNMODS is not set # CONFIG_CGROUP_MISC is not set @@ -917,6 +966,7 @@ CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CHARGER_MANAGER is not set # CONFIG_CHARGER_MAX77976 is not set # CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_RK817 is not set # CONFIG_CHARGER_RT9455 is not set # CONFIG_CHARGER_SBS is not set # CONFIG_CHARGER_SMB347 is not set @@ -951,7 +1001,9 @@ CONFIG_CIFS_POSIX=y CONFIG_CIFS_XATTR=y # CONFIG_CIO_DAC is not set # CONFIG_CLEANCACHE is not set +# CONFIG_CLKSRC_PISTACHIO is not set # CONFIG_CLKSRC_VERSATILE is not set +# CONFIG_CLK_GFM_LPASS_SM8250 is not set # CONFIG_CLK_HSDK is not set # CONFIG_CLK_ICST is not set # CONFIG_CLK_QORIQ is not set @@ -977,6 +1029,7 @@ CONFIG_CMDLINE="" # CONFIG_CODE_PATCHING_SELFTEST is not set # CONFIG_COMEDI is not set # CONFIG_COMMON_CLK_AXI_CLKGEN is not set +# CONFIG_COMMON_CLK_BOSTON is not set # CONFIG_COMMON_CLK_CDCE706 is not set # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_COMMON_CLK_CS2000_CP is not set @@ -991,8 +1044,10 @@ CONFIG_CMDLINE="" # CONFIG_COMMON_CLK_MT8167_MFGCFG is not set # CONFIG_COMMON_CLK_MT8167_MMSYS is not set # CONFIG_COMMON_CLK_MT8167_VDECSYS is not set +# CONFIG_COMMON_CLK_MT8192 is not set # CONFIG_COMMON_CLK_NXP is not set # CONFIG_COMMON_CLK_PIC32 is not set +# CONFIG_COMMON_CLK_PISTACHIO is not set # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_QCOM is not set @@ -1005,12 +1060,14 @@ CONFIG_CMDLINE="" # CONFIG_COMMON_CLK_SI544 is not set # CONFIG_COMMON_CLK_SI570 is not set # CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_COMMON_CLK_VC7 is not set # CONFIG_COMMON_CLK_XGENE is not set # CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set CONFIG_COMPACTION=y # CONFIG_COMPAL_LAPTOP is not set # CONFIG_COMPAT is not set # CONFIG_COMPAT_32BIT_TIME is not set +# CONFIG_COMPAT_ALIGNMENT_FIXUPS is not set # CONFIG_COMPAT_BRK is not set # CONFIG_COMPILE_TEST is not set # CONFIG_CONFIGFS_FS is not set @@ -1020,6 +1077,8 @@ CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 CONFIG_CONSOLE_LOGLEVEL_QUIET=4 CONFIG_CONSTRUCTORS=y # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_CONTEXT_TRACKING is not set +# CONFIG_CONTEXT_TRACKING_IDLE is not set # CONFIG_COPS is not set # CONFIG_CORDIC is not set # CONFIG_COREDUMP is not set @@ -1111,9 +1170,9 @@ CONFIG_CRYPTO_ALGAPI2=y # CONFIG_CRYPTO_ARIA is not set # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_BLAKE2B is not set -CONFIG_CRYPTO_BLAKE2B_NEON=y +# CONFIG_CRYPTO_BLAKE2B_NEON is not set # CONFIG_CRYPTO_BLAKE2S is not set -CONFIG_CRYPTO_BLAKE2S_ARM=y +# CONFIG_CRYPTO_BLAKE2S_ARM is not set # CONFIG_CRYPTO_BLAKE2S_X86 is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_CAMELLIA is not set @@ -1134,6 +1193,7 @@ CONFIG_CRYPTO_CCM=y # CONFIG_CRYPTO_CRC32_ARM_CE is not set # CONFIG_CRYPTO_CRCT10DIF is not set # CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set +# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_CTR=y # CONFIG_CRYPTO_CTS is not set @@ -1160,10 +1220,12 @@ CONFIG_CRYPTO_CTR=y # CONFIG_CRYPTO_DEV_HISI_ZIP is not set # CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set # CONFIG_CRYPTO_DEV_MARVELL_CESA is not set +# CONFIG_CRYPTO_DEV_MEDIATEK is not set # CONFIG_CRYPTO_DEV_MV_CESA is not set # CONFIG_CRYPTO_DEV_MXC_SCC is not set # CONFIG_CRYPTO_DEV_MXS_DCP is not set # CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set +# CONFIG_CRYPTO_DEV_OCTEONTX_CPT is not set # CONFIG_CRYPTO_DEV_QAT_4XXX is not set # CONFIG_CRYPTO_DEV_QAT_C3XXX is not set # CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set @@ -1208,14 +1270,14 @@ CONFIG_CRYPTO_KPP=y CONFIG_CRYPTO_KPP2=y CONFIG_CRYPTO_LIB_AES=y CONFIG_CRYPTO_LIB_ARC4=y -# CONFIG_CRYPTO_LIB_BLAKE2S is not set -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +# CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC is not set # CONFIG_CRYPTO_LIB_CHACHA is not set # CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set # CONFIG_CRYPTO_LIB_CURVE25519 is not set # CONFIG_CRYPTO_LIB_POLY1305 is not set CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 -# CONFIG_CRYPTO_LIB_SHA256 is not set +# CONFIG_CRYPTO_LIB_SHA1 is not set +# CONFIG_CRYPTO_LIB_UTILS is not set # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_LZ4 is not set # CONFIG_CRYPTO_LZ4HC is not set @@ -1259,10 +1321,11 @@ CONFIG_CRYPTO_PCRYPT=y # CONFIG_CRYPTO_SERPENT is not set # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA1_ARM is not set +# CONFIG_CRYPTO_SHA1_ARM64 is not set # CONFIG_CRYPTO_SHA1_ARM64_CE is not set # CONFIG_CRYPTO_SHA1_ARM_CE is not set # CONFIG_CRYPTO_SHA1_ARM_NEON is not set -CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA256_ARM is not set # CONFIG_CRYPTO_SHA256_ARM64 is not set # CONFIG_CRYPTO_SHA256_SSSE3 is not set @@ -1353,10 +1416,10 @@ CONFIG_DEBUG_FS_ALLOW_ALL=y # CONFIG_DEBUG_INFO_BTF is not set # CONFIG_DEBUG_INFO_COMPRESSED is not set # CONFIG_DEBUG_INFO_DWARF4 is not set -CONFIG_DEBUG_INFO_DWARF5=y -# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set +# CONFIG_DEBUG_INFO_DWARF5 is not set +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y # CONFIG_DEBUG_INFO_NONE is not set -CONFIG_DEBUG_INFO_REDUCED=y +# CONFIG_DEBUG_INFO_REDUCED is not set # CONFIG_DEBUG_INFO_SPLIT is not set # CONFIG_DEBUG_IRQFLAGS is not set CONFIG_DEBUG_KERNEL=y @@ -1415,19 +1478,25 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_WX is not set # CONFIG_DEBUG_ZBOOT is not set # CONFIG_DECNET is not set +# CONFIG_DEFAULT_CODEL is not set CONFIG_DEFAULT_CUBIC=y CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_FQ is not set +CONFIG_DEFAULT_FQ_CODEL=y +# CONFIG_DEFAULT_FQ_PIE is not set CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 CONFIG_DEFAULT_INIT="" CONFIG_DEFAULT_IOSCHED="deadline" CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_DEFAULT_NET_SCH="fq_codel" # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_PFIFO_FAST=y +# CONFIG_DEFAULT_PFIFO_FAST is not set # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_SECURITY="" CONFIG_DEFAULT_SECURITY_DAC=y # CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SFQ is not set CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set @@ -1443,7 +1512,6 @@ CONFIG_DEVPORT=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_DEVTMPFS is not set # CONFIG_DEVTMPFS_MOUNT is not set -# CONFIG_DEVTMPFS_SAFE is not set # CONFIG_DEV_DAX is not set # CONFIG_DGAP is not set # CONFIG_DGNC is not set @@ -1513,6 +1581,7 @@ CONFIG_DMA_NONCOHERENT_MMAP=y # CONFIG_DNOTIFY is not set # CONFIG_DNS_RESOLVER is not set CONFIG_DOUBLEFAULT=y +# CONFIG_DP83640_PHY is not set # CONFIG_DP83822_PHY is not set # CONFIG_DP83848_PHY is not set # CONFIG_DP83867_PHY is not set @@ -1534,14 +1603,18 @@ CONFIG_DQL=y # CONFIG_DRM_AMD_DC_DCN3_0 is not set # CONFIG_DRM_AMD_DC_HDCP is not set # CONFIG_DRM_AMD_DC_SI is not set +# CONFIG_DRM_AMD_SECURE_DISPLAY is not set # CONFIG_DRM_ANALOGIX_ANX6345 is not set +# CONFIG_DRM_ANALOGIX_ANX7625 is not set # CONFIG_DRM_ANALOGIX_ANX78XX is not set # CONFIG_DRM_ARCPGU is not set # CONFIG_DRM_ARMADA is not set # CONFIG_DRM_AST is not set +# CONFIG_DRM_ATMEL_HLCDC is not set # CONFIG_DRM_BOCHS is not set # CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_CDNS_MHDP8546 is not set +# CONFIG_DRM_CHIPONE_ICN6211 is not set # CONFIG_DRM_CHRONTEL_CH7033 is not set # CONFIG_DRM_CIRRUS_QEMU is not set # CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set @@ -1576,13 +1649,18 @@ CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 # CONFIG_DRM_IMX8QXP_PIXEL_COMBINER is not set # CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI is not set # CONFIG_DRM_IMX_LCDIF is not set +# CONFIG_DRM_ITE_IT6505 is not set +# CONFIG_DRM_ITE_IT66121 is not set # CONFIG_DRM_KOMEDA is not set # CONFIG_DRM_LEGACY is not set # CONFIG_DRM_LIB_RANDOM is not set # CONFIG_DRM_LIMA is not set # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set # CONFIG_DRM_LOGICVC is not set +# CONFIG_DRM_LONTIUM_LT8912B is not set +# CONFIG_DRM_LONTIUM_LT9211 is not set # CONFIG_DRM_LONTIUM_LT9611 is not set +# CONFIG_DRM_LONTIUM_LT9611UXC is not set # CONFIG_DRM_LVDS_CODEC is not set # CONFIG_DRM_LVDS_ENCODER is not set # CONFIG_DRM_MALI_DISPLAY is not set @@ -1594,18 +1672,27 @@ CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 # CONFIG_DRM_NWL_MIPI_DSI is not set # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_OMAP is not set +# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set # CONFIG_DRM_PANEL_ARM_VERSATILE is not set # CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set +# CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set # CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set # CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set +# CONFIG_DRM_PANEL_DSI_CM is not set # CONFIG_DRM_PANEL_EBBG_FT8719 is not set +# CONFIG_DRM_PANEL_EDP is not set # CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set # CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set # CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set # CONFIG_DRM_PANEL_ILITEK_IL9322 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set # CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set +# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set # CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set # CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set +# CONFIG_DRM_PANEL_JDI_R63452 is not set +# CONFIG_DRM_PANEL_KHADAS_TS050 is not set # CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set # CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set # CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set @@ -1613,8 +1700,13 @@ CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 # CONFIG_DRM_PANEL_LG_LG4573 is not set # CONFIG_DRM_PANEL_LVDS is not set # CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set +# CONFIG_DRM_PANEL_MIPI_DBI is not set # CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set +# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set # CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set # CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set # CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set # CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set @@ -1625,28 +1717,37 @@ CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 # CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set # CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 is not set # CONFIG_DRM_PANEL_RONBO_RB070D30 is not set +# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set +# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set # CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set # CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set # CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set # CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set +# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set # CONFIG_DRM_PANEL_SIMPLE is not set # CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set # CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set # CONFIG_DRM_PANEL_SONY_ACX424AKP is not set # CONFIG_DRM_PANEL_SONY_ACX565AKM is not set +# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set +# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set # CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set # CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set # CONFIG_DRM_PANEL_TPO_TPG110 is not set +# CONFIG_DRM_PANEL_TPO_Y17P is not set # CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set # CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set +# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set # CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set # CONFIG_DRM_PANFROST is not set # CONFIG_DRM_PARADE_PS8622 is not set @@ -1657,10 +1758,15 @@ CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 # CONFIG_DRM_RADEON_USERPTR is not set # CONFIG_DRM_RCAR_DW_HDMI is not set # CONFIG_DRM_RCAR_LVDS is not set +# CONFIG_DRM_RCAR_MIPI_DSI is not set +# CONFIG_DRM_RCAR_USE_LVDS is not set +# CONFIG_DRM_RCAR_USE_MIPI_DSI is not set # CONFIG_DRM_SII902X is not set # CONFIG_DRM_SII9234 is not set # CONFIG_DRM_SIL_SII8620 is not set +# CONFIG_DRM_SIMPLEDRM is not set # CONFIG_DRM_SIMPLE_BRIDGE is not set +# CONFIG_DRM_SSD130X is not set # CONFIG_DRM_STI is not set # CONFIG_DRM_STM is not set # CONFIG_DRM_SUN4I is not set @@ -1669,6 +1775,7 @@ CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 # CONFIG_DRM_TILCDC is not set # CONFIG_DRM_TINYDRM is not set # CONFIG_DRM_TI_DLPC3433 is not set +# CONFIG_DRM_TI_SN65DSI83 is not set # CONFIG_DRM_TI_SN65DSI86 is not set # CONFIG_DRM_TI_TFP410 is not set # CONFIG_DRM_TI_TPD12S015 is not set @@ -1679,6 +1786,7 @@ CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 # CONFIG_DRM_TOSHIBA_TC358775 is not set # CONFIG_DRM_TVE200 is not set # CONFIG_DRM_UDL is not set +# CONFIG_DRM_USE_DYNAMIC_DEBUG is not set # CONFIG_DRM_VBOXVIDEO is not set # CONFIG_DRM_VC4_HDMI_CEC is not set # CONFIG_DRM_VGEM is not set @@ -1867,6 +1975,7 @@ CONFIG_DYNAMIC_DEBUG_CORE=y # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EFI is not set CONFIG_EFI_PARTITION=y +# CONFIG_EFI_VARS_PSTORE is not set # CONFIG_EFS_FS is not set CONFIG_ELFCORE=y # CONFIG_ELF_CORE is not set @@ -1955,6 +2064,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_FB_ARK is not set # CONFIG_FB_ARMCLCD is not set # CONFIG_FB_ASILIANT is not set +# CONFIG_FB_ATMEL is not set # CONFIG_FB_ATY is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_AUO_K190X is not set @@ -1974,6 +2084,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_FB_DDC is not set # CONFIG_FB_FLEX is not set # CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_FSL_DIU is not set # CONFIG_FB_GEODE is not set # CONFIG_FB_GOLDFISH is not set # CONFIG_FB_HGA is not set @@ -2091,10 +2202,12 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_FONT_TER16x32 is not set # CONFIG_FORCEDETH is not set CONFIG_FORCE_MAX_ZONEORDER=11 +# CONFIG_FORCE_NR_CPUS is not set CONFIG_FORTIFY_SOURCE=y # CONFIG_FPGA is not set # CONFIG_FRAMEBUFFER_CONSOLE is not set # CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set # CONFIG_FRAME_POINTER is not set CONFIG_FRAME_WARN=1024 # CONFIG_FREEZER is not set @@ -2102,6 +2215,10 @@ CONFIG_FRAME_WARN=1024 # CONFIG_FSCACHE is not set # CONFIG_FSI is not set # CONFIG_FSL_EDMA is not set +# CONFIG_FSL_ENETC is not set +# CONFIG_FSL_ENETC_IERB is not set +# CONFIG_FSL_ENETC_MDIO is not set +# CONFIG_FSL_ENETC_VF is not set # CONFIG_FSL_ERRATUM_A008585 is not set # CONFIG_FSL_MC_BUS is not set # CONFIG_FSL_PQ_MDIO is not set @@ -2117,6 +2234,7 @@ CONFIG_FSNOTIFY=y # CONFIG_FTL is not set # CONFIG_FTMAC100 is not set # CONFIG_FTRACE is not set +# CONFIG_FTRACE_RECORD_RECURSION is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_FTR_FIXUP_SELFTEST is not set # CONFIG_FTWDT010_WATCHDOG is not set @@ -2137,6 +2255,7 @@ CONFIG_FUTEX_PI=y # CONFIG_FW_CFG_SYSFS is not set CONFIG_FW_LOADER=y # CONFIG_FW_LOADER_COMPRESS is not set +# CONFIG_FW_LOADER_SYSFS is not set CONFIG_FW_LOADER_USER_HELPER=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y # CONFIG_FW_UPLOAD is not set @@ -2149,7 +2268,9 @@ CONFIG_GACT_PROB=y # CONFIG_GADGET_UAC1 is not set # CONFIG_GAMEPORT is not set # CONFIG_GATEWORKS_GW16083 is not set +# CONFIG_GCC12_NO_ARRAY_BOUNDS is not set # CONFIG_GCC_PLUGINS is not set +# CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS is not set # CONFIG_GCOV is not set # CONFIG_GCOV_KERNEL is not set # CONFIG_GDB_SCRIPTS is not set @@ -2160,6 +2281,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y # CONFIG_GENERIC_CPU_DEVICES is not set # CONFIG_GENERIC_FIND_FIRST_BIT is not set CONFIG_GENERIC_HWEIGHT=y +# CONFIG_GENERIC_IOREMAP is not set # CONFIG_GENERIC_IRQ_DEBUGFS is not set CONFIG_GENERIC_IRQ_IPI=y CONFIG_GENERIC_IRQ_PROBE=y @@ -2181,10 +2303,13 @@ CONFIG_GENERIC_VDSO_TIME_NS=y # CONFIG_GNSS is not set # CONFIG_GOLDFISH is not set # CONFIG_GOOGLE_FIRMWARE is not set +# CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT is not set +# CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY is not set +# CONFIG_GOOGLE_SMI is not set # CONFIG_GP2AP002 is not set # CONFIG_GP2AP020A00F is not set # CONFIG_GPD_POCKET_FAN is not set -# CONFIG_GPIOLIB is not set +CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 # CONFIG_GPIO_104_DIO_48E is not set # CONFIG_GPIO_104_IDIO_16 is not set @@ -2238,6 +2363,7 @@ CONFIG_GPIOLIB_FASTPATH_LIMIT=512 # CONFIG_GPIO_PCI_IDIO_16 is not set # CONFIG_GPIO_PISOSR is not set # CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_PWM is not set # CONFIG_GPIO_RCAR is not set # CONFIG_GPIO_RDC321X is not set # CONFIG_GPIO_ROCKCHIP is not set @@ -2252,6 +2378,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_TPIC2810 is not set # CONFIG_GPIO_TS4900 is not set # CONFIG_GPIO_TS5500 is not set +# CONFIG_GPIO_VIRTIO is not set # CONFIG_GPIO_VX855 is not set # CONFIG_GPIO_WATCHDOG is not set # CONFIG_GPIO_WINBOND is not set @@ -2261,6 +2388,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_XRA1403 is not set # CONFIG_GPIO_ZEVIO is not set # CONFIG_GPIO_ZX is not set +# CONFIG_GP_PCI1XXXX is not set # CONFIG_GREENASIA_FF is not set # CONFIG_GREYBUS is not set # CONFIG_GS_FPGABOOT is not set @@ -2275,6 +2403,7 @@ CONFIG_GPIO_SYSFS=y CONFIG_HARDENED_USERCOPY=y # CONFIG_HARDENED_USERCOPY_FALLBACK is not set # CONFIG_HARDENED_USERCOPY_PAGESPAN is not set +CONFIG_HARDEN_BRANCH_HISTORY=y CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HARDLOCKUP_DETECTOR is not set # CONFIG_HAVE_ARM_ARCH_TIMER is not set @@ -2297,6 +2426,7 @@ CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HFSPLUS_FS_POSIX_ACL is not set # CONFIG_HFS_FS is not set # CONFIG_HFS_FS_POSIX_ACL is not set +# CONFIG_HI6421V600_IRQ is not set # CONFIG_HI8435 is not set # CONFIG_HIBERNATION is not set # CONFIG_HID is not set @@ -2373,6 +2503,7 @@ CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HID_PLAYSTATION is not set # CONFIG_HID_PRIMAX is not set # CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_PXRC is not set # CONFIG_HID_RAZER is not set # CONFIG_HID_REDRAGON is not set # CONFIG_HID_RETRODE is not set @@ -2392,6 +2523,7 @@ CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HID_THINGM is not set # CONFIG_HID_THRUSTMASTER is not set # CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPRE is not set # CONFIG_HID_TOPSEED is not set # CONFIG_HID_TWINHAN is not set # CONFIG_HID_U2FZERO is not set @@ -2399,6 +2531,7 @@ CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HID_UDRAW_PS3 is not set # CONFIG_HID_VIEWSONIC is not set # CONFIG_HID_VIVALDI is not set +# CONFIG_HID_VRC2 is not set # CONFIG_HID_WACOM is not set # CONFIG_HID_WALTOP is not set # CONFIG_HID_WIIMOTE is not set @@ -2439,6 +2572,7 @@ CONFIG_HIGH_RES_TIMERS=y CONFIG_HPET_MMAP_DEFAULT=y # CONFIG_HPFS_FS is not set # CONFIG_HP_ILO is not set +# CONFIG_HP_WATCHDOG is not set # CONFIG_HP_WIRELESS is not set # CONFIG_HSA_AMD is not set # CONFIG_HSI is not set @@ -2563,6 +2697,7 @@ CONFIG_HZ_100=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PCA_ISA is not set # CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PCI1XXXX is not set # CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_PXA_PCI is not set # CONFIG_I2C_PXA_SLAVE is not set @@ -2662,6 +2797,7 @@ CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # CONFIG_IMG_MDC_DMA is not set # CONFIG_IMX7D_ADC is not set # CONFIG_IMX_IPUV3_CORE is not set +# CONFIG_IMX_MU_MSI is not set # CONFIG_IMX_THERMAL is not set # CONFIG_INA2XX_ADC is not set # CONFIG_INDIRECT_PIO is not set @@ -2682,6 +2818,7 @@ CONFIG_INET=y # CONFIG_INET_ESPINTCP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_LRO is not set +# CONFIG_INET_TABLE_PERTURB_ORDER is not set # CONFIG_INET_TCP_DIAG is not set # CONFIG_INET_TUNNEL is not set # CONFIG_INET_UDP_DIAG is not set @@ -2694,6 +2831,7 @@ CONFIG_INET=y # CONFIG_INGENIC_ADC is not set # CONFIG_INGENIC_CGU_JZ4725B is not set # CONFIG_INGENIC_CGU_JZ4740 is not set +# CONFIG_INGENIC_CGU_JZ4760 is not set # CONFIG_INGENIC_CGU_JZ4770 is not set # CONFIG_INGENIC_CGU_JZ4780 is not set # CONFIG_INGENIC_CGU_X1000 is not set @@ -2703,9 +2841,12 @@ CONFIG_INET=y # CONFIG_INGENIC_TCU_CLK is not set # CONFIG_INGENIC_TCU_IRQ is not set # CONFIG_INGENIC_TIMER is not set +# CONFIG_INITRAMFS_PRESERVE_MTIME is not set CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +# CONFIG_INIT_STACK_ALL_PATTERN is not set +# CONFIG_INIT_STACK_ALL_ZERO is not set CONFIG_INIT_STACK_NONE=y CONFIG_INOTIFY_USER=y # CONFIG_INPUT is not set @@ -2811,12 +2952,11 @@ CONFIG_INPUT_MISC=y # CONFIG_INV_MPU6050_SPI is not set # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set # CONFIG_IOMMU_DMA_PCI_SAC is not set +# CONFIG_IOMMU_IO_PGTABLE_DART is not set # CONFIG_IOMMU_SUPPORT is not set # CONFIG_IONIC is not set # CONFIG_IOSCHED_BFQ is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSM is not set CONFIG_IO_STRICT_DEVMEM=y # CONFIG_IO_URING is not set CONFIG_IO_WQ=y @@ -2930,6 +3070,7 @@ CONFIG_IP_VS_MH_TAB_INDEX=10 # CONFIG_IR_IGUANA is not set # CONFIG_IR_IMG is not set # CONFIG_IR_IMON is not set +# CONFIG_IR_IMON_RAW is not set # CONFIG_IR_JVC_DECODER is not set # CONFIG_IR_LIRC_CODEC is not set # CONFIG_IR_MCEUSB is not set @@ -3023,6 +3164,7 @@ CONFIG_KERNEL_XZ=y CONFIG_KERNFS=y # CONFIG_KEXEC is not set # CONFIG_KEXEC_FILE is not set +# CONFIG_KEXEC_SIG is not set # CONFIG_KEYBOARD_ADC is not set # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ADP5589 is not set @@ -3044,6 +3186,7 @@ CONFIG_KERNFS=y # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_OMAP4 is not set # CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_PINEPHONE is not set # CONFIG_KEYBOARD_PXA27x is not set # CONFIG_KEYBOARD_QT1050 is not set # CONFIG_KEYBOARD_QT1070 is not set @@ -3087,6 +3230,7 @@ CONFIG_KUSER_HELPERS=y # CONFIG_KVM_GUEST is not set # CONFIG_KVM_INTEL is not set # CONFIG_KVM_WERROR is not set +# CONFIG_KVM_XEN is not set # CONFIG_KXCJK1013 is not set # CONFIG_KXSD9 is not set # CONFIG_L2TP is not set @@ -3094,6 +3238,7 @@ CONFIG_KUSER_HELPERS=y # CONFIG_L2TP_IP is not set # CONFIG_L2TP_V3 is not set # CONFIG_LAN743X is not set +# CONFIG_LAN966X_SWITCH is not set # CONFIG_LANMEDIA is not set # CONFIG_LANTIQ is not set # CONFIG_LAPB is not set @@ -3250,11 +3395,13 @@ CONFIG_LSM_MMAP_MIN_ADDR=65536 # CONFIG_LTC2496 is not set # CONFIG_LTC2497 is not set # CONFIG_LTC2632 is not set +# CONFIG_LTC2688 is not set # CONFIG_LTC2983 is not set # CONFIG_LTE_GDM724X is not set -# CONFIG_LTO_NONE is not set +CONFIG_LTO_NONE=y # CONFIG_LTPC is not set # CONFIG_LTR501 is not set +# CONFIG_LTRF216A is not set # CONFIG_LUSTRE_FS is not set # CONFIG_LV0104CS is not set # CONFIG_LWTUNNEL is not set @@ -3280,8 +3427,10 @@ CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_MACH_LOONGSON2EF is not set # CONFIG_MACH_LOONGSON32 is not set # CONFIG_MACH_LOONGSON64 is not set +# CONFIG_MACH_NINTENDO64 is not set # CONFIG_MACH_PIC32 is not set # CONFIG_MACH_PISTACHIO is not set +# CONFIG_MACH_REALTEK_RTL is not set # CONFIG_MACH_TX39XX is not set # CONFIG_MACH_TX49XX is not set # CONFIG_MACH_VR41XX is not set @@ -3307,11 +3456,13 @@ CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" # CONFIG_MAX1027 is not set # CONFIG_MAX11100 is not set # CONFIG_MAX1118 is not set +# CONFIG_MAX11205 is not set # CONFIG_MAX1241 is not set # CONFIG_MAX1363 is not set # CONFIG_MAX30100 is not set # CONFIG_MAX30102 is not set # CONFIG_MAX31856 is not set +# CONFIG_MAX31865 is not set # CONFIG_MAX44000 is not set # CONFIG_MAX44009 is not set # CONFIG_MAX517 is not set @@ -3354,8 +3505,10 @@ CONFIG_MAY_USE_DEVLINK=y # CONFIG_MDIO_OCTEON is not set # CONFIG_MDIO_THUNDER is not set # CONFIG_MDIO_XPCS is not set +# CONFIG_MDM_GCC_9607 is not set # CONFIG_MD_FAULTY is not set # CONFIG_MEDIATEK_GE_PHY is not set +# CONFIG_MEDIATEK_MT6577_AUXADC is not set # CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set # CONFIG_MEDIA_ATTACH is not set # CONFIG_MEDIA_CAMERA_SUPPORT is not set @@ -3363,6 +3516,7 @@ CONFIG_MAY_USE_DEVLINK=y # CONFIG_MEDIA_CONTROLLER is not set # CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set # CONFIG_MEDIA_PCI_SUPPORT is not set +# CONFIG_MEDIA_PLATFORM_DRIVERS is not set # CONFIG_MEDIA_PLATFORM_SUPPORT is not set # CONFIG_MEDIA_RADIO_SUPPORT is not set # CONFIG_MEDIA_RC_SUPPORT is not set @@ -3455,6 +3609,7 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MFD_GATEWORKS_GSC is not set # CONFIG_MFD_HI6421_PMIC is not set # CONFIG_MFD_INTEL_M10_BMC is not set +# CONFIG_MFD_INTEL_PMT is not set # CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set # CONFIG_MFD_IQS62X is not set # CONFIG_MFD_JANZ_CMODIO is not set @@ -3481,8 +3636,10 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MFD_MENF21BMC is not set # CONFIG_MFD_MP2629 is not set # CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6370 is not set # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_NTXEC is not set +# CONFIG_MFD_OCELOT is not set # CONFIG_MFD_OMAP_USB_HOST is not set # CONFIG_MFD_PALMAS is not set # CONFIG_MFD_PCF50633 is not set @@ -3502,11 +3659,11 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MFD_RSMU_SPI is not set # CONFIG_MFD_RT4831 is not set # CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RT5120 is not set # CONFIG_MFD_RTSX_PCI is not set # CONFIG_MFD_RTSX_USB is not set # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set -# CONFIG_MFD_SIMPLE_MFD_I2C is not set # CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_SL28CPLD is not set # CONFIG_MFD_SM501 is not set @@ -3514,6 +3671,7 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MFD_STMFX is not set # CONFIG_MFD_STMPE is not set # CONFIG_MFD_STPMIC1 is not set +# CONFIG_MFD_SY7636A is not set # CONFIG_MFD_SYSCON is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC3589X is not set @@ -3548,7 +3706,12 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MFD_WM8994 is not set # CONFIG_MG_DISK is not set # CONFIG_MHI_BUS is not set +# CONFIG_MHI_BUS_DEBUG is not set # CONFIG_MHI_BUS_EP is not set +# CONFIG_MHI_BUS_PCI_GENERIC is not set +# CONFIG_MHI_NET is not set +# CONFIG_MHI_WWAN_CTRL is not set +# CONFIG_MHI_WWAN_MBIM is not set # CONFIG_MICREL_KS8995MA is not set # CONFIG_MICREL_PHY is not set # CONFIG_MICROCHIP_KSZ is not set @@ -3564,9 +3727,16 @@ CONFIG_MII=y # CONFIG_MINIX_FS is not set # CONFIG_MINIX_FS_NATIVE_ENDIAN is not set # CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_MIPS32_O32 is not set # CONFIG_MIPS_ALCHEMY is not set # CONFIG_MIPS_CDMM is not set +# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_DTB is not set +# CONFIG_MIPS_CMP is not set # CONFIG_MIPS_COBALT is not set +# CONFIG_MIPS_CPS is not set +# CONFIG_MIPS_ELF_APPENDED_DTB is not set # CONFIG_MIPS_FPU_EMULATOR is not set # CONFIG_MIPS_FP_SUPPORT is not set # CONFIG_MIPS_GENERIC is not set @@ -3575,7 +3745,10 @@ CONFIG_MII=y # CONFIG_MIPS_O32_FP64_SUPPORT is not set # CONFIG_MIPS_PARAVIRT is not set # CONFIG_MIPS_PLATFORM_DEVICES is not set +# CONFIG_MIPS_RAW_APPENDED_DTB is not set # CONFIG_MIPS_SEAD3 is not set +# CONFIG_MIPS_VA_BITS_48 is not set +# CONFIG_MIPS_VPE_LOADER is not set # CONFIG_MISC_ALCOR_PCI is not set CONFIG_MISC_FILESYSTEMS=y # CONFIG_MISC_RTSX_PCI is not set @@ -3588,11 +3761,12 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_MISDN_NETJET is not set # CONFIG_MISDN_SPEEDFAX is not set # CONFIG_MISDN_W6692 is not set -# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set +CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y # CONFIG_MKISS is not set # CONFIG_MLX4_CORE is not set # CONFIG_MLX4_EN is not set # CONFIG_MLX5_CORE is not set +# CONFIG_MLX5_EN_MACSEC is not set # CONFIG_MLX5_SF is not set # CONFIG_MLX90614 is not set # CONFIG_MLX90632 is not set @@ -3611,6 +3785,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_MMC_ARMMMCI is not set # CONFIG_MMC_AU1X is not set # CONFIG_MMC_BLOCK is not set +CONFIG_MMC_BLOCK_BOUNCE=y CONFIG_MMC_BLOCK_MINORS=8 # CONFIG_MMC_CAVIUM_THUNDERX is not set # CONFIG_MMC_CB710 is not set @@ -3660,6 +3835,7 @@ CONFIG_MMU_GATHER_TABLE_FREE=y CONFIG_MODPROBE_PATH="/sbin/modprobe" CONFIG_MODULES=y # CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +# CONFIG_MODULE_COMPRESS is not set # CONFIG_MODULE_COMPRESS_GZIP is not set CONFIG_MODULE_COMPRESS_NONE=y # CONFIG_MODULE_COMPRESS_XZ is not set @@ -3690,18 +3866,23 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MPL115_SPI is not set # CONFIG_MPL3115 is not set # CONFIG_MPLS is not set +# CONFIG_MPLS_IPTUNNEL is not set +# CONFIG_MPLS_ROUTING is not set # CONFIG_MPTCP is not set # CONFIG_MPU3050_I2C is not set # CONFIG_MQ_IOSCHED_DEADLINE is not set # CONFIG_MQ_IOSCHED_KYBER is not set # CONFIG_MS5611 is not set # CONFIG_MS5637 is not set +# CONFIG_MSA311 is not set # CONFIG_MSCC_OCELOT_SWITCH is not set # CONFIG_MSDOS_FS is not set CONFIG_MSDOS_PARTITION=y # CONFIG_MSE102X is not set # CONFIG_MSI_BITMAP_SELFTEST is not set # CONFIG_MSI_LAPTOP is not set +# CONFIG_MSM_GCC_8953 is not set +# CONFIG_MSM_MMCC_8994 is not set # CONFIG_MST_IRQ is not set CONFIG_MTD=y # CONFIG_MTD_ABSENT is not set @@ -3814,6 +3995,7 @@ CONFIG_MTD_OF_PARTS=y # CONFIG_MTD_ONENAND is not set # CONFIG_MTD_OOPS is not set # CONFIG_MTD_OTP is not set +# CONFIG_MTD_PARSER_TRX is not set # CONFIG_MTD_PARTITIONED_MASTER is not set # CONFIG_MTD_PCI is not set # CONFIG_MTD_PCMCIA is not set @@ -3838,16 +4020,17 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 # CONFIG_MTD_ROM is not set CONFIG_MTD_ROOTFS_ROOT_DEV=y # CONFIG_MTD_ROUTERBOOT_PARTS is not set +# CONFIG_MTD_SERCOMM_PARTS is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_SM_COMMON is not set # CONFIG_MTD_SPINAND_MT29F is not set # CONFIG_MTD_SPI_NAND is not set # CONFIG_MTD_SPI_NOR is not set -CONFIG_MTD_SPI_NOR_SWP_DISABLE=y -# CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE is not set +# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set +CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y # CONFIG_MTD_SPI_NOR_SWP_KEEP is not set # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=4096 +# CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE is not set CONFIG_MTD_SPLIT=y # CONFIG_MTD_SPLIT_BCM63XX_FW is not set # CONFIG_MTD_SPLIT_BCM_WFI_FW is not set @@ -3876,10 +4059,18 @@ CONFIG_MTD_SPLIT_SUPPORT=y # CONFIG_MTD_UBI_GLUEBI is not set # CONFIG_MTD_UIMAGE_SPLIT is not set # CONFIG_MTD_VIRT_CONCAT is not set +# CONFIG_MTK_DEVAPC is not set # CONFIG_MTK_MMC is not set # CONFIG_MTK_MMSYS is not set +# CONFIG_MTK_T7XX is not set +# CONFIG_MTK_THERMAL is not set +# CONFIG_MULTIPLEXER is not set CONFIG_MULTIUSER=y # CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_MUX_ADG792A is not set +# CONFIG_MUX_ADGS1408 is not set +# CONFIG_MUX_GPIO is not set +# CONFIG_MUX_MMIO is not set # CONFIG_MV643XX_ETH is not set # CONFIG_MVMDIO is not set # CONFIG_MVNETA_BM is not set @@ -4049,6 +4240,7 @@ CONFIG_NET_CORE=y # CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set # CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set # CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON is not set +# CONFIG_NET_DSA_MSCC_FELIX is not set # CONFIG_NET_DSA_MSCC_SEVILLE is not set # CONFIG_NET_DSA_MT7530 is not set # CONFIG_NET_DSA_MV88E6060 is not set @@ -4060,6 +4252,7 @@ CONFIG_NET_CORE=y # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set # CONFIG_NET_DSA_MV88E6XXX_PTP is not set # CONFIG_NET_DSA_QCA8K is not set +# CONFIG_NET_DSA_REALTEK is not set # CONFIG_NET_DSA_REALTEK_SMI is not set # CONFIG_NET_DSA_SJA1105 is not set # CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set @@ -4132,7 +4325,7 @@ CONFIG_NET_SCHED=y # CONFIG_NET_SCH_CBS is not set # CONFIG_NET_SCH_CHOKE is not set # CONFIG_NET_SCH_CODEL is not set -# CONFIG_NET_SCH_DEFAULT is not set +CONFIG_NET_SCH_DEFAULT=y # CONFIG_NET_SCH_DRR is not set # CONFIG_NET_SCH_DSMARK is not set # CONFIG_NET_SCH_ETF is not set @@ -4162,7 +4355,7 @@ CONFIG_NET_SCH_FQ_CODEL=y # CONFIG_NET_SCH_TEQL is not set # CONFIG_NET_SCTPPROBE is not set # CONFIG_NET_SELFTESTS is not set -# CONFIG_NET_SOCK_MSG is not set +CONFIG_NET_SOCK_MSG=y # CONFIG_NET_SWITCHDEV is not set # CONFIG_NET_TCPPROBE is not set # CONFIG_NET_TC_SKB_EXT is not set @@ -4172,6 +4365,7 @@ CONFIG_NET_SCH_FQ_CODEL=y CONFIG_NET_VENDOR_3COM=y CONFIG_NET_VENDOR_8390=y CONFIG_NET_VENDOR_ADAPTEC=y +CONFIG_NET_VENDOR_ADI=y CONFIG_NET_VENDOR_AGERE=y CONFIG_NET_VENDOR_ALACRITECH=y CONFIG_NET_VENDOR_ALTEON=y @@ -4179,7 +4373,7 @@ CONFIG_NET_VENDOR_AMAZON=y CONFIG_NET_VENDOR_AMD=y CONFIG_NET_VENDOR_AQUANTIA=y CONFIG_NET_VENDOR_ARC=y -CONFIG_NET_VENDOR_ASIX=y +# CONFIG_NET_VENDOR_ASIX is not set CONFIG_NET_VENDOR_ATHEROS=y CONFIG_NET_VENDOR_AURORA=y CONFIG_NET_VENDOR_BROADCOM=y @@ -4190,17 +4384,17 @@ CONFIG_NET_VENDOR_CHELSIO=y CONFIG_NET_VENDOR_CIRRUS=y CONFIG_NET_VENDOR_CISCO=y CONFIG_NET_VENDOR_CORTINA=y -CONFIG_NET_VENDOR_DAVICOM=y +# CONFIG_NET_VENDOR_DAVICOM is not set CONFIG_NET_VENDOR_DEC=y CONFIG_NET_VENDOR_DLINK=y CONFIG_NET_VENDOR_EMULEX=y -CONFIG_NET_VENDOR_ENGLEDER=y +# CONFIG_NET_VENDOR_ENGLEDER is not set CONFIG_NET_VENDOR_EXAR=y CONFIG_NET_VENDOR_EZCHIP=y CONFIG_NET_VENDOR_FARADAY=y CONFIG_NET_VENDOR_FREESCALE=y CONFIG_NET_VENDOR_FUJITSU=y -CONFIG_NET_VENDOR_FUNGIBLE=y +# CONFIG_NET_VENDOR_FUNGIBLE is not set CONFIG_NET_VENDOR_GOOGLE=y CONFIG_NET_VENDOR_HISILICON=y CONFIG_NET_VENDOR_HP=y @@ -4208,13 +4402,13 @@ CONFIG_NET_VENDOR_HUAWEI=y CONFIG_NET_VENDOR_I825XX=y CONFIG_NET_VENDOR_IBM=y CONFIG_NET_VENDOR_INTEL=y -CONFIG_NET_VENDOR_LITEX=y +# CONFIG_NET_VENDOR_LITEX is not set CONFIG_NET_VENDOR_MARVELL=y CONFIG_NET_VENDOR_MELLANOX=y CONFIG_NET_VENDOR_MICREL=y CONFIG_NET_VENDOR_MICROCHIP=y CONFIG_NET_VENDOR_MICROSEMI=y -CONFIG_NET_VENDOR_MICROSOFT=y +# CONFIG_NET_VENDOR_MICROSOFT is not set CONFIG_NET_VENDOR_MYRI=y CONFIG_NET_VENDOR_NATSEMI=y CONFIG_NET_VENDOR_NETERION=y @@ -4243,9 +4437,9 @@ CONFIG_NET_VENDOR_SYNOPSYS=y CONFIG_NET_VENDOR_TEHUTI=y CONFIG_NET_VENDOR_TI=y CONFIG_NET_VENDOR_TOSHIBA=y -CONFIG_NET_VENDOR_VERTEXCOM=y +# CONFIG_NET_VENDOR_VERTEXCOM is not set CONFIG_NET_VENDOR_VIA=y -CONFIG_NET_VENDOR_WANGXUN=y +# CONFIG_NET_VENDOR_WANGXUN is not set CONFIG_NET_VENDOR_WIZNET=y CONFIG_NET_VENDOR_XILINX=y CONFIG_NET_VENDOR_XIRCOM=y @@ -4326,9 +4520,10 @@ CONFIG_NF_CONNTRACK_PROCFS=y # CONFIG_NF_FLOW_TABLE is not set # CONFIG_NF_FLOW_TABLE_PROCFS is not set # CONFIG_NF_LOG_ARP is not set -CONFIG_NF_LOG_IPV4=y -CONFIG_NF_LOG_IPV6=y -CONFIG_NF_LOG_SYSLOG=y +# CONFIG_NF_LOG_BRIDGE is not set +# CONFIG_NF_LOG_IPV4 is not set +# CONFIG_NF_LOG_NETDEV is not set +# CONFIG_NF_LOG_SYSLOG is not set # CONFIG_NF_NAT is not set # CONFIG_NF_NAT_AMANDA is not set # CONFIG_NF_NAT_FTP is not set @@ -4347,7 +4542,7 @@ CONFIG_NF_NAT_MASQUERADE_IPV6=y # CONFIG_NF_REJECT_IPV6 is not set # CONFIG_NF_SOCKET_IPV4 is not set # CONFIG_NF_SOCKET_IPV6 is not set -# CONFIG_NF_TABLES is not set +CONFIG_NF_TABLES=y CONFIG_NF_TABLES_ARP=y CONFIG_NF_TABLES_BRIDGE=y CONFIG_NF_TABLES_INET=y @@ -4357,6 +4552,7 @@ CONFIG_NF_TABLES_NETDEV=y # CONFIG_NF_TABLES_SET is not set # CONFIG_NF_TPROXY_IPV4 is not set # CONFIG_NF_TPROXY_IPV6 is not set +# CONFIG_NGBE is not set # CONFIG_NI65 is not set # CONFIG_NI903X_WDT is not set # CONFIG_NIC7018_WDT is not set @@ -4433,7 +4629,10 @@ CONFIG_NR_CPUS=256 CONFIG_NR_LRU_GENS=7 # CONFIG_NS83820 is not set # CONFIG_NTB is not set +# CONFIG_NTFS3_64BIT_CLUSTER is not set # CONFIG_NTFS3_FS is not set +# CONFIG_NTFS3_FS_POSIX_ACL is not set +# CONFIG_NTFS3_LZX_XPRESS is not set # CONFIG_NTFS_DEBUG is not set # CONFIG_NTFS_FS is not set # CONFIG_NTFS_RW is not set @@ -4447,8 +4646,9 @@ CONFIG_NR_LRU_GENS=7 # CONFIG_NVMEM_IMX_OCOTP is not set # CONFIG_NVMEM_NINTENDO_OTP is not set # CONFIG_NVMEM_REBOOT_MODE is not set -CONFIG_NVMEM_RMEM=y +# CONFIG_NVMEM_RMEM is not set # CONFIG_NVMEM_SYSFS is not set +# CONFIG_NVMEM_U_BOOT_ENV is not set # CONFIG_NVME_AUTH is not set # CONFIG_NVME_FC is not set # CONFIG_NVME_TARGET is not set @@ -4464,10 +4664,9 @@ CONFIG_NVMEM_RMEM=y # CONFIG_OABI_COMPAT is not set # CONFIG_OBS600 is not set # CONFIG_OCFS2_FS is not set -# CONFIG_OCTEON_EP is not set # CONFIG_OCTEONTX2_AF is not set # CONFIG_OCTEONTX2_PF is not set -# CONFIG_OF_MDIO is not set +# CONFIG_OCTEON_EP is not set # CONFIG_OF_OVERLAY is not set CONFIG_OF_RESERVED_MEM=y # CONFIG_OF_UNITTEST is not set @@ -4487,6 +4686,7 @@ CONFIG_OPTIMIZE_INLINING=y # CONFIG_ORANGEFS_FS is not set # CONFIG_ORION_WATCHDOG is not set # CONFIG_OSF_PARTITION is not set +# CONFIG_OSNOISE_TRACER is not set CONFIG_OVERLAY_FS=y # CONFIG_OVERLAY_FS_INDEX is not set # CONFIG_OVERLAY_FS_METACOPY is not set @@ -4502,6 +4702,7 @@ CONFIG_PACKET=y # CONFIG_PAGE_EXTENSION is not set # CONFIG_PAGE_OWNER is not set # CONFIG_PAGE_POISONING is not set +# CONFIG_PAGE_POOL is not set # CONFIG_PAGE_POOL_STATS is not set # CONFIG_PAGE_REPORTING is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -4509,6 +4710,7 @@ CONFIG_PACKET=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_LESS_THAN_256KB is not set # CONFIG_PAGE_SIZE_LESS_THAN_64KB is not set # CONFIG_PAGE_TABLE_CHECK is not set # CONFIG_PALMAS_GPADC is not set @@ -4611,6 +4813,7 @@ CONFIG_PCIE_BUS_DEFAULT=y # CONFIG_PCIE_IPROC is not set # CONFIG_PCIE_KIRIN is not set # CONFIG_PCIE_LAYERSCAPE_GEN4 is not set +# CONFIG_PCIE_MEDIATEK_GEN3 is not set # CONFIG_PCIE_MICROCHIP_HOST is not set # CONFIG_PCIE_PTM is not set # CONFIG_PCIE_ROCKCHIP_DW_HOST is not set @@ -4666,7 +4869,7 @@ CONFIG_PCI_SYSCALL=y # CONFIG_PCMCIA_XIRC2PS is not set # CONFIG_PCMCIA_XIRCOM is not set # CONFIG_PCNET32 is not set -CONFIG_PCPU_DEV_REFCNT=y +# CONFIG_PCPU_DEV_REFCNT is not set # CONFIG_PCSPKR_PLATFORM is not set # CONFIG_PCS_XPCS is not set # CONFIG_PD6729 is not set @@ -4693,14 +4896,16 @@ CONFIG_PCPU_DEV_REFCNT=y # CONFIG_PHY_EXYNOS_DP_VIDEO is not set # CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set # CONFIG_PHY_FSL_IMX8MQ_USB is not set -# CONFIG_PHY_FSL_IMX8M_PCIE is not set +# CONFIG_PHY_INGENIC_USB is not set # CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set # CONFIG_PHY_LAN966X_SERDES is not set # CONFIG_PHY_MAPPHONE_MDM6600 is not set # CONFIG_PHY_MIXEL_MIPI_DPHY is not set # CONFIG_PHY_MTK_HDMI is not set +# CONFIG_PHY_MTK_MIPI_DSI is not set # CONFIG_PHY_MVEBU_CP110_UTMI is not set # CONFIG_PHY_OCELOT_SERDES is not set +# CONFIG_PHY_PISTACHIO_USB is not set # CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_PHY_QCOM_DWC3 is not set @@ -4721,20 +4926,32 @@ CONFIG_PINCONF=y # CONFIG_PINCTRL_AMD is not set # CONFIG_PINCTRL_AXP209 is not set # CONFIG_PINCTRL_CEDARFORK is not set +# CONFIG_PINCTRL_CY8C95X0 is not set # CONFIG_PINCTRL_EXYNOS is not set # CONFIG_PINCTRL_EXYNOS5440 is not set # CONFIG_PINCTRL_ICELAKE is not set # CONFIG_PINCTRL_INGENIC is not set +# CONFIG_PINCTRL_LPASS_LPI is not set # CONFIG_PINCTRL_MCP23S08 is not set -CONFIG_PINCTRL_MICROCHIP_SGPIO=y +# CONFIG_PINCTRL_MDM9607 is not set +# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set +# CONFIG_PINCTRL_MSM8953 is not set # CONFIG_PINCTRL_MSM8X74 is not set # CONFIG_PINCTRL_MT6779 is not set # CONFIG_PINCTRL_MT8167 is not set # CONFIG_PINCTRL_MT8192 is not set +# CONFIG_PINCTRL_MT8195 is not set +# CONFIG_PINCTRL_MT8365 is not set # CONFIG_PINCTRL_MTK_V2 is not set # CONFIG_PINCTRL_OCELOT is not set -# CONFIG_PINCTRL_ROCKCHIP is not set +# CONFIG_PINCTRL_PISTACHIO is not set +# CONFIG_PINCTRL_SC7280 is not set +# CONFIG_PINCTRL_SC8180X is not set +# CONFIG_PINCTRL_SDX55 is not set CONFIG_PINCTRL_SINGLE=y +# CONFIG_PINCTRL_SM6115 is not set +# CONFIG_PINCTRL_SM6125 is not set +# CONFIG_PINCTRL_SM8350 is not set # CONFIG_PINCTRL_STMFX is not set # CONFIG_PINCTRL_SX150X is not set # CONFIG_PING is not set @@ -4760,6 +4977,7 @@ CONFIG_PINMUX=y # CONFIG_PM_AUTOSLEEP is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_DEVFREQ is not set +# CONFIG_PM_USERSPACE_AUTOSLEEP is not set # CONFIG_PM_WAKELOCKS is not set # CONFIG_POSIX_CPU_TIMERS_TASK_WORK is not set # CONFIG_POSIX_MQUEUE is not set @@ -4774,6 +4992,7 @@ CONFIG_POSIX_TIMERS=y # CONFIG_POWER_RESET_LINKSTATION is not set # CONFIG_POWER_RESET_LTC2952 is not set # CONFIG_POWER_RESET_PIIX4_POWEROFF is not set +# CONFIG_POWER_RESET_QNAP is not set # CONFIG_POWER_RESET_REGULATOR is not set # CONFIG_POWER_RESET_RESTART is not set # CONFIG_POWER_RESET_SYSCON is not set @@ -4847,8 +5066,23 @@ CONFIG_PROC_SYSCTL=y # CONFIG_PROVE_RCU_REPEATEDLY is not set # CONFIG_PSAMPLE is not set # CONFIG_PSB6970_PHY is not set +# CONFIG_PSE_CONTROLLER is not set # CONFIG_PSI is not set # CONFIG_PSTORE is not set +# CONFIG_PSTORE_842_COMPRESS is not set +# CONFIG_PSTORE_BLK is not set +# CONFIG_PSTORE_COMPRESS is not set +# CONFIG_PSTORE_CONSOLE is not set +CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 +# CONFIG_PSTORE_DEFLATE_COMPRESS is not set +# CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT is not set +# CONFIG_PSTORE_FTRACE is not set +# CONFIG_PSTORE_LZ4HC_COMPRESS is not set +# CONFIG_PSTORE_LZ4_COMPRESS is not set +# CONFIG_PSTORE_LZO_COMPRESS is not set +# CONFIG_PSTORE_PMSG is not set +# CONFIG_PSTORE_RAM is not set +# CONFIG_PSTORE_ZSTD_COMPRESS is not set # CONFIG_PTDUMP_DEBUGFS is not set # CONFIG_PTP_1588_CLOCK is not set # CONFIG_PTP_1588_CLOCK_IDT82P33 is not set @@ -4867,8 +5101,9 @@ CONFIG_PROC_SYSCTL=y # CONFIG_PWM_DEBUG is not set # CONFIG_PWM_DWC is not set # CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_JZ4740 is not set # CONFIG_PWM_PCA9685 is not set -# CONFIG_PWM_ROCKCHIP is not set +# CONFIG_PWM_RASPBERRYPI_POE is not set # CONFIG_PWM_XILINX is not set CONFIG_PWRSEQ_EMMC=y # CONFIG_PWRSEQ_SD8787 is not set @@ -4876,19 +5111,26 @@ CONFIG_PWRSEQ_SIMPLE=y # CONFIG_QCA7000 is not set # CONFIG_QCA7000_SPI is not set # CONFIG_QCA7000_UART is not set +# CONFIG_QCOM_A7PLL is not set +# CONFIG_QCOM_BAM_DMUX is not set # CONFIG_QCOM_EMAC is not set # CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set # CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set # CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set +# CONFIG_QCOM_GPI_DMA is not set # CONFIG_QCOM_HIDMA is not set # CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_LMH is not set # CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set # CONFIG_QCOM_SCM is not set # CONFIG_QCOM_SPMI_ADC5 is not set +# CONFIG_QCOM_SPMI_ADC_TM5 is not set # CONFIG_QCOM_SPMI_IADC is not set # CONFIG_QCOM_SPMI_TEMP_ALARM is not set # CONFIG_QCOM_SPMI_VADC is not set +# CONFIG_QCOM_SSC_BLOCK_BUS is not set # CONFIG_QED is not set +# CONFIG_QFMT_V1 is not set # CONFIG_QLA3XXX is not set # CONFIG_QLCNIC is not set # CONFIG_QLGE is not set @@ -4897,12 +5139,15 @@ CONFIG_PWRSEQ_SIMPLE=y # CONFIG_QORIQ_CPUFREQ is not set # CONFIG_QORIQ_THERMAL is not set # CONFIG_QRTR is not set +# CONFIG_QRTR_MHI is not set +# CONFIG_QRTR_TUN is not set # CONFIG_QSEMI_PHY is not set # CONFIG_QUEUED_LOCK_STAT is not set # CONFIG_QUICC_ENGINE is not set # CONFIG_QUOTA is not set # CONFIG_QUOTACTL is not set # CONFIG_QUOTA_DEBUG is not set +# CONFIG_QUOTA_NETLINK_INTERFACE is not set # CONFIG_R3964 is not set # CONFIG_R6040 is not set # CONFIG_R8169 is not set @@ -4931,16 +5176,17 @@ CONFIG_PWRSEQ_SIMPLE=y # CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set # CONFIG_RANDOM_TRUST_BOOTLOADER is not set # CONFIG_RANDOM_TRUST_CPU is not set +# CONFIG_RANDSTRUCT_NONE is not set # CONFIG_RAPIDIO is not set # CONFIG_RAS is not set # CONFIG_RAW_DRIVER is not set # CONFIG_RBTREE_TEST is not set # CONFIG_RCU_BOOST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_CPU_STALL_TIMEOUT=60 # CONFIG_RCU_EQS_DEBUG is not set # CONFIG_RCU_EXPEDITE_BOOT is not set # CONFIG_RCU_EXPERT is not set -CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=20 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 CONFIG_RCU_KTHREAD_PRIO=0 CONFIG_RCU_NEED_SEGCBLIST=y # CONFIG_RCU_PERF_TEST is not set @@ -4968,6 +5214,9 @@ CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 # CONFIG_READ_ONLY_THP_FOR_FS is not set # CONFIG_REALTEK_PHY is not set # CONFIG_REDWOOD is not set +# CONFIG_REED_SOLOMON is not set +# CONFIG_REED_SOLOMON_DEC8 is not set +# CONFIG_REED_SOLOMON_ENC8 is not set # CONFIG_REED_SOLOMON_TEST is not set # CONFIG_REGMAP is not set # CONFIG_REGMAP_I2C is not set @@ -5009,6 +5258,8 @@ CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 # CONFIG_REGULATOR_MP886X is not set # CONFIG_REGULATOR_MPQ7920 is not set # CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_MT6315 is not set +# CONFIG_REGULATOR_MT6359 is not set # CONFIG_REGULATOR_PCA9450 is not set # CONFIG_REGULATOR_PF8X00 is not set # CONFIG_REGULATOR_PFUZE100 is not set @@ -5026,7 +5277,6 @@ CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 # CONFIG_REGULATOR_RTQ2134 is not set # CONFIG_REGULATOR_RTQ6752 is not set # CONFIG_REGULATOR_SLG51000 is not set -# CONFIG_REGULATOR_SY7636A is not set # CONFIG_REGULATOR_SY8106A is not set # CONFIG_REGULATOR_SY8824X is not set # CONFIG_REGULATOR_SY8827N is not set @@ -5078,8 +5328,10 @@ CONFIG_RFKILL=y # CONFIG_RFKILL_INPUT is not set # CONFIG_RFKILL_LEDS is not set # CONFIG_RFKILL_REGULATOR is not set +# CONFIG_RICHTEK_RTQ6056 is not set # CONFIG_RING_BUFFER_BENCHMARK is not set # CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set # CONFIG_RMI4_CORE is not set # CONFIG_RMNET is not set # CONFIG_ROCKCHIP_DW_HDMI is not set @@ -5098,6 +5350,7 @@ CONFIG_RFKILL=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPMSG_QCOM_GLINK_RPM is not set # CONFIG_RPMSG_VIRTIO is not set +# CONFIG_RPMSG_WWAN_CTRL is not set # CONFIG_RPR0521 is not set # CONFIG_RSEQ is not set # CONFIG_RT2X00 is not set @@ -5152,6 +5405,7 @@ CONFIG_RTC_DRV_CMOS=y # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_MAX6902 is not set # CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_MAX77686 is not set # CONFIG_RTC_DRV_MCP795 is not set # CONFIG_RTC_DRV_MOXART is not set # CONFIG_RTC_DRV_MPC5121 is not set @@ -5191,6 +5445,7 @@ CONFIG_RTC_DRV_CMOS=y # CONFIG_RTC_DRV_SNVS is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_SUN6I is not set +# CONFIG_RTC_DRV_TEGRA is not set # CONFIG_RTC_DRV_TEST is not set # CONFIG_RTC_DRV_V3020 is not set # CONFIG_RTC_DRV_X1205 is not set @@ -5259,6 +5514,7 @@ CONFIG_SBITMAP=y # CONFIG_SCACHE_DEBUGFS is not set # CONFIG_SCC is not set # CONFIG_SCD30_CORE is not set +# CONFIG_SCD4X is not set # CONFIG_SCF_TORTURE_TEST is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_AUTOGROUP is not set @@ -5362,10 +5618,20 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_SCSI_ULTRASTOR is not set # CONFIG_SCSI_VIRTIO is not set # CONFIG_SCSI_WD719X is not set +# CONFIG_SC_CAMCC_7180 is not set +# CONFIG_SC_DISPCC_7280 is not set +# CONFIG_SC_GCC_7280 is not set +# CONFIG_SC_GCC_8180X is not set +# CONFIG_SC_GPUCC_7280 is not set +# CONFIG_SC_GPUCC_8280XP is not set +# CONFIG_SC_VIDEOCC_7280 is not set # CONFIG_SCx200_ACB is not set # CONFIG_SDIO_UART is not set +# CONFIG_SDM_GPUCC_660 is not set +# CONFIG_SDM_MMCC_660 is not set # CONFIG_SDR_MAX2175 is not set # CONFIG_SDR_PLATFORM_DRIVERS is not set +# CONFIG_SDX_GCC_55 is not set # CONFIG_SD_ADC_MODULATOR is not set # CONFIG_SECCOMP is not set # CONFIG_SECCOMP_CACHE_DEBUG is not set @@ -5374,6 +5640,7 @@ CONFIG_SECTION_MISMATCH_WARN_ONLY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_APPARMOR is not set CONFIG_SECURITY_DMESG_RESTRICT=y +# CONFIG_SECURITY_LANDLOCK is not set # CONFIG_SECURITY_LOADPIN is not set # CONFIG_SECURITY_LOCKDOWN_LSM is not set # CONFIG_SECURITY_NETWORK_XFRM is not set @@ -5388,7 +5655,9 @@ CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 # CONFIG_SECURITY_TOMOYO is not set # CONFIG_SECURITY_YAMA is not set CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_SENSEAIR_SUNRISE_CO2 is not set # CONFIG_SENSIRION_SGP30 is not set +# CONFIG_SENSIRION_SGP40 is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_ACPI_POWER is not set @@ -5435,6 +5704,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_CORSAIR_CPRO is not set # CONFIG_SENSORS_CORSAIR_PSU is not set # CONFIG_SENSORS_DELL_SMM is not set +# CONFIG_SENSORS_DELTA_AHE50DC_FAN is not set # CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_DPS920AB is not set # CONFIG_SENSORS_DRIVETEMP is not set @@ -5442,6 +5712,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_DS620 is not set # CONFIG_SENSORS_EMC1403 is not set # CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC2305 is not set # CONFIG_SENSORS_EMC6W201 is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set @@ -5503,6 +5774,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_LM95234 is not set # CONFIG_SENSORS_LM95241 is not set # CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_LT7182S is not set # CONFIG_SENSORS_LTC2945 is not set # CONFIG_SENSORS_LTC2947_I2C is not set # CONFIG_SENSORS_LTC2947_SPI is not set @@ -5530,6 +5802,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_MAX20751 is not set # CONFIG_SENSORS_MAX31722 is not set # CONFIG_SENSORS_MAX31730 is not set +# CONFIG_SENSORS_MAX31760 is not set # CONFIG_SENSORS_MAX31785 is not set # CONFIG_SENSORS_MAX31790 is not set # CONFIG_SENSORS_MAX34440 is not set @@ -5543,6 +5816,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_MCP3021 is not set # CONFIG_SENSORS_MP2888 is not set # CONFIG_SENSORS_MP2975 is not set +# CONFIG_SENSORS_MP5023 is not set # CONFIG_SENSORS_MR75203 is not set # CONFIG_SENSORS_NCT6683 is not set # CONFIG_SENSORS_NCT6775 is not set @@ -5559,6 +5833,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_PIM4328 is not set +# CONFIG_SENSORS_PLI1209BC is not set # CONFIG_SENSORS_PM6764TR is not set # CONFIG_SENSORS_PMBUS is not set # CONFIG_SENSORS_POWR1220 is not set @@ -5584,7 +5859,6 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_STPDDC60 is not set # CONFIG_SENSORS_STTS751 is not set -# CONFIG_SENSORS_SY7636A is not set # CONFIG_SENSORS_TC654 is not set # CONFIG_SENSORS_TC74 is not set # CONFIG_SENSORS_THMC50 is not set @@ -5598,6 +5872,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_TPS23861 is not set # CONFIG_SENSORS_TPS40422 is not set # CONFIG_SENSORS_TPS53679 is not set +# CONFIG_SENSORS_TPS546D24 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_SENSORS_TSL2563 is not set # CONFIG_SENSORS_UCD9000 is not set @@ -5618,6 +5893,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_XDPE122 is not set +# CONFIG_SENSORS_XDPE152 is not set # CONFIG_SENSORS_XGENE is not set # CONFIG_SENSORS_ZL6100 is not set CONFIG_SERIAL_8250=y @@ -5700,6 +5976,7 @@ CONFIG_SERIAL_EARLYCON=y # CONFIG_SERIO_SUN4I_PS2 is not set # CONFIG_SFC is not set # CONFIG_SFC_FALCON is not set +# CONFIG_SFC_SIENA is not set # CONFIG_SFI is not set # CONFIG_SFP is not set # CONFIG_SF_PDMA is not set @@ -5715,7 +5992,6 @@ CONFIG_SERIAL_EARLYCON=y # CONFIG_SG_POOL is not set # CONFIG_SG_SPLIT is not set CONFIG_SHMEM=y -# CONFIG_SHORTCUT_FE is not set # CONFIG_SHRINKER_DEBUG is not set # CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set # CONFIG_SH_ETH is not set @@ -5771,7 +6047,13 @@ CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_SMSC_PHY is not set # CONFIG_SMS_SDIO_DRV is not set # CONFIG_SMS_USB_DRV is not set +# CONFIG_SM_CAMCC_8250 is not set # CONFIG_SM_FTL is not set +# CONFIG_SM_GCC_6115 is not set +# CONFIG_SM_GCC_6125 is not set +# CONFIG_SM_GCC_6350 is not set +# CONFIG_SM_GCC_6375 is not set +# CONFIG_SM_GCC_8350 is not set # CONFIG_SND is not set # CONFIG_SND_AC97_POWER_SAVE is not set # CONFIG_SND_AD1816A is not set @@ -5783,6 +6065,7 @@ CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_SND_ALS100 is not set # CONFIG_SND_ALS300 is not set # CONFIG_SND_ALS4000 is not set +# CONFIG_SND_AMD_ACP_CONFIG is not set # CONFIG_SND_ARM is not set # CONFIG_SND_ASIHPI is not set # CONFIG_SND_ATIIXP is not set @@ -5793,6 +6076,7 @@ CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_SND_AU8820 is not set # CONFIG_SND_AU8830 is not set # CONFIG_SND_AUDIO_GRAPH_CARD is not set +# CONFIG_SND_AUDIO_GRAPH_CARD2 is not set # CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set # CONFIG_SND_AW2 is not set # CONFIG_SND_AZT2320 is not set @@ -5809,7 +6093,10 @@ CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_SND_CS46XX is not set # CONFIG_SND_CS5530 is not set # CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTL_FAST_LOOKUP is not set +# CONFIG_SND_CTL_INPUT_VALIDATION is not set # CONFIG_SND_CTXFI is not set +# CONFIG_SND_DACBERRY400 is not set # CONFIG_SND_DARLA20 is not set # CONFIG_SND_DARLA24 is not set # CONFIG_SND_DEBUG is not set @@ -5835,6 +6122,7 @@ CONFIG_SND_DRIVERS=y # CONFIG_SND_GUSCLASSIC is not set # CONFIG_SND_GUSEXTREME is not set # CONFIG_SND_GUSMAX is not set +# CONFIG_SND_HDA_CODEC_CS8409 is not set # CONFIG_SND_HDA_INTEL is not set # CONFIG_SND_HDA_INTEL_DETECT_DMIC is not set # CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM is not set @@ -5919,6 +6207,8 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SIS7019 is not set # CONFIG_SND_SOC is not set # CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_AD193X_I2C is not set +# CONFIG_SND_SOC_AD193X_SPI is not set # CONFIG_SND_SOC_ADAU1372_I2C is not set # CONFIG_SND_SOC_ADAU1372_SPI is not set # CONFIG_SND_SOC_ADAU1701 is not set @@ -5927,8 +6217,10 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_ADAU7002 is not set # CONFIG_SND_SOC_ADAU7118_HW is not set # CONFIG_SND_SOC_ADAU7118_I2C is not set +# CONFIG_SND_SOC_ADI is not set # CONFIG_SND_SOC_AK4104 is not set # CONFIG_SND_SOC_AK4118 is not set +# CONFIG_SND_SOC_AK4375 is not set # CONFIG_SND_SOC_AK4458 is not set # CONFIG_SND_SOC_AK4554 is not set # CONFIG_SND_SOC_AK4613 is not set @@ -5938,9 +6230,11 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_ALC5623 is not set # CONFIG_SND_SOC_AMD_ACP is not set # CONFIG_SND_SOC_AMD_ACP3x is not set +# CONFIG_SND_SOC_AMD_ACP5x is not set # CONFIG_SND_SOC_AMD_RENOIR is not set # CONFIG_SND_SOC_AU1XAUDIO is not set # CONFIG_SND_SOC_AU1XPSC is not set +# CONFIG_SND_SOC_AW8738 is not set # CONFIG_SND_SOC_BD28623 is not set # CONFIG_SND_SOC_BT_SCO is not set # CONFIG_SND_SOC_CS35L32 is not set @@ -5948,6 +6242,10 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_CS35L34 is not set # CONFIG_SND_SOC_CS35L35 is not set # CONFIG_SND_SOC_CS35L36 is not set +# CONFIG_SND_SOC_CS35L41_I2C is not set +# CONFIG_SND_SOC_CS35L41_SPI is not set +# CONFIG_SND_SOC_CS35L45_I2C is not set +# CONFIG_SND_SOC_CS35L45_SPI is not set # CONFIG_SND_SOC_CS4234 is not set # CONFIG_SND_SOC_CS4265 is not set # CONFIG_SND_SOC_CS4270 is not set @@ -5959,6 +6257,7 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_CS42L52 is not set # CONFIG_SND_SOC_CS42L56 is not set # CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS42L83 is not set # CONFIG_SND_SOC_CS42XX8_I2C is not set # CONFIG_SND_SOC_CS43130 is not set # CONFIG_SND_SOC_CS4341 is not set @@ -5971,25 +6270,32 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_ES7134 is not set # CONFIG_SND_SOC_ES7241 is not set # CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_ES8326 is not set # CONFIG_SND_SOC_ES8328 is not set # CONFIG_SND_SOC_ES8328_I2C is not set # CONFIG_SND_SOC_ES8328_SPI is not set # CONFIG_SND_SOC_EUKREA_TLV320 is not set # CONFIG_SND_SOC_FSL_ASOC_CARD is not set # CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_AUD2HTX is not set # CONFIG_SND_SOC_FSL_AUDMIX is not set # CONFIG_SND_SOC_FSL_ESAI is not set # CONFIG_SND_SOC_FSL_MICFIL is not set +# CONFIG_SND_SOC_FSL_RPMSG is not set # CONFIG_SND_SOC_FSL_SAI is not set # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_SSI is not set # CONFIG_SND_SOC_FSL_XCVR is not set # CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_HDA is not set # CONFIG_SND_SOC_ICS43432 is not set # CONFIG_SND_SOC_IMG is not set # CONFIG_SND_SOC_IMX_AUDMIX is not set # CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_SOC_IMX_CARD is not set # CONFIG_SND_SOC_IMX_ES8328 is not set +# CONFIG_SND_SOC_IMX_HDMI is not set +# CONFIG_SND_SOC_IMX_RPMSG is not set # CONFIG_SND_SOC_IMX_SPDIF is not set # CONFIG_SND_SOC_IMX_WM8962 is not set # CONFIG_SND_SOC_INNO_RK3036 is not set @@ -6042,7 +6348,9 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_MAX98373 is not set # CONFIG_SND_SOC_MAX98373_I2C is not set # CONFIG_SND_SOC_MAX98390 is not set +# CONFIG_SND_SOC_MAX98396 is not set # CONFIG_SND_SOC_MAX98504 is not set +# CONFIG_SND_SOC_MAX98520 is not set # CONFIG_SND_SOC_MAX9860 is not set # CONFIG_SND_SOC_MAX9867 is not set # CONFIG_SND_SOC_MAX98927 is not set @@ -6054,14 +6362,19 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_MT2701 is not set # CONFIG_SND_SOC_MT6351 is not set # CONFIG_SND_SOC_MT6358 is not set +# CONFIG_SND_SOC_MT6359 is not set +# CONFIG_SND_SOC_MT6359_ACCDET is not set # CONFIG_SND_SOC_MT6660 is not set # CONFIG_SND_SOC_MT6797 is not set # CONFIG_SND_SOC_MT8173 is not set # CONFIG_SND_SOC_MT8183 is not set +# CONFIG_SND_SOC_MT8192 is not set +# CONFIG_SND_SOC_MT8195 is not set # CONFIG_SND_SOC_MTK_BTCVSD is not set # CONFIG_SND_SOC_NAU8315 is not set # CONFIG_SND_SOC_NAU8540 is not set # CONFIG_SND_SOC_NAU8810 is not set +# CONFIG_SND_SOC_NAU8821 is not set # CONFIG_SND_SOC_NAU8822 is not set # CONFIG_SND_SOC_NAU8824 is not set # CONFIG_SND_SOC_PCM1681 is not set @@ -6075,6 +6388,7 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_PCM3060_SPI is not set # CONFIG_SND_SOC_PCM3168A_I2C is not set # CONFIG_SND_SOC_PCM3168A_SPI is not set +# CONFIG_SND_SOC_PCM5102A is not set # CONFIG_SND_SOC_PCM512x_I2C is not set # CONFIG_SND_SOC_PCM512x_SPI is not set # CONFIG_SND_SOC_QCOM is not set @@ -6086,13 +6400,16 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_RT5640 is not set # CONFIG_SND_SOC_RT5659 is not set # CONFIG_SND_SOC_RT5677_SPI is not set +# CONFIG_SND_SOC_RT9120 is not set # CONFIG_SND_SOC_SGTL5000 is not set # CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set # CONFIG_SND_SOC_SIMPLE_MUX is not set # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set # CONFIG_SND_SOC_SOF_TOPLEVEL is not set # CONFIG_SND_SOC_SPDIF is not set +# CONFIG_SND_SOC_SRC4XXX_I2C is not set # CONFIG_SND_SOC_SSM2305 is not set +# CONFIG_SND_SOC_SSM2518 is not set # CONFIG_SND_SOC_SSM2602_I2C is not set # CONFIG_SND_SOC_SSM2602_SPI is not set # CONFIG_SND_SOC_SSM4567 is not set @@ -6103,13 +6420,16 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_TAS2562 is not set # CONFIG_SND_SOC_TAS2764 is not set # CONFIG_SND_SOC_TAS2770 is not set +# CONFIG_SND_SOC_TAS2780 is not set # CONFIG_SND_SOC_TAS5086 is not set # CONFIG_SND_SOC_TAS571X is not set # CONFIG_SND_SOC_TAS5720 is not set +# CONFIG_SND_SOC_TAS5805M is not set # CONFIG_SND_SOC_TAS6424 is not set # CONFIG_SND_SOC_TDA7419 is not set # CONFIG_SND_SOC_TFA9879 is not set # CONFIG_SND_SOC_TFA989X is not set +# CONFIG_SND_SOC_TLV320ADC3XXX is not set # CONFIG_SND_SOC_TLV320ADCX140 is not set # CONFIG_SND_SOC_TLV320AIC23_I2C is not set # CONFIG_SND_SOC_TLV320AIC23_SPI is not set @@ -6131,6 +6451,8 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_WM8711 is not set # CONFIG_SND_SOC_WM8728 is not set # CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8731_I2C is not set +# CONFIG_SND_SOC_WM8731_SPI is not set # CONFIG_SND_SOC_WM8737 is not set # CONFIG_SND_SOC_WM8741 is not set # CONFIG_SND_SOC_WM8750 is not set @@ -6142,6 +6464,7 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_WM8804_SPI is not set # CONFIG_SND_SOC_WM8903 is not set # CONFIG_SND_SOC_WM8904 is not set +# CONFIG_SND_SOC_WM8940 is not set # CONFIG_SND_SOC_WM8960 is not set # CONFIG_SND_SOC_WM8962 is not set # CONFIG_SND_SOC_WM8974 is not set @@ -6160,6 +6483,7 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set # CONFIG_SND_SUN4I_CODEC is not set # CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_TEST_COMPONENT is not set # CONFIG_SND_TIMER is not set # CONFIG_SND_TRIDENT is not set CONFIG_SND_USB=y @@ -6178,6 +6502,7 @@ CONFIG_SND_USB=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VIA82XX is not set # CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTIO is not set # CONFIG_SND_VIRTUOSO is not set # CONFIG_SND_VX222 is not set # CONFIG_SND_VXPOCKET is not set @@ -6197,6 +6522,7 @@ CONFIG_SND_X86=y # CONFIG_SOC_HAS_OMAP2_SDRC is not set # CONFIG_SOC_OMAP5 is not set # CONFIG_SOC_TI is not set +# CONFIG_SOFTIRQ_ON_OWN_STACK is not set # CONFIG_SOFTLOCKUP_DETECTOR is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_SOLARIS_X86_PARTITION is not set @@ -6243,6 +6569,7 @@ CONFIG_SND_X86=y # CONFIG_SPI_MASTER is not set # CONFIG_SPI_MEM is not set # CONFIG_SPI_MICROCHIP_CORE is not set +# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MPC52xx is not set # CONFIG_SPI_MPC52xx_PSC is not set # CONFIG_SPI_MTK_QUADSPI is not set @@ -6276,6 +6603,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_SPMI is not set # CONFIG_SPS30 is not set # CONFIG_SPS30_I2C is not set +# CONFIG_SPS30_SERIAL is not set CONFIG_SQUASHFS=y # CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set # CONFIG_SQUASHFS_DECOMP_MULTI is not set @@ -6329,6 +6657,7 @@ CONFIG_STDBINUTILS=y # CONFIG_STMMAC_ETH is not set # CONFIG_STMMAC_PCI is not set # CONFIG_STMMAC_PLATFORM is not set +# CONFIG_STMMAC_SELFTESTS is not set # CONFIG_STM_DUMMY is not set # CONFIG_STM_SOURCE_CONSOLE is not set CONFIG_STP=y @@ -6365,6 +6694,8 @@ CONFIG_SWAP=y # CONFIG_SWCONFIG_LEDS is not set # CONFIG_SW_SYNC is not set # CONFIG_SX9310 is not set +# CONFIG_SX9324 is not set +# CONFIG_SX9360 is not set # CONFIG_SX9500 is not set # CONFIG_SXGBE_ETH is not set CONFIG_SYMBOLIC_ERRNAME=y @@ -6447,12 +6778,14 @@ CONFIG_TCP_CONG_CUBIC=y # CONFIG_TEST_BITOPS is not set # CONFIG_TEST_BLACKHOLE_DEV is not set # CONFIG_TEST_BPF is not set +# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set # CONFIG_TEST_DIV64 is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_FREE_PAGES is not set # CONFIG_TEST_HASH is not set # CONFIG_TEST_HEXDUMP is not set # CONFIG_TEST_IDA is not set +# CONFIG_TEST_KASAN_MODULE is not set # CONFIG_TEST_KMOD is not set # CONFIG_TEST_KSTRTOX is not set # CONFIG_TEST_LIST_SORT is not set @@ -6474,6 +6807,7 @@ CONFIG_TCP_CONG_CUBIC=y # CONFIG_TEST_STRING_HELPERS is not set # CONFIG_TEST_STRSCPY is not set # CONFIG_TEST_SYSCTL is not set +# CONFIG_TEST_UBSAN is not set # CONFIG_TEST_UDELAY is not set # CONFIG_TEST_USER_COPY is not set # CONFIG_TEST_UUID is not set @@ -6514,9 +6848,11 @@ CONFIG_TIERS_PER_GEN=4 # CONFIG_TIGON3 is not set # CONFIG_TIMB_DMA is not set CONFIG_TIMERFD=y +# CONFIG_TIMERLAT_TRACER is not set # CONFIG_TIMER_STATS is not set # CONFIG_TIME_NS is not set # CONFIG_TINYDRM_HX8357D is not set +# CONFIG_TINYDRM_ILI9163 is not set # CONFIG_TINYDRM_ILI9225 is not set # CONFIG_TINYDRM_ILI9341 is not set # CONFIG_TINYDRM_ILI9486 is not set @@ -6614,6 +6950,7 @@ CONFIG_TMPFS_XATTR=y # CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set # CONFIG_TOUCHSCREEN_ILI210X is not set # CONFIG_TOUCHSCREEN_ILITEK is not set +# CONFIG_TOUCHSCREEN_IMAGIS is not set # CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set @@ -6706,6 +7043,7 @@ CONFIG_TMPFS_XATTR=y # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_TRACE_EVAL_MAP_FILE is not set # CONFIG_TRACE_EVENT_INJECT is not set +# CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT is not set CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_TRACE_SINK is not set # CONFIG_TRACING_EVENTS_GPIO is not set @@ -6738,12 +7076,8 @@ CONFIG_TTY=y # CONFIG_TWL6040_CORE is not set # CONFIG_TXGBE is not set # CONFIG_TYPEC is not set -# CONFIG_TYPEC_ANX7411 is not set -# CONFIG_TYPEC_MUX_FSA4480 is not set -# CONFIG_TYPEC_RT1719 is not set # CONFIG_TYPEC_TCPM is not set # CONFIG_TYPEC_UCSI is not set -# CONFIG_TYPEC_WUSB3801 is not set # CONFIG_TYPHOON is not set # CONFIG_UACCESS_WITH_MEMCPY is not set # CONFIG_UBIFS_ATIME_SUPPORT is not set @@ -6757,6 +7091,7 @@ CONFIG_UBIFS_FS_ZLIB=y CONFIG_UBIFS_FS_ZSTD=y # CONFIG_UBSAN is not set CONFIG_UBSAN_ALIGNMENT=y +# CONFIG_UBSAN_MISC is not set # CONFIG_UCB1400_CORE is not set # CONFIG_UCSI is not set # CONFIG_UDF_FS is not set @@ -6801,6 +7136,7 @@ CONFIG_USB_AN2720=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARMLINUX=y # CONFIG_USB_ATM is not set +# CONFIG_USB_AUDIO is not set CONFIG_USB_AUTOSUSPEND_DELAY=2 # CONFIG_USB_BDC_UDC is not set CONFIG_USB_BELKIN=y @@ -6854,6 +7190,7 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y # CONFIG_USB_EMI26 is not set # CONFIG_USB_EMI62 is not set # CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_ETH is not set # CONFIG_USB_EZUSB_FX2 is not set # CONFIG_USB_FEW_INIT_RETRIES is not set # CONFIG_USB_FOTG210_HCD is not set @@ -6974,7 +7311,9 @@ CONFIG_USB_GADGET_VBUS_DRAW=2 # CONFIG_USB_MSI2500 is not set # CONFIG_USB_MSM_OTG is not set # CONFIG_USB_MTU3 is not set +# CONFIG_USB_MUSB_GADGET is not set # CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_MUSB_HOST is not set # CONFIG_USB_MV_U3D is not set # CONFIG_USB_MV_UDC is not set # CONFIG_USB_MXS_PHY is not set @@ -7028,6 +7367,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_PRINTER is not set # CONFIG_USB_PWC_INPUT_EVDEV is not set # CONFIG_USB_PXA27X is not set +# CONFIG_USB_QCOM_EUD is not set # CONFIG_USB_R8A66597 is not set # CONFIG_USB_R8A66597_HCD is not set # CONFIG_USB_RAW_GADGET is not set @@ -7187,6 +7527,7 @@ CONFIG_VDSO=y # CONFIG_VFIO is not set # CONFIG_VGASTATE is not set # CONFIG_VGA_ARB is not set +# CONFIG_VGA_CONSOLE is not set # CONFIG_VGA_SWITCHEROO is not set # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set CONFIG_VHOST_MENU=y @@ -7194,6 +7535,7 @@ CONFIG_VHOST_MENU=y # CONFIG_VHOST_VSOCK is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_VELOCITY is not set +# CONFIG_VIDEO_AD5398 is not set # CONFIG_VIDEO_AD5820 is not set # CONFIG_VIDEO_AD9389B is not set # CONFIG_VIDEO_ADP1653 is not set @@ -7210,13 +7552,21 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_AK7375 is not set # CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_AM437X_VPFE is not set +# CONFIG_VIDEO_AR0521 is not set +# CONFIG_VIDEO_ARDUCAM_64MP is not set +# CONFIG_VIDEO_ARDUCAM_PIVARIETY is not set # CONFIG_VIDEO_ASPEED is not set +# CONFIG_VIDEO_ATMEL_ISC is not set +# CONFIG_VIDEO_ATMEL_ISI is not set # CONFIG_VIDEO_AU0828 is not set # CONFIG_VIDEO_BT819 is not set # CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_BT856 is not set # CONFIG_VIDEO_BT866 is not set # CONFIG_VIDEO_CADENCE is not set +# CONFIG_VIDEO_CADENCE_CSI2RX is not set +# CONFIG_VIDEO_CADENCE_CSI2TX is not set # CONFIG_VIDEO_CAFE_CCIC is not set # CONFIG_VIDEO_CCS is not set # CONFIG_VIDEO_CS3308 is not set @@ -7242,18 +7592,26 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_HEXIUM_GEMINI is not set # CONFIG_VIDEO_HEXIUM_ORION is not set # CONFIG_VIDEO_HI556 is not set +# CONFIG_VIDEO_HI846 is not set +# CONFIG_VIDEO_HI847 is not set # CONFIG_VIDEO_I2C is not set +# CONFIG_VIDEO_IMX208 is not set # CONFIG_VIDEO_IMX214 is not set # CONFIG_VIDEO_IMX219 is not set # CONFIG_VIDEO_IMX258 is not set # CONFIG_VIDEO_IMX274 is not set # CONFIG_VIDEO_IMX290 is not set +# CONFIG_VIDEO_IMX296 is not set # CONFIG_VIDEO_IMX319 is not set # CONFIG_VIDEO_IMX334 is not set +# CONFIG_VIDEO_IMX335 is not set # CONFIG_VIDEO_IMX355 is not set +# CONFIG_VIDEO_IMX412 is not set # CONFIG_VIDEO_IMX477 is not set +# CONFIG_VIDEO_IMX519 is not set # CONFIG_VIDEO_IRS1125 is not set # CONFIG_VIDEO_IR_I2C is not set +# CONFIG_VIDEO_ISL7998X is not set # CONFIG_VIDEO_IVTV is not set # CONFIG_VIDEO_KS0127 is not set # CONFIG_VIDEO_LM3560 is not set @@ -7275,9 +7633,13 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_MUX is not set # CONFIG_VIDEO_MXB is not set # CONFIG_VIDEO_NOON010PC30 is not set +# CONFIG_VIDEO_OG01A1B is not set # CONFIG_VIDEO_OMAP2_VOUT is not set # CONFIG_VIDEO_OV02A10 is not set +# CONFIG_VIDEO_OV08D10 is not set # CONFIG_VIDEO_OV13858 is not set +# CONFIG_VIDEO_OV13B10 is not set +# CONFIG_VIDEO_OV2311 is not set # CONFIG_VIDEO_OV2640 is not set # CONFIG_VIDEO_OV2659 is not set # CONFIG_VIDEO_OV2680 is not set @@ -7286,8 +7648,10 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_OV5640 is not set # CONFIG_VIDEO_OV5645 is not set # CONFIG_VIDEO_OV5647 is not set +# CONFIG_VIDEO_OV5648 is not set # CONFIG_VIDEO_OV5670 is not set # CONFIG_VIDEO_OV5675 is not set +# CONFIG_VIDEO_OV5693 is not set # CONFIG_VIDEO_OV5695 is not set # CONFIG_VIDEO_OV6650 is not set # CONFIG_VIDEO_OV7251 is not set @@ -7296,9 +7660,12 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_OV772X is not set # CONFIG_VIDEO_OV7740 is not set # CONFIG_VIDEO_OV8856 is not set +# CONFIG_VIDEO_OV8865 is not set # CONFIG_VIDEO_OV9281 is not set +# CONFIG_VIDEO_OV9282 is not set # CONFIG_VIDEO_OV9640 is not set # CONFIG_VIDEO_OV9650 is not set +# CONFIG_VIDEO_OV9734 is not set # CONFIG_VIDEO_PVRUSB2 is not set # CONFIG_VIDEO_RDACM20 is not set # CONFIG_VIDEO_RDACM21 is not set @@ -7479,6 +7846,7 @@ CONFIG_WLAN=y CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y # CONFIG_WQ_WATCHDOG is not set # CONFIG_WWAN is not set +# CONFIG_WWAN_HWSIM is not set # CONFIG_WW_MUTEX_SELFTEST is not set # CONFIG_X25 is not set # CONFIG_X509_CERTIFICATE_PARSER is not set @@ -7555,9 +7923,12 @@ CONFIG_ZONE_DMA=y # CONFIG_ZPA2326 is not set # CONFIG_ZPOOL is not set # CONFIG_ZRAM is not set +# CONFIG_ZRAM_DEF_COMP_LZ4 is not set +# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set +# CONFIG_ZRAM_DEF_COMP_LZO is not set +# CONFIG_ZRAM_DEF_COMP_LZORLE is not set +# CONFIG_ZRAM_DEF_COMP_ZSTD is not set # CONFIG_ZRAM_MEMORY_TRACKING is not set # CONFIG_ZSMALLOC is not set -# CONFIG_ZSTD_COMPRESS is not set -# CONFIG_ZSTD_DECOMPRESS is not set # CONFIG_ZSWAP is not set # CONFIG_ZX_TDM is not set diff --git a/target/linux/generic/hack-6.0/249-udp-tunnel-selection.patch b/target/linux/generic/hack-6.0/249-udp-tunnel-selection.patch deleted file mode 100644 index 2c74298df..000000000 --- a/target/linux/generic/hack-6.0/249-udp-tunnel-selection.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/ipv4/Kconfig -+++ b/net/ipv4/Kconfig -@@ -315,7 +315,7 @@ config NET_IPVTI - on top. - - config NET_UDP_TUNNEL -- tristate -+ tristate "IP: UDP tunneling support" - select NET_IP_TUNNEL - default n - diff --git a/target/linux/generic/hack-6.0/252-SATA_PMP.patch b/target/linux/generic/hack-6.0/252-SATA_PMP.patch deleted file mode 100644 index 6502d1d6e..000000000 --- a/target/linux/generic/hack-6.0/252-SATA_PMP.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 8c817e33be829c7249c2cfd59ff48ad5fac6a31d Mon Sep 17 00:00:00 2001 -From: Sungbo Eo -Date: Fri, 7 Jul 2017 17:09:21 +0200 -Subject: [PATCH] kconfig: solidify SATA_PMP config - -SATA_PMP option in kernel config file disappears for every kernel_oldconfig refresh. -To prevent this, SATA_HOST is now selected automatically when SATA_PMP is enabled. -This patch can be dropped if SATA_MV is ever re-added into the config. ---- - drivers/ata/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/ata/Kconfig -+++ b/drivers/ata/Kconfig -@@ -112,7 +112,7 @@ config SATA_ZPODD - - config SATA_PMP - bool "SATA Port Multiplier support" -- depends on SATA_HOST -+ select SATA_HOST - default y - help - This option adds support for SATA Port Multipliers diff --git a/target/linux/generic/hack-6.0/253-ksmbd-config.patch b/target/linux/generic/hack-6.0/253-ksmbd-config.patch deleted file mode 100644 index 890374d28..000000000 --- a/target/linux/generic/hack-6.0/253-ksmbd-config.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1954,7 +1954,7 @@ config PADATA - bool - - config ASN1 -- tristate -+ tristate "ASN1" - help - Build a simple ASN.1 grammar compiler that produces a bytecode output - that can be interpreted by the ASN.1 stream decoder and used to ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -627,7 +627,7 @@ config LIBFDT - bool - - config OID_REGISTRY -- tristate -+ tristate "OID" - help - Enable fast lookup object identifier registry. - diff --git a/target/linux/generic/hack-6.0/261-lib-arc4-unhide.patch b/target/linux/generic/hack-6.0/261-lib-arc4-unhide.patch deleted file mode 100644 index 4ffd8cfa3..000000000 --- a/target/linux/generic/hack-6.0/261-lib-arc4-unhide.patch +++ /dev/null @@ -1,15 +0,0 @@ -This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We -need this to be able to compile this into the kernel and make use of it -from backports. - ---- a/lib/crypto/Kconfig -+++ b/lib/crypto/Kconfig -@@ -6,7 +6,7 @@ config CRYPTO_LIB_AES - tristate - - config CRYPTO_LIB_ARC4 -- tristate -+ tristate "ARC4 cipher library" - - config CRYPTO_ARCH_HAVE_LIB_BLAKE2S - bool diff --git a/target/linux/generic/hack-6.0/301-mips_image_cmdline_hack.patch b/target/linux/generic/hack-6.0/301-mips_image_cmdline_hack.patch deleted file mode 100644 index eaf839601..000000000 --- a/target/linux/generic/hack-6.0/301-mips_image_cmdline_hack.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: John Crispin -Subject: hack: kernel: add generic image_cmdline hack to MIPS targets - -lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976 -Signed-off-by: Gabor Juhos ---- - arch/mips/Kconfig | 4 ++++ - arch/mips/kernel/head.S | 6 ++++++ - 2 files changed, 10 insertions(+) - ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1112,6 +1112,10 @@ config MIPS_MSC - config SYNC_R4K - bool - -+config IMAGE_CMDLINE_HACK -+ bool "OpenWrt specific image command line hack" -+ default n -+ - config NO_IOPORT_MAP - def_bool n - ---- a/arch/mips/kernel/head.S -+++ b/arch/mips/kernel/head.S -@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry) - j kernel_entry - #endif /* CONFIG_BOOT_RAW */ - -+#ifdef CONFIG_IMAGE_CMDLINE_HACK -+ .ascii "CMDLINE:" -+EXPORT(__image_cmdline) -+ .fill 0x400 -+#endif /* CONFIG_IMAGE_CMDLINE_HACK */ -+ - __REF - - NESTED(kernel_entry, 16, sp) # kernel entry point diff --git a/target/linux/generic/hack-6.0/430-mtk-bmt-support.patch b/target/linux/generic/hack-6.0/430-mtk-bmt-support.patch deleted file mode 100644 index f782e07cd..000000000 --- a/target/linux/generic/hack-6.0/430-mtk-bmt-support.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -61,6 +61,10 @@ config MTD_NAND_ECC_MEDIATEK - help - This enables support for the hardware ECC engine from Mediatek. - -+config MTD_NAND_MTK_BMT -+ bool "Support MediaTek NAND Bad-block Management Table" -+ default n -+ - endmenu - - endmenu ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -3,6 +3,7 @@ - nandcore-objs := core.o bbt.o - obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o - obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o -+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o - - obj-y += onenand/ - obj-y += raw/ diff --git a/target/linux/generic/hack-6.0/531-debloat_lzma.patch b/target/linux/generic/hack-6.0/531-debloat_lzma.patch deleted file mode 100644 index 2f70eee3e..000000000 --- a/target/linux/generic/hack-6.0/531-debloat_lzma.patch +++ /dev/null @@ -1,1040 +0,0 @@ -From 3fd297761ac246c54d7723c57fca95c112b99465 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 15 Jul 2017 21:15:44 +0200 -Subject: lzma: de-bloat the lzma library used by jffs2 - -lede-commit: 3fd1dd08fbcbb78b34efefd32c3032e5c99108d6 -Signed-off-by: Felix Fietkau ---- - include/linux/lzma/LzFind.h | 17 --- - include/linux/lzma/LzmaDec.h | 101 --------------- - include/linux/lzma/LzmaEnc.h | 20 --- - lib/lzma/LzFind.c | 287 ++++--------------------------------------- - lib/lzma/LzmaDec.c | 86 +------------ - lib/lzma/LzmaEnc.c | 172 ++------------------------ - 6 files changed, 42 insertions(+), 641 deletions(-) - ---- a/include/linux/lzma/LzFind.h -+++ b/include/linux/lzma/LzFind.h -@@ -55,11 +55,6 @@ typedef struct _CMatchFinder - - #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) - --int MatchFinder_NeedMove(CMatchFinder *p); --Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); --void MatchFinder_MoveBlock(CMatchFinder *p); --void MatchFinder_ReadIfRequired(CMatchFinder *p); -- - void MatchFinder_Construct(CMatchFinder *p); - - /* Conditions: -@@ -70,12 +65,6 @@ int MatchFinder_Create(CMatchFinder *p, - UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc); - void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); --void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); --void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); -- --UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, -- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, -- UInt32 *distances, UInt32 maxLen); - - /* - Conditions: -@@ -102,12 +91,6 @@ typedef struct _IMatchFinder - - void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); - --void MatchFinder_Init(CMatchFinder *p); --UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); --UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); --void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); --void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -- - #ifdef __cplusplus - } - #endif ---- a/include/linux/lzma/LzmaDec.h -+++ b/include/linux/lzma/LzmaDec.h -@@ -31,14 +31,6 @@ typedef struct _CLzmaProps - UInt32 dicSize; - } CLzmaProps; - --/* LzmaProps_Decode - decodes properties --Returns: -- SZ_OK -- SZ_ERROR_UNSUPPORTED - Unsupported properties --*/ -- --SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); -- - - /* ---------- LZMA Decoder state ---------- */ - -@@ -70,8 +62,6 @@ typedef struct - - #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } - --void LzmaDec_Init(CLzmaDec *p); -- - /* There are two types of LZMA streams: - 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -@@ -108,97 +98,6 @@ typedef enum - - /* ELzmaStatus is used only as output value for function call */ - -- --/* ---------- Interfaces ---------- */ -- --/* There are 3 levels of interfaces: -- 1) Dictionary Interface -- 2) Buffer Interface -- 3) One Call Interface -- You can select any of these interfaces, but don't mix functions from different -- groups for same object. */ -- -- --/* There are two variants to allocate state for Dictionary Interface: -- 1) LzmaDec_Allocate / LzmaDec_Free -- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs -- You can use variant 2, if you set dictionary buffer manually. -- For Buffer Interface you must always use variant 1. -- --LzmaDec_Allocate* can return: -- SZ_OK -- SZ_ERROR_MEM - Memory allocation error -- SZ_ERROR_UNSUPPORTED - Unsupported properties --*/ -- --SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); --void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); -- --SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); --void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); -- --/* ---------- Dictionary Interface ---------- */ -- --/* You can use it, if you want to eliminate the overhead for data copying from -- dictionary to some other external buffer. -- You must work with CLzmaDec variables directly in this interface. -- -- STEPS: -- LzmaDec_Constr() -- LzmaDec_Allocate() -- for (each new stream) -- { -- LzmaDec_Init() -- while (it needs more decompression) -- { -- LzmaDec_DecodeToDic() -- use data from CLzmaDec::dic and update CLzmaDec::dicPos -- } -- } -- LzmaDec_Free() --*/ -- --/* LzmaDec_DecodeToDic -- -- The decoding to internal dictionary buffer (CLzmaDec::dic). -- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! -- --finishMode: -- It has meaning only if the decoding reaches output limit (dicLimit). -- LZMA_FINISH_ANY - Decode just dicLimit bytes. -- LZMA_FINISH_END - Stream must be finished after dicLimit. -- --Returns: -- SZ_OK -- status: -- LZMA_STATUS_FINISHED_WITH_MARK -- LZMA_STATUS_NOT_FINISHED -- LZMA_STATUS_NEEDS_MORE_INPUT -- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -- SZ_ERROR_DATA - Data error --*/ -- --SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, -- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -- -- --/* ---------- Buffer Interface ---------- */ -- --/* It's zlib-like interface. -- See LzmaDec_DecodeToDic description for information about STEPS and return results, -- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need -- to work with CLzmaDec variables manually. -- --finishMode: -- It has meaning only if the decoding reaches output limit (*destLen). -- LZMA_FINISH_ANY - Decode just destLen bytes. -- LZMA_FINISH_END - Stream must be finished after (*destLen). --*/ -- --SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, -- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -- -- - /* ---------- One Call Interface ---------- */ - - /* LzmaDecode ---- a/include/linux/lzma/LzmaEnc.h -+++ b/include/linux/lzma/LzmaEnc.h -@@ -31,9 +31,6 @@ typedef struct _CLzmaEncProps - } CLzmaEncProps; - - void LzmaEncProps_Init(CLzmaEncProps *p); --void LzmaEncProps_Normalize(CLzmaEncProps *p); --UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); -- - - /* ---------- CLzmaEncHandle Interface ---------- */ - -@@ -53,26 +50,9 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc * - void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); - SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); - SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); --SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, -- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - --/* ---------- One Call Interface ---------- */ -- --/* LzmaEncode --Return code: -- SZ_OK - OK -- SZ_ERROR_MEM - Memory allocation error -- SZ_ERROR_PARAM - Incorrect paramater -- SZ_ERROR_OUTPUT_EOF - output buffer overflow -- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) --*/ -- --SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -- - #ifdef __cplusplus - } - #endif ---- a/lib/lzma/LzFind.c -+++ b/lib/lzma/LzFind.c -@@ -14,9 +14,15 @@ - - #define kStartMaxLen 3 - -+#if 0 -+#define DIRECT_INPUT p->directInput -+#else -+#define DIRECT_INPUT 1 -+#endif -+ - static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) - { -- if (!p->directInput) -+ if (!DIRECT_INPUT) - { - alloc->Free(alloc, p->bufferBase); - p->bufferBase = 0; -@@ -28,7 +34,7 @@ static void LzInWindow_Free(CMatchFinder - static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) - { - UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -- if (p->directInput) -+ if (DIRECT_INPUT) - { - p->blockSize = blockSize; - return 1; -@@ -42,12 +48,12 @@ static int LzInWindow_Create(CMatchFinde - return (p->bufferBase != 0); - } - --Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } --Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -+static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -+static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } - --UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -+static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } - --void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -+static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) - { - p->posLimit -= subValue; - p->pos -= subValue; -@@ -58,7 +64,7 @@ static void MatchFinder_ReadBlock(CMatch - { - if (p->streamEndWasReached || p->result != SZ_OK) - return; -- if (p->directInput) -+ if (DIRECT_INPUT) - { - UInt32 curSize = 0xFFFFFFFF - p->streamPos; - if (curSize > p->directInputRem) -@@ -89,7 +95,7 @@ static void MatchFinder_ReadBlock(CMatch - } - } - --void MatchFinder_MoveBlock(CMatchFinder *p) -+static void MatchFinder_MoveBlock(CMatchFinder *p) - { - memmove(p->bufferBase, - p->buffer - p->keepSizeBefore, -@@ -97,22 +103,14 @@ void MatchFinder_MoveBlock(CMatchFinder - p->buffer = p->bufferBase + p->keepSizeBefore; - } - --int MatchFinder_NeedMove(CMatchFinder *p) -+static int MatchFinder_NeedMove(CMatchFinder *p) - { -- if (p->directInput) -+ if (DIRECT_INPUT) - return 0; - /* if (p->streamEndWasReached) return 0; */ - return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); - } - --void MatchFinder_ReadIfRequired(CMatchFinder *p) --{ -- if (p->streamEndWasReached) -- return; -- if (p->keepSizeAfter >= p->streamPos - p->pos) -- MatchFinder_ReadBlock(p); --} -- - static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) - { - if (MatchFinder_NeedMove(p)) -@@ -268,7 +266,7 @@ static void MatchFinder_SetLimits(CMatch - p->posLimit = p->pos + limit; - } - --void MatchFinder_Init(CMatchFinder *p) -+static void MatchFinder_Init(CMatchFinder *p) - { - UInt32 i; - for (i = 0; i < p->hashSizeSum; i++) -@@ -287,7 +285,7 @@ static UInt32 MatchFinder_GetSubValue(CM - return (p->pos - p->historySize - 1) & kNormalizeMask; - } - --void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -+static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) - { - UInt32 i; - for (i = 0; i < numItems; i++) -@@ -319,38 +317,7 @@ static void MatchFinder_CheckLimits(CMat - MatchFinder_SetLimits(p); - } - --static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -- UInt32 *distances, UInt32 maxLen) --{ -- son[_cyclicBufferPos] = curMatch; -- for (;;) -- { -- UInt32 delta = pos - curMatch; -- if (cutValue-- == 0 || delta >= _cyclicBufferSize) -- return distances; -- { -- const Byte *pb = cur - delta; -- curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; -- if (pb[maxLen] == cur[maxLen] && *pb == *cur) -- { -- UInt32 len = 0; -- while (++len != lenLimit) -- if (pb[len] != cur[len]) -- break; -- if (maxLen < len) -- { -- *distances++ = maxLen = len; -- *distances++ = delta - 1; -- if (len == lenLimit) -- return distances; -- } -- } -- } -- } --} -- --UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, - UInt32 *distances, UInt32 maxLen) - { -@@ -460,10 +427,10 @@ static void SkipMatchesSpec(UInt32 lenLi - p->buffer++; \ - if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); - --#define MOVE_POS_RET MOVE_POS return offset; -- - static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } - -+#define MOVE_POS_RET MatchFinder_MovePos(p); return offset; -+ - #define GET_MATCHES_HEADER2(minLen, ret_op) \ - UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ - lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -@@ -479,62 +446,7 @@ static void MatchFinder_MovePos(CMatchFi - distances + offset, maxLen) - distances); MOVE_POS_RET; - - #define SKIP_FOOTER \ -- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -- --static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 offset; -- GET_MATCHES_HEADER(2) -- HASH2_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- offset = 0; -- GET_MATCHES_FOOTER(offset, 1) --} -- --UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 offset; -- GET_MATCHES_HEADER(3) -- HASH_ZIP_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- offset = 0; -- GET_MATCHES_FOOTER(offset, 2) --} -- --static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 hash2Value, delta2, maxLen, offset; -- GET_MATCHES_HEADER(3) -- -- HASH3_CALC; -- -- delta2 = p->pos - p->hash[hash2Value]; -- curMatch = p->hash[kFix3HashSize + hashValue]; -- -- p->hash[hash2Value] = -- p->hash[kFix3HashSize + hashValue] = p->pos; -- -- -- maxLen = 2; -- offset = 0; -- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -- { -- for (; maxLen != lenLimit; maxLen++) -- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -- break; -- distances[0] = maxLen; -- distances[1] = delta2 - 1; -- offset = 2; -- if (maxLen == lenLimit) -- { -- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -- MOVE_POS_RET; -- } -- } -- GET_MATCHES_FOOTER(offset, maxLen) --} -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MatchFinder_MovePos(p); - - static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) - { -@@ -583,108 +495,6 @@ static UInt32 Bt4_MatchFinder_GetMatches - GET_MATCHES_FOOTER(offset, maxLen) - } - --static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -- GET_MATCHES_HEADER(4) -- -- HASH4_CALC; -- -- delta2 = p->pos - p->hash[ hash2Value]; -- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -- curMatch = p->hash[kFix4HashSize + hashValue]; -- -- p->hash[ hash2Value] = -- p->hash[kFix3HashSize + hash3Value] = -- p->hash[kFix4HashSize + hashValue] = p->pos; -- -- maxLen = 1; -- offset = 0; -- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -- { -- distances[0] = maxLen = 2; -- distances[1] = delta2 - 1; -- offset = 2; -- } -- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -- { -- maxLen = 3; -- distances[offset + 1] = delta3 - 1; -- offset += 2; -- delta2 = delta3; -- } -- if (offset != 0) -- { -- for (; maxLen != lenLimit; maxLen++) -- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -- break; -- distances[offset - 2] = maxLen; -- if (maxLen == lenLimit) -- { -- p->son[p->cyclicBufferPos] = curMatch; -- MOVE_POS_RET; -- } -- } -- if (maxLen < 3) -- maxLen = 3; -- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -- distances + offset, maxLen) - (distances)); -- MOVE_POS_RET --} -- --UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) --{ -- UInt32 offset; -- GET_MATCHES_HEADER(3) -- HASH_ZIP_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -- distances, 2) - (distances)); -- MOVE_POS_RET --} -- --static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- SKIP_HEADER(2) -- HASH2_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- SKIP_FOOTER -- } -- while (--num != 0); --} -- --void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- SKIP_HEADER(3) -- HASH_ZIP_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- SKIP_FOOTER -- } -- while (--num != 0); --} -- --static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- UInt32 hash2Value; -- SKIP_HEADER(3) -- HASH3_CALC; -- curMatch = p->hash[kFix3HashSize + hashValue]; -- p->hash[hash2Value] = -- p->hash[kFix3HashSize + hashValue] = p->pos; -- SKIP_FOOTER -- } -- while (--num != 0); --} -- - static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) - { - do -@@ -701,61 +511,12 @@ static void Bt4_MatchFinder_Skip(CMatchF - while (--num != 0); - } - --static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- UInt32 hash2Value, hash3Value; -- SKIP_HEADER(4) -- HASH4_CALC; -- curMatch = p->hash[kFix4HashSize + hashValue]; -- p->hash[ hash2Value] = -- p->hash[kFix3HashSize + hash3Value] = -- p->hash[kFix4HashSize + hashValue] = p->pos; -- p->son[p->cyclicBufferPos] = curMatch; -- MOVE_POS -- } -- while (--num != 0); --} -- --void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) --{ -- do -- { -- SKIP_HEADER(3) -- HASH_ZIP_CALC; -- curMatch = p->hash[hashValue]; -- p->hash[hashValue] = p->pos; -- p->son[p->cyclicBufferPos] = curMatch; -- MOVE_POS -- } -- while (--num != 0); --} -- - void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) - { - vTable->Init = (Mf_Init_Func)MatchFinder_Init; - vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -- if (!p->btMode) -- { -- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; -- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; -- } -- else if (p->numHashBytes == 2) -- { -- vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; -- vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; -- } -- else if (p->numHashBytes == 3) -- { -- vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; -- vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; -- } -- else -- { -- vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -- vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -- } -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; - } ---- a/lib/lzma/LzmaDec.c -+++ b/lib/lzma/LzmaDec.c -@@ -682,7 +682,7 @@ static void LzmaDec_InitRc(CLzmaDec *p, - p->needFlush = 0; - } - --void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) - { - p->needFlush = 1; - p->remainLen = 0; -@@ -698,7 +698,7 @@ void LzmaDec_InitDicAndState(CLzmaDec *p - p->needInitState = 1; - } - --void LzmaDec_Init(CLzmaDec *p) -+static void LzmaDec_Init(CLzmaDec *p) - { - p->dicPos = 0; - LzmaDec_InitDicAndState(p, True, True); -@@ -716,7 +716,7 @@ static void LzmaDec_InitStateReal(CLzmaD - p->needInitState = 0; - } - --SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -+static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, - ELzmaFinishMode finishMode, ELzmaStatus *status) - { - SizeT inSize = *srcLen; -@@ -837,65 +837,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, Si - return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; - } - --SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) --{ -- SizeT outSize = *destLen; -- SizeT inSize = *srcLen; -- *srcLen = *destLen = 0; -- for (;;) -- { -- SizeT inSizeCur = inSize, outSizeCur, dicPos; -- ELzmaFinishMode curFinishMode; -- SRes res; -- if (p->dicPos == p->dicBufSize) -- p->dicPos = 0; -- dicPos = p->dicPos; -- if (outSize > p->dicBufSize - dicPos) -- { -- outSizeCur = p->dicBufSize; -- curFinishMode = LZMA_FINISH_ANY; -- } -- else -- { -- outSizeCur = dicPos + outSize; -- curFinishMode = finishMode; -- } -- -- res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); -- src += inSizeCur; -- inSize -= inSizeCur; -- *srcLen += inSizeCur; -- outSizeCur = p->dicPos - dicPos; -- memcpy(dest, p->dic + dicPos, outSizeCur); -- dest += outSizeCur; -- outSize -= outSizeCur; -- *destLen += outSizeCur; -- if (res != 0) -- return res; -- if (outSizeCur == 0 || outSize == 0) -- return SZ_OK; -- } --} -- --void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -+static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) - { - alloc->Free(alloc, p->probs); - p->probs = 0; - } - --static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) --{ -- alloc->Free(alloc, p->dic); -- p->dic = 0; --} -- --void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) --{ -- LzmaDec_FreeProbs(p, alloc); -- LzmaDec_FreeDict(p, alloc); --} -- --SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -+static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) - { - UInt32 dicSize; - Byte d; -@@ -935,7 +883,7 @@ static SRes LzmaDec_AllocateProbs2(CLzma - return SZ_OK; - } - --SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) - { - CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -@@ -943,28 +891,6 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, - p->prop = propNew; - return SZ_OK; - } -- --SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) --{ -- CLzmaProps propNew; -- SizeT dicBufSize; -- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -- dicBufSize = propNew.dicSize; -- if (p->dic == 0 || dicBufSize != p->dicBufSize) -- { -- LzmaDec_FreeDict(p, alloc); -- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); -- if (p->dic == 0) -- { -- LzmaDec_FreeProbs(p, alloc); -- return SZ_ERROR_MEM; -- } -- } -- p->dicBufSize = dicBufSize; -- p->prop = propNew; -- return SZ_OK; --} - - SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, ---- a/lib/lzma/LzmaEnc.c -+++ b/lib/lzma/LzmaEnc.c -@@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) - p->writeEndMark = 0; - } - --void LzmaEncProps_Normalize(CLzmaEncProps *p) -+static void LzmaEncProps_Normalize(CLzmaEncProps *p) - { - int level = p->level; - if (level < 0) level = 5; -@@ -76,7 +76,7 @@ void LzmaEncProps_Normalize(CLzmaEncProp - #endif - } - --UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -+static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) - { - CLzmaEncProps props = *props2; - LzmaEncProps_Normalize(&props); -@@ -93,7 +93,7 @@ UInt32 LzmaEncProps_GetDictSize(const CL - - #define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } - --UInt32 GetPosSlot1(UInt32 pos) -+static UInt32 GetPosSlot1(UInt32 pos) - { - UInt32 res; - BSR2_RET(pos, res); -@@ -107,7 +107,7 @@ UInt32 GetPosSlot1(UInt32 pos) - #define kNumLogBits (9 + (int)sizeof(size_t) / 2) - #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) - --void LzmaEnc_FastPosInit(Byte *g_FastPos) -+static void LzmaEnc_FastPosInit(Byte *g_FastPos) - { - int c = 2, slotFast; - g_FastPos[0] = 0; -@@ -339,58 +339,6 @@ typedef struct - CSaveState saveState; - } CLzmaEnc; - --void LzmaEnc_SaveState(CLzmaEncHandle pp) --{ -- CLzmaEnc *p = (CLzmaEnc *)pp; -- CSaveState *dest = &p->saveState; -- int i; -- dest->lenEnc = p->lenEnc; -- dest->repLenEnc = p->repLenEnc; -- dest->state = p->state; -- -- for (i = 0; i < kNumStates; i++) -- { -- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -- } -- for (i = 0; i < kNumLenToPosStates; i++) -- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -- memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -- memcpy(dest->reps, p->reps, sizeof(p->reps)); -- memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); --} -- --void LzmaEnc_RestoreState(CLzmaEncHandle pp) --{ -- CLzmaEnc *dest = (CLzmaEnc *)pp; -- const CSaveState *p = &dest->saveState; -- int i; -- dest->lenEnc = p->lenEnc; -- dest->repLenEnc = p->repLenEnc; -- dest->state = p->state; -- -- for (i = 0; i < kNumStates; i++) -- { -- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -- } -- for (i = 0; i < kNumLenToPosStates; i++) -- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -- memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -- memcpy(dest->reps, p->reps, sizeof(p->reps)); -- memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); --} -- - SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) - { - CLzmaEnc *p = (CLzmaEnc *)pp; -@@ -600,7 +548,7 @@ static void LitEnc_EncodeMatched(CRangeE - while (symbol < 0x10000); - } - --void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) - { - UInt32 i; - for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -@@ -1676,7 +1624,7 @@ static void FillDistancesPrices(CLzmaEnc - p->matchPriceCount = 0; - } - --void LzmaEnc_Construct(CLzmaEnc *p) -+static void LzmaEnc_Construct(CLzmaEnc *p) - { - RangeEnc_Construct(&p->rc); - MatchFinder_Construct(&p->matchFinderBase); -@@ -1709,7 +1657,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc * - return p; - } - --void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) - { - alloc->Free(alloc, p->litProbs); - alloc->Free(alloc, p->saveState.litProbs); -@@ -1717,7 +1665,7 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAl - p->saveState.litProbs = 0; - } - --void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -+static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) - { - #ifndef _7ZIP_ST - MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -@@ -1947,7 +1895,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, U - return SZ_OK; - } - --void LzmaEnc_Init(CLzmaEnc *p) -+static void LzmaEnc_Init(CLzmaEnc *p) - { - UInt32 i; - p->state = 0; -@@ -2005,7 +1953,7 @@ void LzmaEnc_Init(CLzmaEnc *p) - p->lpMask = (1 << p->lp) - 1; - } - --void LzmaEnc_InitPrices(CLzmaEnc *p) -+static void LzmaEnc_InitPrices(CLzmaEnc *p) - { - if (!p->fastMode) - { -@@ -2037,26 +1985,6 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEn - return SZ_OK; - } - --static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, -- ISzAlloc *alloc, ISzAlloc *allocBig) --{ -- CLzmaEnc *p = (CLzmaEnc *)pp; -- p->matchFinderBase.stream = inStream; -- p->needInit = 1; -- p->rc.outStream = outStream; -- return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); --} -- --SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, -- ISeqInStream *inStream, UInt32 keepWindowSize, -- ISzAlloc *alloc, ISzAlloc *allocBig) --{ -- CLzmaEnc *p = (CLzmaEnc *)pp; -- p->matchFinderBase.stream = inStream; -- p->needInit = 1; -- return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); --} -- - static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) - { - p->matchFinderBase.directInput = 1; -@@ -2064,7 +1992,7 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc - p->matchFinderBase.directInputRem = srcLen; - } - --SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -+static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) - { - CLzmaEnc *p = (CLzmaEnc *)pp; -@@ -2074,7 +2002,7 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle p - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); - } - --void LzmaEnc_Finish(CLzmaEncHandle pp) -+static void LzmaEnc_Finish(CLzmaEncHandle pp) - { - #ifndef _7ZIP_ST - CLzmaEnc *p = (CLzmaEnc *)pp; -@@ -2107,53 +2035,6 @@ static size_t MyWrite(void *pp, const vo - return size; - } - -- --UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) --{ -- const CLzmaEnc *p = (CLzmaEnc *)pp; -- return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); --} -- --const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) --{ -- const CLzmaEnc *p = (CLzmaEnc *)pp; -- return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; --} -- --SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, -- Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) --{ -- CLzmaEnc *p = (CLzmaEnc *)pp; -- UInt64 nowPos64; -- SRes res; -- CSeqOutStreamBuf outStream; -- -- outStream.funcTable.Write = MyWrite; -- outStream.data = dest; -- outStream.rem = *destLen; -- outStream.overflow = False; -- -- p->writeEndMark = False; -- p->finished = False; -- p->result = SZ_OK; -- -- if (reInit) -- LzmaEnc_Init(p); -- LzmaEnc_InitPrices(p); -- nowPos64 = p->nowPos64; -- RangeEnc_Init(&p->rc); -- p->rc.outStream = &outStream.funcTable; -- -- res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); -- -- *unpackSize = (UInt32)(p->nowPos64 - nowPos64); -- *destLen -= outStream.rem; -- if (outStream.overflow) -- return SZ_ERROR_OUTPUT_EOF; -- -- return res; --} -- - static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) - { - SRes res = SZ_OK; -@@ -2184,13 +2065,6 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, - return res; - } - --SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, -- ISzAlloc *alloc, ISzAlloc *allocBig) --{ -- RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); -- return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); --} -- - SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) - { - CLzmaEnc *p = (CLzmaEnc *)pp; -@@ -2247,25 +2121,3 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp - return SZ_ERROR_OUTPUT_EOF; - return res; - } -- --SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) --{ -- CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); -- SRes res; -- if (p == 0) -- return SZ_ERROR_MEM; -- -- res = LzmaEnc_SetProps(p, props); -- if (res == SZ_OK) -- { -- res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); -- if (res == SZ_OK) -- res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, -- writeEndMark, progress, alloc, allocBig); -- } -- -- LzmaEnc_Destroy(p, alloc, allocBig); -- return res; --} diff --git a/target/linux/generic/hack-6.0/640-bridge-only-accept-EAP-locally.patch b/target/linux/generic/hack-6.0/640-bridge-only-accept-EAP-locally.patch deleted file mode 100644 index 2356c58a5..000000000 --- a/target/linux/generic/hack-6.0/640-bridge-only-accept-EAP-locally.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:18:54 +0200 -Subject: bridge: only accept EAP locally - -When bridging, do not forward EAP frames to other ports, only deliver -them locally, regardless of the state. - -Signed-off-by: Felix Fietkau -[add disable_eap_hack sysfs attribute] -Signed-off-by: Etienne Champetier ---- - ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -133,10 +133,14 @@ int br_handle_frame_finish(struct net *n - } - } - -+ BR_INPUT_SKB_CB(skb)->brdev = br->dev; -+ -+ if (skb->protocol == htons(ETH_P_PAE) && !br->disable_eap_hack) -+ return br_pass_frame_up(skb); -+ - if (state == BR_STATE_LEARNING) - goto drop; - -- BR_INPUT_SKB_CB(skb)->brdev = br->dev; - BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED); - - if (IS_ENABLED(CONFIG_INET) && ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -482,6 +482,8 @@ struct net_bridge { - u16 group_fwd_mask; - u16 group_fwd_mask_required; - -+ bool disable_eap_hack; -+ - /* STP */ - bridge_id designated_root; - bridge_id bridge_id; diff --git a/target/linux/generic/hack-6.0/661-use_fq_codel_by_default.patch b/target/linux/generic/hack-6.0/661-use_fq_codel_by_default.patch deleted file mode 100644 index 5dfc7f462..000000000 --- a/target/linux/generic/hack-6.0/661-use_fq_codel_by_default.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 1d418f7e88035ed7a94073f6354246c66e9193e9 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:22:58 +0200 -Subject: fq_codel: switch default qdisc from pfifo_fast to fq_codel and remove pfifo_fast - -Signed-off-by: Felix Fietkau ---- - include/net/sch_generic.h | 3 ++- - net/sched/Kconfig | 3 ++- - net/sched/sch_api.c | 2 +- - net/sched/sch_fq_codel.c | 3 ++- - net/sched/sch_generic.c | 4 ++-- - 5 files changed, 9 insertions(+), 6 deletions(-) - ---- a/include/net/sch_generic.h -+++ b/include/net/sch_generic.h -@@ -585,12 +585,13 @@ extern struct Qdisc_ops noop_qdisc_ops; - extern struct Qdisc_ops pfifo_fast_ops; - extern struct Qdisc_ops mq_qdisc_ops; - extern struct Qdisc_ops noqueue_qdisc_ops; -+extern struct Qdisc_ops fq_codel_qdisc_ops; - extern const struct Qdisc_ops *default_qdisc_ops; - static inline const struct Qdisc_ops * - get_default_qdisc_ops(const struct net_device *dev, int ntx) - { - return ntx < dev->real_num_tx_queues ? -- default_qdisc_ops : &pfifo_fast_ops; -+ default_qdisc_ops : &fq_codel_qdisc_ops; - } - - struct Qdisc_class_common { ---- a/net/sched/Kconfig -+++ b/net/sched/Kconfig -@@ -4,8 +4,9 @@ - # - - menuconfig NET_SCHED -- bool "QoS and/or fair queueing" -+ def_bool y - select NET_SCH_FIFO -+ select NET_SCH_FQ_CODEL - help - When the kernel has several packets to send out over a network - device, it has to decide which ones to send first, which ones to ---- a/net/sched/sch_api.c -+++ b/net/sched/sch_api.c -@@ -2277,7 +2277,7 @@ static int __init pktsched_init(void) - return err; - } - -- register_qdisc(&pfifo_fast_ops); -+ register_qdisc(&fq_codel_qdisc_ops); - register_qdisc(&pfifo_qdisc_ops); - register_qdisc(&bfifo_qdisc_ops); - register_qdisc(&pfifo_head_drop_qdisc_ops); ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -719,7 +719,7 @@ static const struct Qdisc_class_ops fq_c - .walk = fq_codel_walk, - }; - --static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { -+struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { - .cl_ops = &fq_codel_class_ops, - .id = "fq_codel", - .priv_size = sizeof(struct fq_codel_sched_data), -@@ -734,6 +734,7 @@ static struct Qdisc_ops fq_codel_qdisc_o - .dump_stats = fq_codel_dump_stats, - .owner = THIS_MODULE, - }; -+EXPORT_SYMBOL(fq_codel_qdisc_ops); - - static int __init fq_codel_module_init(void) - { ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -32,7 +32,7 @@ - #include - - /* Qdisc to use by default */ --const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; -+const struct Qdisc_ops *default_qdisc_ops = &fq_codel_qdisc_ops; - EXPORT_SYMBOL(default_qdisc_ops); - - static void qdisc_maybe_clear_missed(struct Qdisc *q, -@@ -1142,12 +1142,12 @@ static void attach_one_default_qdisc(str - void *_unused) - { - struct Qdisc *qdisc; -- const struct Qdisc_ops *ops = default_qdisc_ops; -+ const struct Qdisc_ops *ops = &fq_codel_qdisc_ops; - - if (dev->priv_flags & IFF_NO_QUEUE) - ops = &noqueue_qdisc_ops; - else if(dev->type == ARPHRD_CAN) -- ops = &pfifo_fast_ops; -+ ops = &fq_codel_qdisc_ops; - - qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL); - if (!qdisc) diff --git a/target/linux/generic/hack-6.0/920-device_tree_cmdline.patch b/target/linux/generic/hack-6.0/920-device_tree_cmdline.patch deleted file mode 100644 index a3a76f66a..000000000 --- a/target/linux/generic/hack-6.0/920-device_tree_cmdline.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -1179,6 +1179,9 @@ int __init early_init_dt_scan_chosen(cha - p = of_get_flat_dt_prop(node, "bootargs", &l); - if (p != NULL && l > 0) - strlcpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); -+ p = of_get_flat_dt_prop(node, "bootargs-append", &l); -+ if (p != NULL && l > 0) -+ strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE)); - - /* - * CONFIG_CMDLINE is meant to be a default in case nothing else diff --git a/target/linux/generic/hack-6.0/204-module_strip.patch b/target/linux/generic/hack-6.1/204-module_strip.patch similarity index 76% rename from target/linux/generic/hack-6.0/204-module_strip.patch rename to target/linux/generic/hack-6.1/204-module_strip.patch index fd5298bf4..f0949d32f 100644 --- a/target/linux/generic/hack-6.0/204-module_strip.patch +++ b/target/linux/generic/hack-6.1/204-module_strip.patch @@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau --- a/include/linux/module.h +++ b/include/linux/module.h -@@ -164,6 +164,7 @@ extern void cleanup_module(void); +@@ -163,6 +163,7 @@ extern void cleanup_module(void); /* Generic info of form tag = "info" */ #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau /* For userspace: you can also call me... */ #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) -@@ -233,12 +234,12 @@ extern void cleanup_module(void); +@@ -232,12 +233,12 @@ extern void cleanup_module(void); * Author(s), use "Name " or just "Name", for multiple * authors use multiple MODULE_AUTHOR() statements/lines. */ @@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ extern typeof(name) __mod_##type##__##name##_device_table \ -@@ -265,7 +266,9 @@ extern typeof(name) __mod_##type##__##na +@@ -264,7 +265,9 @@ extern typeof(name) __mod_##type##__##na */ #if defined(MODULE) || !defined(CONFIG_SYSFS) @@ -49,7 +49,7 @@ Signed-off-by: Felix Fietkau #else #define MODULE_VERSION(_version) \ MODULE_INFO(version, _version); \ -@@ -288,7 +291,7 @@ extern typeof(name) __mod_##type##__##na +@@ -287,7 +290,7 @@ extern typeof(name) __mod_##type##__##na /* Optional firmware file (or files) needed by the module * format is simply firmware file name. Multiple firmware * files require multiple MODULE_FIRMWARE() specifiers */ @@ -88,9 +88,9 @@ Signed-off-by: Felix Fietkau --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig -@@ -286,6 +286,13 @@ config UNUSED_KSYMS_WHITELIST - one per line. The path can be absolute, or relative to the kernel - source tree. +@@ -290,4 +290,11 @@ config MODULES_TREE_LOOKUP + def_bool y + depends on PERF_EVENTS || TRACING || CFI_CLANG +config MODULE_STRIPPED + bool "Reduce module size" @@ -99,12 +99,26 @@ Signed-off-by: Felix Fietkau + Remove module parameter descriptions, author info, version, aliases, + device tables, etc. + - config MODULES_TREE_LOOKUP - def_bool y - depends on PERF_EVENTS || TRACING || CFI_CLANG + endif # MODULES --- a/kernel/module/main.c +++ b/kernel/module/main.c -@@ -1954,9 +1954,11 @@ static int setup_load_info(struct load_i +@@ -988,6 +988,7 @@ size_t modinfo_attrs_count = ARRAY_SIZE( + + static const char vermagic[] = VERMAGIC_STRING; + ++#if defined(CONFIG_MODVERSIONS) || !defined(CONFIG_MODULE_STRIPPED) + int try_to_force_load(struct module *mod, const char *reason) + { + #ifdef CONFIG_MODULE_FORCE_LOAD +@@ -999,6 +1000,7 @@ int try_to_force_load(struct module *mod + return -ENOEXEC; + #endif + } ++#endif + + static char *get_modinfo(const struct load_info *info, const char *tag); + static char *get_next_modinfo(const struct load_info *info, const char *tag, +@@ -1950,9 +1952,11 @@ static int setup_load_info(struct load_i static int check_modinfo(struct module *mod, struct load_info *info, int flags) { @@ -117,7 +131,7 @@ Signed-off-by: Felix Fietkau if (flags & MODULE_INIT_IGNORE_VERMAGIC) modmagic = NULL; -@@ -1977,6 +1979,7 @@ static int check_modinfo(struct module * +@@ -1973,6 +1977,7 @@ static int check_modinfo(struct module * mod->name); add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); } @@ -148,7 +162,29 @@ Signed-off-by: Felix Fietkau buf_printf(b, "\n"); buf_printf(b, "__visible struct module __this_module\n"); buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n"); -@@ -2101,11 +2105,13 @@ static void add_depends(struct buffer *b +@@ -1995,8 +1999,10 @@ static void add_header(struct buffer *b, + buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n"); + buf_printf(b, "};\n"); + ++#ifndef CONFIG_MODULE_STRIPPED + if (!external_module) + buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); ++#endif + + buf_printf(b, + "\n" +@@ -2004,8 +2010,10 @@ static void add_header(struct buffer *b, + "MODULE_INFO(retpoline, \"Y\");\n" + "#endif\n"); + ++#ifndef CONFIG_MODULE_STRIPPED + if (strstarts(mod->name, "drivers/staging")) + buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); ++#endif + + if (strstarts(mod->name, "tools/testing")) + buf_printf(b, "\nMODULE_INFO(test, \"Y\");\n"); +@@ -2101,11 +2109,13 @@ static void add_depends(struct buffer *b static void add_srcversion(struct buffer *b, struct module *mod) { @@ -162,7 +198,7 @@ Signed-off-by: Felix Fietkau } static void write_buf(struct buffer *b, const char *fname) -@@ -2191,7 +2197,9 @@ static void write_mod_c_file(struct modu +@@ -2191,7 +2201,9 @@ static void write_mod_c_file(struct modu add_exported_symbols(&buf, mod); add_versions(&buf, mod); add_depends(&buf, mod); diff --git a/target/linux/generic/hack-6.0/205-kconfig-exit.patch b/target/linux/generic/hack-6.1/205-kconfig-exit.patch similarity index 50% rename from target/linux/generic/hack-6.0/205-kconfig-exit.patch rename to target/linux/generic/hack-6.1/205-kconfig-exit.patch index f1b50283d..2c6989578 100644 --- a/target/linux/generic/hack-6.0/205-kconfig-exit.patch +++ b/target/linux/generic/hack-6.1/205-kconfig-exit.patch @@ -1,3 +1,12 @@ +From 300d26562ce4dc427154cb247beb75db4b1f0774 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:29:57 +0200 +Subject: [PATCH] scripts/Kconfig: Kconfig exit + +--- + scripts/kconfig/conf.c | 2 ++ + 1 file changed, 2 insertions(+) + --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -432,6 +432,8 @@ static int conf_sym(struct menu *menu) diff --git a/target/linux/generic/hack-6.0/210-darwin_scripts_include.patch b/target/linux/generic/hack-6.1/210-darwin_scripts_include.patch similarity index 100% rename from target/linux/generic/hack-6.0/210-darwin_scripts_include.patch rename to target/linux/generic/hack-6.1/210-darwin_scripts_include.patch diff --git a/target/linux/generic/hack-6.0/211-darwin-uuid-typedef-clash.patch b/target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch similarity index 100% rename from target/linux/generic/hack-6.0/211-darwin-uuid-typedef-clash.patch rename to target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch diff --git a/target/linux/generic/hack-6.0/212-tools_portability.patch b/target/linux/generic/hack-6.1/212-tools_portability.patch similarity index 88% rename from target/linux/generic/hack-6.0/212-tools_portability.patch rename to target/linux/generic/hack-6.1/212-tools_portability.patch index 3e74a76f4..4b1c6c498 100644 --- a/target/linux/generic/hack-6.0/212-tools_portability.patch +++ b/target/linux/generic/hack-6.1/212-tools_portability.patch @@ -81,3 +81,13 @@ Signed-off-by: Felix Fietkau struct page; struct kmem_cache; +--- a/tools/perf/pmu-events/jevents.py ++++ b/tools/perf/pmu-events/jevents.py +@@ -684,6 +684,7 @@ def main() -> None: + #include "util/header.h" + #include "util/pmu.h" + #include ++#include + #include + + struct compact_pmu_event { diff --git a/target/linux/generic/hack-6.0/214-spidev_h_portability.patch b/target/linux/generic/hack-6.1/214-spidev_h_portability.patch similarity index 100% rename from target/linux/generic/hack-6.0/214-spidev_h_portability.patch rename to target/linux/generic/hack-6.1/214-spidev_h_portability.patch diff --git a/target/linux/generic/hack-6.0/220-arm-gc_sections.patch b/target/linux/generic/hack-6.1/220-arm-gc_sections.patch similarity index 99% rename from target/linux/generic/hack-6.0/220-arm-gc_sections.patch rename to target/linux/generic/hack-6.1/220-arm-gc_sections.patch index 6cfc3236b..483118138 100644 --- a/target/linux/generic/hack-6.0/220-arm-gc_sections.patch +++ b/target/linux/generic/hack-6.1/220-arm-gc_sections.patch @@ -12,7 +12,7 @@ Signed-off-by: Gabor Juhos --- --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -121,6 +121,7 @@ config ARM +@@ -122,6 +122,7 @@ config ARM select HAVE_UID16 select HAVE_VIRT_CPU_ACCOUNTING_GEN select IRQ_FORCED_THREADING diff --git a/target/linux/generic/hack-6.0/221-module_exports.patch b/target/linux/generic/hack-6.1/221-module_exports.patch similarity index 80% rename from target/linux/generic/hack-6.0/221-module_exports.patch rename to target/linux/generic/hack-6.1/221-module_exports.patch index f13ef0ae3..7e43945dc 100644 --- a/target/linux/generic/hack-6.0/221-module_exports.patch +++ b/target/linux/generic/hack-6.1/221-module_exports.patch @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau /* Align . to a 8 byte boundary equals to maximum function alignment. */ #define ALIGN_FUNCTION() . = ALIGN(8) -@@ -479,14 +489,14 @@ +@@ -512,14 +522,14 @@ /* Kernel symbol table: Normal symbols */ \ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ __start___ksymtab = .; \ @@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau __stop___ksymtab_gpl = .; \ } \ \ -@@ -506,7 +516,7 @@ +@@ -539,7 +549,7 @@ \ /* Kernel symbol table: strings */ \ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ @@ -56,10 +56,10 @@ Signed-off-by: Felix Fietkau } \ \ /* __*init sections */ \ -@@ -1023,6 +1033,8 @@ - +@@ -1043,6 +1053,8 @@ #define COMMON_DISCARDS \ SANITIZER_DISCARDS \ + PATCHABLE_DISCARDS \ + SYMTAB_DISCARD \ + SYMTAB_DISCARD_GPL \ *(.discard) \ @@ -89,9 +89,33 @@ Signed-off-by: Felix Fietkau "__kstrtab_" #sym ": \n" \ " .asciz \"" #sym "\" \n" \ "__kstrtabns_" #sym ": \n" \ +--- a/include/asm-generic/export.h ++++ b/include/asm-generic/export.h +@@ -31,6 +31,12 @@ + #endif + .endm + ++#ifdef MODULE ++#define __EXPORT_SUFFIX(name) ++#else ++#define __EXPORT_SUFFIX(name) + #name ++#endif ++ + /* + * note on .section use: we specify progbits since usage of the "M" (SHF_MERGE) + * section flag requires it. Use '%progbits' instead of '@progbits' since the +@@ -44,7 +50,7 @@ + __ksymtab_\name: + __put \val, __kstrtab_\name + .previous +- .section __ksymtab_strings,"aMS",%progbits,1 ++ .section __ksymtab_strings __EXPORT_SUFFIX(name),"aMS",%progbits,1 + __kstrtab_\name: + .asciz "\name" + .previous --- a/scripts/Makefile.build +++ b/scripts/Makefile.build -@@ -328,7 +328,7 @@ targets += $(real-dtb-y) $(lib-y) $(alwa +@@ -388,7 +388,7 @@ targets += $(real-dtb-y) $(lib-y) $(alwa # Linker scripts preprocessor (.lds.S -> .lds) # --------------------------------------------------------------------------- quiet_cmd_cpp_lds_S = LDS $@ diff --git a/target/linux/generic/hack-6.0/230-openwrt_lzma_options.patch b/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch similarity index 72% rename from target/linux/generic/hack-6.0/230-openwrt_lzma_options.patch rename to target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch index 1adc6b9fa..55530c5c7 100644 --- a/target/linux/generic/hack-6.0/230-openwrt_lzma_options.patch +++ b/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch @@ -23,12 +23,16 @@ Signed-off-by: Imre Kaloz { {0x02, 0x21}, "lz4", unlz4 }, --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib -@@ -421,7 +421,7 @@ quiet_cmd_bzip2_with_size = BZIP2 $@ +@@ -443,10 +443,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@ # --------------------------------------------------------------------------- quiet_cmd_lzma = LZMA $@ - cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@ -+ cmd_lzma = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@ ++ cmd_lzma = cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so > $@ quiet_cmd_lzma_with_size = LZMA $@ - cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ +- cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ ++ cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@ + + quiet_cmd_lzo = LZO $@ + cmd_lzo = cat $(real-prereqs) | $(KLZOP) -9 > $@ diff --git a/target/linux/generic/hack-6.0/250-netfilter_depends.patch b/target/linux/generic/hack-6.1/250-netfilter_depends.patch similarity index 100% rename from target/linux/generic/hack-6.0/250-netfilter_depends.patch rename to target/linux/generic/hack-6.1/250-netfilter_depends.patch diff --git a/target/linux/generic/hack-6.0/251-kconfig.patch b/target/linux/generic/hack-6.1/251-kconfig.patch similarity index 96% rename from target/linux/generic/hack-6.0/251-kconfig.patch rename to target/linux/generic/hack-6.1/251-kconfig.patch index 6027f20b2..9511c4c2b 100644 --- a/target/linux/generic/hack-6.0/251-kconfig.patch +++ b/target/linux/generic/hack-6.1/251-kconfig.patch @@ -92,7 +92,7 @@ Signed-off-by: John Crispin bool --- a/lib/Kconfig +++ b/lib/Kconfig -@@ -456,16 +456,16 @@ config BCH_CONST_T +@@ -457,16 +457,16 @@ config BCH_CONST_T # Textsearch support is select'ed if needed # config TEXTSEARCH @@ -147,7 +147,7 @@ Signed-off-by: John Crispin config CFG80211 tristate "cfg80211 - wireless configuration API" -@@ -204,7 +204,7 @@ config CFG80211_WEXT_EXPORT +@@ -208,7 +208,7 @@ config CFG80211_WEXT_EXPORT endif # CFG80211 config LIB80211 @@ -156,7 +156,7 @@ Signed-off-by: John Crispin default n help This options enables a library of common routines used -@@ -213,17 +213,17 @@ config LIB80211 +@@ -217,17 +217,17 @@ config LIB80211 Drivers should select this themselves if needed. config LIB80211_CRYPT_WEP diff --git a/target/linux/generic/hack-6.1/253-ksmbd-config.patch b/target/linux/generic/hack-6.1/253-ksmbd-config.patch new file mode 100644 index 000000000..b0c379657 --- /dev/null +++ b/target/linux/generic/hack-6.1/253-ksmbd-config.patch @@ -0,0 +1,32 @@ +From dcd966fa7ca63f38cf7147e1184d13d66e2ca340 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:33:30 +0200 +Subject: [PATCH] Kconfig: add tristate for OID and ASNI string + +--- + init/Kconfig | 2 +- + lib/Kconfig | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -2003,7 +2003,7 @@ config PADATA + bool + + config ASN1 +- tristate ++ tristate "ASN1" + help + Build a simple ASN.1 grammar compiler that produces a bytecode output + that can be interpreted by the ASN.1 stream decoder and used to +--- a/lib/Kconfig ++++ b/lib/Kconfig +@@ -637,7 +637,7 @@ config LIBFDT + bool + + config OID_REGISTRY +- tristate ++ tristate "OID" + help + Enable fast lookup object identifier registry. + diff --git a/target/linux/generic/hack-6.0/259-regmap_dynamic.patch b/target/linux/generic/hack-6.1/259-regmap_dynamic.patch similarity index 98% rename from target/linux/generic/hack-6.0/259-regmap_dynamic.patch rename to target/linux/generic/hack-6.1/259-regmap_dynamic.patch index 6339784cb..e85fac537 100644 --- a/target/linux/generic/hack-6.0/259-regmap_dynamic.patch +++ b/target/linux/generic/hack-6.1/259-regmap_dynamic.patch @@ -125,7 +125,7 @@ Signed-off-by: Felix Fietkau #include #include #include -@@ -3384,3 +3385,5 @@ static int __init regmap_initcall(void) +@@ -3505,3 +3506,5 @@ static int __init regmap_initcall(void) return 0; } postcore_initcall(regmap_initcall); diff --git a/target/linux/generic/hack-6.0/260-crypto_test_dependencies.patch b/target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch similarity index 100% rename from target/linux/generic/hack-6.0/260-crypto_test_dependencies.patch rename to target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch diff --git a/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch b/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch new file mode 100644 index 000000000..01829b2d5 --- /dev/null +++ b/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch @@ -0,0 +1,24 @@ +From 241e5d3f7b0dd3c01f8c7fa83cbc9a3882286d53 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:35:18 +0200 +Subject: [PATCH] lib/crypto: add tristate string for ARC4 + +This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We +need this to be able to compile this into the kernel and make use of it +from backports. + +--- + lib/crypto/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/crypto/Kconfig ++++ b/lib/crypto/Kconfig +@@ -9,7 +9,7 @@ config CRYPTO_LIB_AES + tristate + + config CRYPTO_LIB_ARC4 +- tristate ++ tristate "ARC4 cipher library" + + config CRYPTO_ARCH_HAVE_LIB_BLAKE2S + bool diff --git a/target/linux/generic/hack-6.0/280-rfkill-stubs.patch b/target/linux/generic/hack-6.1/280-rfkill-stubs.patch similarity index 97% rename from target/linux/generic/hack-6.0/280-rfkill-stubs.patch rename to target/linux/generic/hack-6.1/280-rfkill-stubs.patch index 7a650d132..ff6638f7a 100644 --- a/target/linux/generic/hack-6.0/280-rfkill-stubs.patch +++ b/target/linux/generic/hack-6.1/280-rfkill-stubs.patch @@ -26,7 +26,7 @@ Signed-off-by: John Crispin * @name: name of the struct -- the string is not copied internally --- a/net/Makefile +++ b/net/Makefile -@@ -52,7 +52,7 @@ obj-$(CONFIG_TIPC) += tipc/ +@@ -51,7 +51,7 @@ obj-$(CONFIG_TIPC) += tipc/ obj-$(CONFIG_NETLABEL) += netlabel/ obj-$(CONFIG_IUCV) += iucv/ obj-$(CONFIG_SMC) += smc/ diff --git a/target/linux/generic/hack-6.0/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch b/target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch similarity index 100% rename from target/linux/generic/hack-6.0/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch rename to target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch diff --git a/target/linux/generic/hack-6.0/321-powerpc_crtsavres_prereq.patch b/target/linux/generic/hack-6.1/321-powerpc_crtsavres_prereq.patch similarity index 100% rename from target/linux/generic/hack-6.0/321-powerpc_crtsavres_prereq.patch rename to target/linux/generic/hack-6.1/321-powerpc_crtsavres_prereq.patch diff --git a/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch b/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch new file mode 100644 index 000000000..11f028c62 --- /dev/null +++ b/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch @@ -0,0 +1,112 @@ +From 0bccc3722bdd88e8ae995e77ef9f7b77ee4cbdee Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 7 Apr 2021 22:45:54 +0100 +Subject: [PATCH 2/2] mtd: blktrans: call add disks after mtd device +To: linux-mtd@lists.infradead.org +Cc: Vignesh Raghavendra , + Richard Weinberger , + Miquel Raynal , + David Woodhouse + +Calling device_add_disk while holding mtd_table_mutex leads +to deadlock in case part_bits!=0 as block partition parsers +will try to open the newly created disks, trying to acquire +mutex once again. +Move device_add_disk to additional function called after +add partitions of an MTD device have been added and locks +have been released. + +Signed-off-by: Daniel Golle +--- + drivers/mtd/mtd_blkdevs.c | 33 ++++++++++++++++++++++++++------- + drivers/mtd/mtdcore.c | 3 +++ + include/linux/mtd/blktrans.h | 1 + + 3 files changed, 30 insertions(+), 7 deletions(-) + +--- a/drivers/mtd/mtd_blkdevs.c ++++ b/drivers/mtd/mtd_blkdevs.c +@@ -386,19 +386,8 @@ int add_mtd_blktrans_dev(struct mtd_blkt + if (new->readonly) + set_disk_ro(gd, 1); + +- ret = device_add_disk(&new->mtd->dev, gd, NULL); +- if (ret) +- goto out_cleanup_disk; +- +- if (new->disk_attributes) { +- ret = sysfs_create_group(&disk_to_dev(gd)->kobj, +- new->disk_attributes); +- WARN_ON(ret); +- } + return 0; + +-out_cleanup_disk: +- put_disk(new->disk); + out_free_tag_set: + blk_mq_free_tag_set(new->tag_set); + out_kfree_tag_set: +@@ -408,6 +397,35 @@ out_list_del: + return ret; + } + ++void register_mtd_blktrans_devs(void) ++{ ++ struct mtd_blktrans_ops *tr; ++ struct mtd_blktrans_dev *dev, *next; ++ int ret; ++ ++ list_for_each_entry(tr, &blktrans_majors, list) { ++ list_for_each_entry_safe(dev, next, &tr->devs, list) { ++ if (disk_live(dev->disk)) ++ continue; ++ ++ ret = device_add_disk(&dev->mtd->dev, dev->disk, NULL); ++ if (ret) ++ goto out_cleanup_disk; ++ ++ if (dev->disk_attributes) { ++ ret = sysfs_create_group(&disk_to_dev(dev->disk)->kobj, ++ dev->disk_attributes); ++ WARN_ON(ret); ++ } ++ } ++ } ++ ++ return; ++ ++out_cleanup_disk: ++ put_disk(dev->disk); ++} ++ + int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) + { + unsigned long flags; +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -31,6 +31,7 @@ + + #include + #include ++#include + + #include "mtdcore.h" + +@@ -1057,6 +1058,8 @@ int mtd_device_parse_register(struct mtd + + ret = mtd_otp_nvmem_add(mtd); + ++ register_mtd_blktrans_devs(); ++ + out: + if (ret && device_is_registered(&mtd->dev)) + del_mtd_device(mtd); +--- a/include/linux/mtd/blktrans.h ++++ b/include/linux/mtd/blktrans.h +@@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struc + extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); + extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); + extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev); ++extern void register_mtd_blktrans_devs(void); + + /** + * module_mtd_blktrans() - Helper macro for registering a mtd blktrans driver diff --git a/target/linux/generic/hack-6.0/410-block-fit-partition-parser.patch b/target/linux/generic/hack-6.1/410-block-fit-partition-parser.patch similarity index 87% rename from target/linux/generic/hack-6.0/410-block-fit-partition-parser.patch rename to target/linux/generic/hack-6.1/410-block-fit-partition-parser.patch index 38856ded7..0384dad85 100644 --- a/target/linux/generic/hack-6.0/410-block-fit-partition-parser.patch +++ b/target/linux/generic/hack-6.1/410-block-fit-partition-parser.patch @@ -1,6 +1,25 @@ +From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:37:33 +0200 +Subject: [PATCH] kernel: add block fit partition parser + +--- + block/blk.h | 2 ++ + block/partitions/Kconfig | 7 +++++++ + block/partitions/Makefile | 1 + + block/partitions/check.h | 3 +++ + block/partitions/core.c | 17 +++++++++++++++++ + block/partitions/efi.c | 8 ++++++++ + block/partitions/efi.h | 3 +++ + block/partitions/msdos.c | 10 ++++++++++ + drivers/mtd/mtd_blkdevs.c | 2 ++ + drivers/mtd/ubi/block.c | 3 +++ + include/linux/msdos_partition.h | 1 + + 11 files changed, 57 insertions(+) + --- a/block/blk.h +++ b/block/blk.h -@@ -406,6 +406,8 @@ void blk_free_ext_minor(unsigned int min +@@ -414,6 +414,8 @@ void blk_free_ext_minor(unsigned int min #define ADDPART_FLAG_NONE 0 #define ADDPART_FLAG_RAID 1 #define ADDPART_FLAG_WHOLEDISK 2 @@ -98,30 +117,6 @@ return true; } ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -433,6 +433,9 @@ int ubiblock_create(struct ubi_volume_in - } - gd->flags |= GENHD_FL_NO_PART; - gd->private_data = dev; -+#ifdef CONFIG_FIT_PARTITION -+ gd->flags |= GENHD_FL_EXT_DEVT; -+#endif - sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); - set_capacity(gd, disk_capacity); - dev->gd = gd; ---- a/drivers/mtd/mtd_blkdevs.c -+++ b/drivers/mtd/mtd_blkdevs.c -@@ -346,6 +346,9 @@ int add_mtd_blktrans_dev(struct mtd_blkt - gd->first_minor = (new->devnum) << tr->part_bits; - gd->minors = 1 << tr->part_bits; - gd->fops = &mtd_block_ops; -+#ifdef CONFIG_FIT_PARTITION -+ gd->flags |= GENHD_FL_EXT_DEVT; -+#endif - - if (tr->part_bits) { - if (new->devnum < 26) --- a/block/partitions/efi.c +++ b/block/partitions/efi.c @@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio diff --git a/target/linux/generic/hack-6.0/420-mtd-set-rootfs-to-be-root-dev.patch b/target/linux/generic/hack-6.1/420-mtd-set-rootfs-to-be-root-dev.patch similarity index 94% rename from target/linux/generic/hack-6.0/420-mtd-set-rootfs-to-be-root-dev.patch rename to target/linux/generic/hack-6.1/420-mtd-set-rootfs-to-be-root-dev.patch index b1b2021e8..bb3a293c6 100644 --- a/target/linux/generic/hack-6.0/420-mtd-set-rootfs-to-be-root-dev.patch +++ b/target/linux/generic/hack-6.1/420-mtd-set-rootfs-to-be-root-dev.patch @@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos #include #include -@@ -748,6 +749,16 @@ int add_mtd_device(struct mtd_info *mtd) +@@ -751,6 +752,16 @@ int add_mtd_device(struct mtd_info *mtd) of this try_ nonsense, and no bitching about it either. :) */ __module_get(THIS_MODULE); diff --git a/target/linux/generic/hack-6.0/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch b/target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch similarity index 100% rename from target/linux/generic/hack-6.0/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch rename to target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch diff --git a/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch b/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch new file mode 100644 index 000000000..1e69ee644 --- /dev/null +++ b/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch @@ -0,0 +1,33 @@ +From ac84397efb3b3868c71c10ad7521161773228a17 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:41:44 +0200 +Subject: [PATCH] mtd/nand: add MediaTek NAND bad block managment table + +--- + drivers/mtd/nand/Kconfig | 4 ++++ + drivers/mtd/nand/Makefile | 1 + + 2 files changed, 5 insertions(+) + +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -46,6 +46,10 @@ config MTD_NAND_ECC_SW_BCH + ECC codes. They are used with NAND devices requiring more than 1 bit + of error correction. + ++config MTD_NAND_MTK_BMT ++ bool "Support MediaTek NAND Bad-block Management Table" ++ default n ++ + config MTD_NAND_ECC_MXIC + bool "Macronix external hardware ECC engine" + depends on HAS_IOMEM +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -3,6 +3,7 @@ + nandcore-objs := core.o bbt.o + obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o + obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o ++obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o + + obj-y += onenand/ + obj-y += raw/ diff --git a/target/linux/generic/hack-6.1/600-bridge_offload.patch b/target/linux/generic/hack-6.1/600-bridge_offload.patch new file mode 100644 index 000000000..aa78c96e7 --- /dev/null +++ b/target/linux/generic/hack-6.1/600-bridge_offload.patch @@ -0,0 +1,846 @@ +From 11c3fae5afa6cac444d12622e2cf5af60a99c1ef Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:43:15 +0200 +Subject: [PATCH] net/bridge: add bridge offload + +--- + include/linux/if_bridge.h | 1 + + net/bridge/Makefile | 2 +- + net/bridge/br.c | 8 + + net/bridge/br_device.c | 2 + + net/bridge/br_fdb.c | 5 + + net/bridge/br_forward.c | 3 + + net/bridge/br_if.c | 6 +- + net/bridge/br_input.c | 5 + + net/bridge/br_offload.c | 438 ++++++++++++++++++++++++++++++++ + net/bridge/br_private.h | 22 +- + net/bridge/br_private_offload.h | 23 ++ + net/bridge/br_stp.c | 3 + + net/bridge/br_sysfs_br.c | 35 +++ + net/bridge/br_sysfs_if.c | 2 + + net/bridge/br_vlan_tunnel.c | 3 + + 15 files changed, 555 insertions(+), 3 deletions(-) + create mode 100644 net/bridge/br_offload.c + create mode 100644 net/bridge/br_private_offload.h + +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -60,6 +60,7 @@ struct br_ip_list { + #define BR_TX_FWD_OFFLOAD BIT(20) + #define BR_PORT_LOCKED BIT(21) + #define BR_BPDU_FILTER BIT(22) ++#define BR_OFFLOAD BIT(23) + + #define BR_DEFAULT_AGEING_TIME (300 * HZ) + +--- a/net/bridge/Makefile ++++ b/net/bridge/Makefile +@@ -5,7 +5,7 @@ + + obj-$(CONFIG_BRIDGE) += bridge.o + +-bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ ++bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o br_offload.o \ + br_ioctl.o br_stp.o br_stp_bpdu.o \ + br_stp_if.o br_stp_timer.o br_netlink.o \ + br_netlink_tunnel.o br_arp_nd_proxy.o +--- a/net/bridge/br.c ++++ b/net/bridge/br.c +@@ -18,6 +18,7 @@ + #include + + #include "br_private.h" ++#include "br_private_offload.h" + + /* + * Handle changes in state of network devices enslaved to a bridge. +@@ -389,6 +390,10 @@ static int __init br_init(void) + if (err) + goto err_out; + ++ err = br_offload_init(); ++ if (err) ++ goto err_out0; ++ + err = register_pernet_subsys(&br_net_ops); + if (err) + goto err_out1; +@@ -438,6 +443,8 @@ err_out3: + err_out2: + unregister_pernet_subsys(&br_net_ops); + err_out1: ++ br_offload_fini(); ++err_out0: + br_fdb_fini(); + err_out: + stp_proto_unregister(&br_stp_proto); +@@ -460,6 +467,7 @@ static void __exit br_deinit(void) + #if IS_ENABLED(CONFIG_ATM_LANE) + br_fdb_test_addr_hook = NULL; + #endif ++ br_offload_fini(); + br_fdb_fini(); + } + +--- a/net/bridge/br_device.c ++++ b/net/bridge/br_device.c +@@ -525,6 +525,8 @@ void br_dev_setup(struct net_device *dev + br->bridge_hello_time = br->hello_time = 2 * HZ; + br->bridge_forward_delay = br->forward_delay = 15 * HZ; + br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME; ++ br->offload_cache_size = 128; ++ br->offload_cache_reserved = 8; + dev->max_mtu = ETH_MAX_MTU; + + br_netfilter_rtable_init(br); +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -23,6 +23,7 @@ + #include + #include + #include "br_private.h" ++#include "br_private_offload.h" + + static const struct rhashtable_params br_fdb_rht_params = { + .head_offset = offsetof(struct net_bridge_fdb_entry, rhnode), +@@ -185,6 +186,8 @@ static void fdb_notify(struct net_bridge + struct sk_buff *skb; + int err = -ENOBUFS; + ++ br_offload_fdb_update(fdb); ++ + if (swdev_notify) + br_switchdev_fdb_notify(br, fdb, type); + +@@ -393,6 +396,8 @@ static struct net_bridge_fdb_entry *fdb_ + fdb->key.vlan_id = vid; + fdb->flags = flags; + fdb->updated = fdb->used = jiffies; ++ INIT_HLIST_HEAD(&fdb->offload_in); ++ INIT_HLIST_HEAD(&fdb->offload_out); + err = rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, &fdb->rhnode, + br_fdb_rht_params); + if (err) { +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -16,6 +16,7 @@ + #include + #include + #include "br_private.h" ++#include "br_private_offload.h" + + /* Don't forward packets to originating port or forwarding disabled */ + static inline int should_deliver(const struct net_bridge_port *p, +@@ -32,6 +33,8 @@ static inline int should_deliver(const s + + int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) + { ++ br_offload_output(skb); ++ + skb_push(skb, ETH_HLEN); + if (!is_skb_forwardable(skb->dev, skb)) + goto drop; +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -25,6 +25,7 @@ + #include + + #include "br_private.h" ++#include "br_private_offload.h" + + /* + * Determine initial path cost based on speed. +@@ -437,7 +438,7 @@ static struct net_bridge_port *new_nbp(s + p->path_cost = port_cost(dev); + p->priority = 0x8000 >> BR_PORT_BITS; + p->port_no = index; +- p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; ++ p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD | BR_OFFLOAD; + br_init_port(p); + br_set_state(p, BR_STATE_DISABLED); + br_stp_port_timer_init(p); +@@ -761,6 +762,9 @@ void br_port_flags_change(struct net_bri + + if (mask & BR_NEIGH_SUPPRESS) + br_recalculate_neigh_suppress_enabled(br); ++ ++ if (mask & BR_OFFLOAD) ++ br_offload_port_state(p); + } + + bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag) +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -22,6 +22,7 @@ + #include + #include "br_private.h" + #include "br_private_tunnel.h" ++#include "br_private_offload.h" + + static int + br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) +@@ -189,6 +190,7 @@ int br_handle_frame_finish(struct net *n + dst->used = now; + br_forward(dst->dst, skb, local_rcv, false); + } else { ++ br_offload_skb_disable(skb); + if (!mcast_hit) + br_flood(br, skb, pkt_type, local_rcv, false); + else +@@ -322,6 +324,9 @@ static rx_handler_result_t br_handle_fra + memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); + + p = br_port_get_rcu(skb->dev); ++ if (br_offload_input(p, skb)) ++ return RX_HANDLER_CONSUMED; ++ + if (p->flags & BR_VLAN_TUNNEL) + br_handle_ingress_vlan_tunnel(skb, p, nbp_vlan_group_rcu(p)); + +--- /dev/null ++++ b/net/bridge/br_offload.c +@@ -0,0 +1,438 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++#include ++#include ++#include "br_private.h" ++#include "br_private_offload.h" ++ ++static DEFINE_SPINLOCK(offload_lock); ++ ++struct bridge_flow_key { ++ u8 dest[ETH_ALEN]; ++ u8 src[ETH_ALEN]; ++#ifdef CONFIG_BRIDGE_VLAN_FILTERING ++ u16 vlan_tag; ++ bool vlan_present; ++#endif ++}; ++ ++struct bridge_flow { ++ struct net_bridge_port *port; ++ struct rhash_head node; ++ struct bridge_flow_key key; ++#ifdef CONFIG_BRIDGE_VLAN_FILTERING ++ bool vlan_out_present; ++ u16 vlan_out; ++#endif ++ ++ unsigned long used; ++ struct net_bridge_fdb_entry *fdb_in, *fdb_out; ++ struct hlist_node fdb_list_in, fdb_list_out; ++ ++ struct rcu_head rcu; ++}; ++ ++static const struct rhashtable_params flow_params = { ++ .automatic_shrinking = true, ++ .head_offset = offsetof(struct bridge_flow, node), ++ .key_len = sizeof(struct bridge_flow_key), ++ .key_offset = offsetof(struct bridge_flow, key), ++}; ++ ++static struct kmem_cache *offload_cache __read_mostly; ++ ++static void ++flow_rcu_free(struct rcu_head *head) ++{ ++ struct bridge_flow *flow; ++ ++ flow = container_of(head, struct bridge_flow, rcu); ++ kmem_cache_free(offload_cache, flow); ++} ++ ++static void ++__br_offload_flow_free(struct bridge_flow *flow) ++{ ++ flow->used = 0; ++ hlist_del(&flow->fdb_list_in); ++ hlist_del(&flow->fdb_list_out); ++ ++ call_rcu(&flow->rcu, flow_rcu_free); ++} ++ ++static void ++br_offload_flow_free(struct bridge_flow *flow) ++{ ++ if (rhashtable_remove_fast(&flow->port->offload.rht, &flow->node, ++ flow_params) != 0) ++ return; ++ ++ __br_offload_flow_free(flow); ++} ++ ++static bool ++br_offload_flow_fdb_refresh_time(struct bridge_flow *flow, ++ struct net_bridge_fdb_entry *fdb) ++{ ++ if (!time_after(flow->used, fdb->updated)) ++ return false; ++ ++ fdb->updated = flow->used; ++ ++ return true; ++} ++ ++ ++static void ++br_offload_flow_refresh_time(struct bridge_flow *flow) ++{ ++ br_offload_flow_fdb_refresh_time(flow, flow->fdb_in); ++ br_offload_flow_fdb_refresh_time(flow, flow->fdb_out); ++} ++ ++static void ++br_offload_destroy_cb(void *ptr, void *arg) ++{ ++ struct bridge_flow *flow = ptr; ++ ++ __br_offload_flow_free(flow); ++} ++ ++static bool ++br_offload_need_gc(struct net_bridge_port *p) ++{ ++ return (atomic_read(&p->offload.rht.nelems) + ++ p->br->offload_cache_reserved) >= p->br->offload_cache_size; ++} ++ ++static void ++br_offload_gc_work(struct work_struct *work) ++{ ++ struct rhashtable_iter hti; ++ struct net_bridge_port *p; ++ struct bridge_flow *gc_flow = NULL; ++ struct bridge_flow *flow; ++ unsigned long gc_used; ++ ++ p = container_of(work, struct net_bridge_port, offload.gc_work); ++ ++ if (!br_offload_need_gc(p)) ++ return; ++ ++ rhashtable_walk_enter(&p->offload.rht, &hti); ++ rhashtable_walk_start(&hti); ++ while ((flow = rhashtable_walk_next(&hti)) != NULL) { ++ unsigned long used; ++ ++ if (IS_ERR(flow)) ++ continue; ++ ++ used = READ_ONCE(flow->used); ++ if (!used) ++ continue; ++ ++ if (gc_flow && !time_before(used, gc_used)) ++ continue; ++ ++ gc_flow = flow; ++ gc_used = used; ++ } ++ rhashtable_walk_stop(&hti); ++ rhashtable_walk_exit(&hti); ++ ++ if (!gc_flow) ++ return; ++ ++ spin_lock_bh(&offload_lock); ++ if (br_offload_need_gc(p) && gc_flow && ++ gc_flow->used == gc_used) ++ br_offload_flow_free(gc_flow); ++ if (p->offload.enabled && br_offload_need_gc(p)) ++ queue_work(system_long_wq, work); ++ spin_unlock_bh(&offload_lock); ++ ++} ++ ++void br_offload_port_state(struct net_bridge_port *p) ++{ ++ struct net_bridge_port_offload *o = &p->offload; ++ bool enabled = true; ++ bool flush = false; ++ ++ if (p->state != BR_STATE_FORWARDING || ++ !(p->flags & BR_OFFLOAD)) ++ enabled = false; ++ ++ spin_lock_bh(&offload_lock); ++ if (o->enabled == enabled) ++ goto out; ++ ++ if (enabled) { ++ if (!o->gc_work.func) ++ INIT_WORK(&o->gc_work, br_offload_gc_work); ++ rhashtable_init(&o->rht, &flow_params); ++ } else { ++ flush = true; ++ rhashtable_free_and_destroy(&o->rht, br_offload_destroy_cb, o); ++ } ++ ++ o->enabled = enabled; ++ ++out: ++ spin_unlock_bh(&offload_lock); ++ ++ if (flush) ++ flush_work(&o->gc_work); ++} ++ ++void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb) ++{ ++ struct bridge_flow *f; ++ struct hlist_node *tmp; ++ ++ spin_lock_bh(&offload_lock); ++ ++ hlist_for_each_entry_safe(f, tmp, &fdb->offload_in, fdb_list_in) ++ br_offload_flow_free(f); ++ ++ hlist_for_each_entry_safe(f, tmp, &fdb->offload_out, fdb_list_out) ++ br_offload_flow_free(f); ++ ++ spin_unlock_bh(&offload_lock); ++} ++ ++static void ++br_offload_prepare_key(struct net_bridge_port *p, struct bridge_flow_key *key, ++ struct sk_buff *skb) ++{ ++ memset(key, 0, sizeof(*key)); ++ memcpy(key, eth_hdr(skb), 2 * ETH_ALEN); ++#ifdef CONFIG_BRIDGE_VLAN_FILTERING ++ if (!br_opt_get(p->br, BROPT_VLAN_ENABLED)) ++ return; ++ ++ if (!skb_vlan_tag_present(skb) || skb->vlan_proto != p->br->vlan_proto) ++ return; ++ ++ key->vlan_present = true; ++ key->vlan_tag = skb_vlan_tag_get_id(skb); ++#endif ++} ++ ++void br_offload_output(struct sk_buff *skb) ++{ ++ struct net_bridge_port_offload *o; ++ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; ++ struct net_bridge_port *p, *inp; ++ struct net_device *dev; ++ struct net_bridge_fdb_entry *fdb_in, *fdb_out; ++ struct net_bridge_vlan_group *vg; ++ struct bridge_flow_key key; ++ struct bridge_flow *flow; ++ u16 vlan; ++ ++ if (!cb->offload) ++ return; ++ ++ rcu_read_lock(); ++ ++ p = br_port_get_rcu(skb->dev); ++ if (!p) ++ goto out; ++ ++ o = &p->offload; ++ if (!o->enabled) ++ goto out; ++ ++ if (atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size) ++ goto out; ++ ++ dev = dev_get_by_index_rcu(dev_net(p->br->dev), cb->input_ifindex); ++ if (!dev) ++ goto out; ++ ++ inp = br_port_get_rcu(dev); ++ if (!inp) ++ goto out; ++ ++ vg = nbp_vlan_group_rcu(inp); ++ vlan = cb->input_vlan_present ? cb->input_vlan_tag : br_get_pvid(vg); ++ fdb_in = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_source, vlan); ++ if (!fdb_in || !fdb_in->dst) ++ goto out; ++ ++ vg = nbp_vlan_group_rcu(p); ++ vlan = skb_vlan_tag_present(skb) ? skb_vlan_tag_get_id(skb) : br_get_pvid(vg); ++ fdb_out = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_dest, vlan); ++ if (!fdb_out || !fdb_out->dst) ++ goto out; ++ ++ br_offload_prepare_key(p, &key, skb); ++#ifdef CONFIG_BRIDGE_VLAN_FILTERING ++ key.vlan_present = cb->input_vlan_present; ++ key.vlan_tag = cb->input_vlan_tag; ++#endif ++ ++ flow = kmem_cache_alloc(offload_cache, GFP_ATOMIC); ++ flow->port = inp; ++ memcpy(&flow->key, &key, sizeof(key)); ++ ++#ifdef CONFIG_BRIDGE_VLAN_FILTERING ++ flow->vlan_out_present = skb_vlan_tag_present(skb); ++ flow->vlan_out = skb_vlan_tag_get(skb); ++#endif ++ ++ flow->fdb_in = fdb_in; ++ flow->fdb_out = fdb_out; ++ flow->used = jiffies; ++ ++ spin_lock_bh(&offload_lock); ++ if (!o->enabled || ++ atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size || ++ rhashtable_insert_fast(&inp->offload.rht, &flow->node, flow_params)) { ++ kmem_cache_free(offload_cache, flow); ++ goto out_unlock; ++ } ++ ++ hlist_add_head(&flow->fdb_list_in, &fdb_in->offload_in); ++ hlist_add_head(&flow->fdb_list_out, &fdb_out->offload_out); ++ ++ if (br_offload_need_gc(p)) ++ queue_work(system_long_wq, &p->offload.gc_work); ++ ++out_unlock: ++ spin_unlock_bh(&offload_lock); ++ ++out: ++ rcu_read_unlock(); ++} ++ ++bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb) ++{ ++ struct net_bridge_port_offload *o = &p->offload; ++ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; ++ struct bridge_flow_key key; ++ struct net_bridge_port *dst; ++ struct bridge_flow *flow; ++ unsigned long now = jiffies; ++ bool ret = false; ++ ++ if (skb->len < sizeof(key)) ++ return false; ++ ++ if (!o->enabled) ++ return false; ++ ++ if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) ++ return false; ++ ++ br_offload_prepare_key(p, &key, skb); ++ ++ rcu_read_lock(); ++ flow = rhashtable_lookup(&o->rht, &key, flow_params); ++ if (!flow) { ++ cb->offload = 1; ++#ifdef CONFIG_BRIDGE_VLAN_FILTERING ++ cb->input_vlan_present = key.vlan_present != 0; ++ cb->input_vlan_tag = key.vlan_tag; ++#endif ++ cb->input_ifindex = p->dev->ifindex; ++ goto out; ++ } ++ ++ if (flow->fdb_in->dst != p) ++ goto out; ++ ++ dst = flow->fdb_out->dst; ++ if (!dst) ++ goto out; ++ ++ ret = true; ++#ifdef CONFIG_BRIDGE_VLAN_FILTERING ++ if (!flow->vlan_out_present && key.vlan_present) { ++ __vlan_hwaccel_clear_tag(skb); ++ } else if (flow->vlan_out_present) { ++ if (skb_vlan_tag_present(skb) && ++ skb->vlan_proto != p->br->vlan_proto) { ++ /* Protocol-mismatch, empty out vlan_tci for new tag */ ++ skb_push(skb, ETH_HLEN); ++ skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, ++ skb_vlan_tag_get(skb)); ++ if (unlikely(!skb)) ++ goto out; ++ ++ skb_pull(skb, ETH_HLEN); ++ skb_reset_mac_len(skb); ++ } ++ ++ __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, ++ flow->vlan_out); ++ } ++#endif ++ ++ skb->dev = dst->dev; ++ skb_push(skb, ETH_HLEN); ++ ++ if (skb_warn_if_lro(skb) || !is_skb_forwardable(skb->dev, skb)) { ++ kfree_skb(skb); ++ goto out; ++ } ++ ++ if (now - flow->used >= HZ) { ++ flow->used = now; ++ br_offload_flow_refresh_time(flow); ++ } ++ ++ skb_forward_csum(skb); ++ dev_queue_xmit(skb); ++ ++out: ++ rcu_read_unlock(); ++ return ret; ++} ++ ++static void ++br_offload_check_gc(struct net_bridge *br) ++{ ++ struct net_bridge_port *p; ++ ++ spin_lock_bh(&br->lock); ++ list_for_each_entry(p, &br->port_list, list) ++ if (br_offload_need_gc(p)) ++ queue_work(system_long_wq, &p->offload.gc_work); ++ spin_unlock_bh(&br->lock); ++} ++ ++ ++int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, ++ struct netlink_ext_ack *extack) ++{ ++ br->offload_cache_size = val; ++ br_offload_check_gc(br); ++ ++ return 0; ++} ++ ++int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, ++ struct netlink_ext_ack *extack) ++{ ++ br->offload_cache_reserved = val; ++ br_offload_check_gc(br); ++ ++ return 0; ++} ++ ++int __init br_offload_init(void) ++{ ++ offload_cache = kmem_cache_create("bridge_offload_cache", ++ sizeof(struct bridge_flow), ++ 0, SLAB_HWCACHE_ALIGN, NULL); ++ if (!offload_cache) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++void br_offload_fini(void) ++{ ++ kmem_cache_destroy(offload_cache); ++} +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -271,7 +271,13 @@ struct net_bridge_fdb_entry { + unsigned long updated ____cacheline_aligned_in_smp; + unsigned long used; + +- struct rcu_head rcu; ++ union { ++ struct { ++ struct hlist_head offload_in; ++ struct hlist_head offload_out; ++ }; ++ struct rcu_head rcu; ++ }; + }; + + struct net_bridge_fdb_flush_desc { +@@ -353,6 +359,12 @@ struct net_bridge_mdb_entry { + struct rcu_head rcu; + }; + ++struct net_bridge_port_offload { ++ struct rhashtable rht; ++ struct work_struct gc_work; ++ bool enabled; ++}; ++ + struct net_bridge_port { + struct net_bridge *br; + struct net_device *dev; +@@ -414,6 +426,7 @@ struct net_bridge_port { + u16 backup_redirected_cnt; + + struct bridge_stp_xstats stp_xstats; ++ struct net_bridge_port_offload offload; + }; + + #define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj) +@@ -531,6 +544,9 @@ struct net_bridge { + struct kobject *ifobj; + u32 auto_cnt; + ++ u32 offload_cache_size; ++ u32 offload_cache_reserved; ++ + #ifdef CONFIG_NET_SWITCHDEV + /* Counter used to make sure that hardware domains get unique + * identifiers in case a bridge spans multiple switchdev instances. +@@ -565,6 +581,10 @@ struct br_input_skb_cb { + #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE + u8 br_netfilter_broute:1; + #endif ++ u8 offload:1; ++ u8 input_vlan_present:1; ++ u16 input_vlan_tag; ++ int input_ifindex; + + #ifdef CONFIG_NET_SWITCHDEV + /* Set if TX data plane offloading is used towards at least one +--- /dev/null ++++ b/net/bridge/br_private_offload.h +@@ -0,0 +1,23 @@ ++#ifndef __BR_OFFLOAD_H ++#define __BR_OFFLOAD_H ++ ++bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb); ++void br_offload_output(struct sk_buff *skb); ++void br_offload_port_state(struct net_bridge_port *p); ++void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb); ++int br_offload_init(void); ++void br_offload_fini(void); ++int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, ++ struct netlink_ext_ack *extack); ++int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, ++ struct netlink_ext_ack *extack); ++ ++static inline void br_offload_skb_disable(struct sk_buff *skb) ++{ ++ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; ++ ++ if (cb->offload) ++ cb->offload = 0; ++} ++ ++#endif +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -12,6 +12,7 @@ + + #include "br_private.h" + #include "br_private_stp.h" ++#include "br_private_offload.h" + + /* since time values in bpdu are in jiffies and then scaled (1/256) + * before sending, make sure that is at least one STP tick. +@@ -58,6 +59,8 @@ void br_set_state(struct net_bridge_port + (unsigned int) p->port_no, p->dev->name, + br_port_state_names[p->state]); + ++ br_offload_port_state(p); ++ + if (p->br->stp_enabled == BR_KERNEL_STP) { + switch (p->state) { + case BR_STATE_BLOCKING: +--- a/net/bridge/br_sysfs_br.c ++++ b/net/bridge/br_sysfs_br.c +@@ -18,6 +18,7 @@ + #include + + #include "br_private.h" ++#include "br_private_offload.h" + + /* IMPORTANT: new bridge options must be added with netlink support only + * please do not add new sysfs entries +@@ -933,6 +934,38 @@ static ssize_t vlan_stats_per_port_store + static DEVICE_ATTR_RW(vlan_stats_per_port); + #endif + ++static ssize_t offload_cache_size_show(struct device *d, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct net_bridge *br = to_bridge(d); ++ return sprintf(buf, "%u\n", br->offload_cache_size); ++} ++ ++static ssize_t offload_cache_size_store(struct device *d, ++ struct device_attribute *attr, ++ const char *buf, size_t len) ++{ ++ return store_bridge_parm(d, buf, len, br_offload_set_cache_size); ++} ++static DEVICE_ATTR_RW(offload_cache_size); ++ ++static ssize_t offload_cache_reserved_show(struct device *d, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct net_bridge *br = to_bridge(d); ++ return sprintf(buf, "%u\n", br->offload_cache_reserved); ++} ++ ++static ssize_t offload_cache_reserved_store(struct device *d, ++ struct device_attribute *attr, ++ const char *buf, size_t len) ++{ ++ return store_bridge_parm(d, buf, len, br_offload_set_cache_reserved); ++} ++static DEVICE_ATTR_RW(offload_cache_reserved); ++ + static struct attribute *bridge_attrs[] = { + &dev_attr_forward_delay.attr, + &dev_attr_hello_time.attr, +@@ -987,6 +1020,8 @@ static struct attribute *bridge_attrs[] + &dev_attr_vlan_stats_enabled.attr, + &dev_attr_vlan_stats_per_port.attr, + #endif ++ &dev_attr_offload_cache_size.attr, ++ &dev_attr_offload_cache_reserved.attr, + NULL + }; + +--- a/net/bridge/br_sysfs_if.c ++++ b/net/bridge/br_sysfs_if.c +@@ -241,6 +241,7 @@ BRPORT_ATTR_FLAG(broadcast_flood, BR_BCA + BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); + BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); + BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); ++BRPORT_ATTR_FLAG(offload, BR_OFFLOAD); + + #ifdef CONFIG_BRIDGE_IGMP_SNOOPING + static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) +@@ -295,6 +296,7 @@ static const struct brport_attribute *br + &brport_attr_isolated, + &brport_attr_bpdu_filter, + &brport_attr_backup_port, ++ &brport_attr_offload, + NULL + }; + +--- a/net/bridge/br_vlan_tunnel.c ++++ b/net/bridge/br_vlan_tunnel.c +@@ -15,6 +15,7 @@ + + #include "br_private.h" + #include "br_private_tunnel.h" ++#include "br_private_offload.h" + + static inline int br_vlan_tunid_cmp(struct rhashtable_compare_arg *arg, + const void *ptr) +@@ -180,6 +181,7 @@ void br_handle_ingress_vlan_tunnel(struc + skb_dst_drop(skb); + + __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, vlan->vid); ++ br_offload_skb_disable(skb); + } + + int br_handle_egress_vlan_tunnel(struct sk_buff *skb, +@@ -201,6 +203,7 @@ int br_handle_egress_vlan_tunnel(struct + if (err) + return err; + ++ br_offload_skb_disable(skb); + tunnel_dst = rcu_dereference(vlan->tinfo.tunnel_dst); + if (tunnel_dst && dst_hold_safe(&tunnel_dst->dst)) + skb_dst_set(skb, &tunnel_dst->dst); diff --git a/target/linux/generic/hack-6.1/601-of_net-add-mac-address-ascii-support.patch b/target/linux/generic/hack-6.1/601-of_net-add-mac-address-ascii-support.patch new file mode 100644 index 000000000..94a53ab35 --- /dev/null +++ b/target/linux/generic/hack-6.1/601-of_net-add-mac-address-ascii-support.patch @@ -0,0 +1,112 @@ +From: Yousong Zhou +Subject: [PATCH] ath79: add nvmem cell mac-address-ascii support + +This is needed for devices with mac address stored in ascii format, e.g. +HiWiFi HC6361 to be ported in the following patch. + +Submitted-by: Yousong Zhou +--- + net/ethernet/eth.c | 83 ++++++++++++------ + 1 files changed, 72 insertions(+), 11 deletions(-) + +--- a/net/ethernet/eth.c ++++ b/net/ethernet/eth.c +@@ -531,6 +531,63 @@ int eth_platform_get_mac_address(struct + } + EXPORT_SYMBOL(eth_platform_get_mac_address); + ++static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell) ++{ ++ size_t len; ++ void *mac; ++ ++ mac = nvmem_cell_read(cell, &len); ++ if (IS_ERR(mac)) ++ return PTR_ERR(mac); ++ if (len != ETH_ALEN) { ++ kfree(mac); ++ return ERR_PTR(-EINVAL); ++ } ++ return mac; ++} ++ ++static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell) ++{ ++ size_t len; ++ int ret; ++ void *mac_ascii; ++ u8 *mac; ++ ++ mac_ascii = nvmem_cell_read(cell, &len); ++ if (IS_ERR(mac_ascii)) ++ return PTR_ERR(mac_ascii); ++ if (len != ETH_ALEN*2+5) { ++ kfree(mac_ascii); ++ return ERR_PTR(-EINVAL); ++ } ++ mac = kmalloc(ETH_ALEN, GFP_KERNEL); ++ if (!mac) { ++ kfree(mac_ascii); ++ return ERR_PTR(-ENOMEM); ++ } ++ ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", ++ &mac[0], &mac[1], &mac[2], ++ &mac[3], &mac[4], &mac[5]); ++ kfree(mac_ascii); ++ if (ret == ETH_ALEN) ++ return mac; ++ kfree(mac); ++ return ERR_PTR(-EINVAL); ++} ++ ++static struct nvmem_cell_mac_address_property { ++ char *name; ++ void *(*read)(struct nvmem_cell *); ++} nvmem_cell_mac_address_properties[] = { ++ { ++ .name = "mac-address", ++ .read = nvmem_cell_get_mac_address, ++ }, { ++ .name = "mac-address-ascii", ++ .read = nvmem_cell_get_mac_address_ascii, ++ }, ++}; ++ + /** + * platform_get_ethdev_address - Set netdev's MAC address from a given device + * @dev: Pointer to the device +@@ -564,19 +621,23 @@ int nvmem_get_mac_address(struct device + { + struct nvmem_cell *cell; + const void *mac; +- size_t len; ++ struct nvmem_cell_mac_address_property *property; ++ int i; + +- cell = nvmem_cell_get(dev, "mac-address"); +- if (IS_ERR(cell)) +- return PTR_ERR(cell); +- +- mac = nvmem_cell_read(cell, &len); +- nvmem_cell_put(cell); +- +- if (IS_ERR(mac)) +- return PTR_ERR(mac); ++ for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) { ++ property = &nvmem_cell_mac_address_properties[i]; ++ cell = nvmem_cell_get(dev, property->name); ++ if (IS_ERR(cell)) { ++ if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1) ++ return PTR_ERR(cell); ++ continue; ++ } ++ mac = property->read(cell); ++ nvmem_cell_put(cell); ++ break; ++ } + +- if (len != ETH_ALEN || !is_valid_ether_addr(mac)) { ++ if (!is_valid_ether_addr(mac)) { + kfree(mac); + return -EINVAL; + } diff --git a/target/linux/generic/hack-6.0/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch similarity index 93% rename from target/linux/generic/hack-6.0/645-netfilter-connmark-introduce-set-dscpmark.patch rename to target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch index 2d3fe01a7..fde2bb7d3 100644 --- a/target/linux/generic/hack-6.0/645-netfilter-connmark-introduce-set-dscpmark.patch +++ b/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch @@ -83,7 +83,7 @@ Signed-off-by: Kevin Darbyshire-Bryant --- a/include/uapi/linux/netfilter/xt_connmark.h +++ b/include/uapi/linux/netfilter/xt_connmark.h -@@ -20,6 +20,11 @@ enum { +@@ -15,6 +15,11 @@ enum { }; enum { @@ -95,7 +95,7 @@ Signed-off-by: Kevin Darbyshire-Bryant D_SHIFT_LEFT = 0, D_SHIFT_RIGHT, }; -@@ -34,6 +39,11 @@ struct xt_connmark_tginfo2 { +@@ -29,6 +34,11 @@ struct xt_connmark_tginfo2 { __u8 shift_dir, shift_bits, mode; }; @@ -109,7 +109,7 @@ Signed-off-by: Kevin Darbyshire-Bryant __u8 invert; --- a/net/netfilter/xt_connmark.c +++ b/net/netfilter/xt_connmark.c -@@ -24,12 +24,13 @@ MODULE_ALIAS("ipt_connmark"); +@@ -24,13 +24,14 @@ MODULE_ALIAS("ipt_connmark"); MODULE_ALIAS("ip6t_connmark"); static unsigned int @@ -120,15 +120,16 @@ Signed-off-by: Kevin Darbyshire-Bryant u_int32_t new_targetmark; struct nf_conn *ct; u_int32_t newmark; + u_int32_t oldmark; + u_int8_t dscp; ct = nf_ct_get(skb, &ctinfo); if (ct == NULL) -@@ -37,12 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c - +@@ -39,12 +40,24 @@ connmark_tg_shift(struct sk_buff *skb, c switch (info->mode) { case XT_CONNMARK_SET: -- newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; + oldmark = READ_ONCE(ct->mark); +- newmark = (oldmark & ~info->ctmask) ^ info->ctmark; - if (info->shift_dir == D_SHIFT_RIGHT) - newmark >>= info->shift_bits; - else @@ -151,10 +152,10 @@ Signed-off-by: Kevin Darbyshire-Bryant + newmark = (newmark & ~info->ctmark) | + (info->ctmask | (dscp << info->shift_bits)); + } - if (ct->mark != newmark) { - ct->mark = newmark; + if (READ_ONCE(ct->mark) != newmark) { + WRITE_ONCE(ct->mark, newmark); nf_conntrack_event_cache(IPCT_MARK, ct); -@@ -81,20 +94,36 @@ static unsigned int +@@ -83,20 +96,36 @@ static unsigned int connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_connmark_tginfo1 *info = par->targinfo; @@ -193,7 +194,7 @@ Signed-off-by: Kevin Darbyshire-Bryant return connmark_tg_shift(skb, info); } -@@ -165,6 +194,16 @@ static struct xt_target connmark_tg_reg[ +@@ -167,6 +196,16 @@ static struct xt_target connmark_tg_reg[ .targetsize = sizeof(struct xt_connmark_tginfo2), .destroy = connmark_tg_destroy, .me = THIS_MODULE, diff --git a/target/linux/generic/hack-6.0/650-netfilter-add-xt_FLOWOFFLOAD-target.patch b/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch similarity index 90% rename from target/linux/generic/hack-6.0/650-netfilter-add-xt_FLOWOFFLOAD-target.patch rename to target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch index 85be7a7af..557144cbc 100644 --- a/target/linux/generic/hack-6.0/650-netfilter-add-xt_FLOWOFFLOAD-target.patch +++ b/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch @@ -8,30 +8,7 @@ Signed-off-by: Felix Fietkau --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig -@@ -712,8 +712,6 @@ config NFT_REJECT_NETDEV - - endif # NF_TABLES_NETDEV - --endif # NF_TABLES -- - config NF_FLOW_TABLE_INET - tristate "Netfilter flow table mixed IPv4/IPv6 module" - depends on NF_FLOW_TABLE -@@ -722,11 +720,12 @@ config NF_FLOW_TABLE_INET - - To compile it as a module, choose M here. - -+endif # NF_TABLES -+ - config NF_FLOW_TABLE - tristate "Netfilter flow table module" - depends on NETFILTER_INGRESS - depends on NF_CONNTRACK -- depends on NF_TABLES - help - This option adds the flow table core infrastructure. - -@@ -1023,6 +1022,15 @@ config NETFILTER_XT_TARGET_NOTRACK +@@ -1023,6 +1023,15 @@ config NETFILTER_XT_TARGET_NOTRACK depends on NETFILTER_ADVANCED select NETFILTER_XT_TARGET_CT @@ -49,7 +26,7 @@ Signed-off-by: Felix Fietkau depends on NETFILTER_ADVANCED --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile -@@ -148,6 +148,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF +@@ -154,6 +154,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o @@ -59,7 +36,7 @@ Signed-off-by: Felix Fietkau obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o --- /dev/null +++ b/net/netfilter/xt_FLOWOFFLOAD.c -@@ -0,0 +1,694 @@ +@@ -0,0 +1,697 @@ +/* + * Copyright (C) 2018-2021 Felix Fietkau + * @@ -250,13 +227,16 @@ Signed-off-by: Felix Fietkau +} + +static void -+xt_flowoffload_check_hook(struct flow_offload *flow, void *data) ++xt_flowoffload_check_hook(struct nf_flowtable *flowtable, ++ struct flow_offload *flow, void *data) +{ -+ struct xt_flowoffload_table *table = data; ++ struct xt_flowoffload_table *table; + struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple; + struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple; + struct xt_flowoffload_hook *hook; + ++ table = container_of(flowtable, struct xt_flowoffload_table, ft); ++ + spin_lock_bh(&hooks_lock); + hlist_for_each_entry(hook, &table->hooks, list) { + if (hook->ops.dev->ifindex != tuple0->iifidx && @@ -283,8 +263,8 @@ Signed-off-by: Felix Fietkau + hook->used = false; + spin_unlock_bh(&hooks_lock); + -+ -+ ++ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook, ++ NULL); + if (err && err != -EAGAIN) + goto out; + @@ -754,6 +734,34 @@ Signed-off-by: Felix Fietkau +MODULE_LICENSE("GPL"); +module_init(xt_flowoffload_tg_init); +module_exit(xt_flowoffload_tg_exit); +--- a/net/netfilter/nf_flow_table_core.c ++++ b/net/netfilter/nf_flow_table_core.c +@@ -7,7 +7,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -381,8 +380,7 @@ flow_offload_lookup(struct nf_flowtable + } + EXPORT_SYMBOL_GPL(flow_offload_lookup); + +-static int +-nf_flow_table_iterate(struct nf_flowtable *flow_table, ++int nf_flow_table_iterate(struct nf_flowtable *flow_table, + void (*iter)(struct nf_flowtable *flowtable, + struct flow_offload *flow, void *data), + void *data) +@@ -436,6 +434,7 @@ static void nf_flow_offload_gc_step(stru + nf_flow_offload_stats(flow_table, flow); + } + } ++EXPORT_SYMBOL_GPL(nf_flow_table_iterate); + + void nf_flow_table_gc_run(struct nf_flowtable *flow_table) + { --- /dev/null +++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h @@ -0,0 +1,17 @@ @@ -774,3 +782,17 @@ Signed-off-by: Felix Fietkau +}; + +#endif /* _XT_FLOWOFFLOAD_H */ +--- a/include/net/netfilter/nf_flow_table.h ++++ b/include/net/netfilter/nf_flow_table.h +@@ -280,6 +280,11 @@ void nf_flow_table_free(struct nf_flowta + + void flow_offload_teardown(struct flow_offload *flow); + ++int nf_flow_table_iterate(struct nf_flowtable *flow_table, ++ void (*iter)(struct nf_flowtable *flowtable, ++ struct flow_offload *flow, void *data), ++ void *data); ++ + void nf_flow_snat_port(const struct flow_offload *flow, + struct sk_buff *skb, unsigned int thoff, + u8 protocol, enum flow_offload_tuple_dir dir); diff --git a/target/linux/generic/hack-6.0/651-wireless_mesh_header.patch b/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch similarity index 92% rename from target/linux/generic/hack-6.0/651-wireless_mesh_header.patch rename to target/linux/generic/hack-6.1/651-wireless_mesh_header.patch index fd7d5346a..795cff377 100644 --- a/target/linux/generic/hack-6.0/651-wireless_mesh_header.patch +++ b/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch @@ -11,7 +11,7 @@ Signed-off-by: Imre Kaloz --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -149,8 +149,8 @@ static inline bool dev_xmit_complete(int +@@ -150,8 +150,8 @@ static inline bool dev_xmit_complete(int #if defined(CONFIG_HYPERV_NET) # define LL_MAX_HEADER 128 diff --git a/target/linux/generic/hack-6.0/660-fq_codel_defaults.patch b/target/linux/generic/hack-6.1/660-fq_codel_defaults.patch similarity index 92% rename from target/linux/generic/hack-6.0/660-fq_codel_defaults.patch rename to target/linux/generic/hack-6.1/660-fq_codel_defaults.patch index 42698c645..b923a2d20 100644 --- a/target/linux/generic/hack-6.0/660-fq_codel_defaults.patch +++ b/target/linux/generic/hack-6.1/660-fq_codel_defaults.patch @@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c -@@ -474,7 +474,11 @@ static int fq_codel_init(struct Qdisc *s +@@ -471,7 +471,11 @@ static int fq_codel_init(struct Qdisc *s sch->limit = 10*1024; q->flows_cnt = 1024; diff --git a/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch b/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch new file mode 100644 index 000000000..11152e53c --- /dev/null +++ b/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch @@ -0,0 +1,25 @@ +From 804fbb3f2ec9283f7b778e057a68bfff440a0be6 Mon Sep 17 00:00:00 2001 +From: Rui Salvaterra +Date: Wed, 30 Mar 2022 22:51:55 +0100 +Subject: [PATCH] kernel: ct: size the hashtable more adequately + +To set the default size of the connection tracking hash table, a divider of +16384 becomes inadequate for a router handling lots of connections. Divide by +2048 instead, making the default size scale better with the available RAM. + +Signed-off-by: Rui Salvaterra +--- + net/netfilter/nf_conntrack_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -2698,7 +2698,7 @@ int nf_conntrack_init_start(void) + + if (!nf_conntrack_htable_size) { + nf_conntrack_htable_size +- = (((nr_pages << PAGE_SHIFT) / 16384) ++ = (((nr_pages << PAGE_SHIFT) / 2048) + / sizeof(struct hlist_head)); + if (BITS_PER_LONG >= 64 && + nr_pages > (4 * (1024 * 1024 * 1024 / PAGE_SIZE))) diff --git a/target/linux/generic/hack-6.0/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch similarity index 94% rename from target/linux/generic/hack-6.0/700-swconfig_switch_drivers.patch rename to target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch index 560937a7c..48be44002 100644 --- a/target/linux/generic/hack-6.0/700-swconfig_switch_drivers.patch +++ b/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch @@ -36,8 +36,9 @@ Signed-off-by: Felix Fietkau + Support for FC is very limited. + +config AR8216_PHY -+ tristate "Driver for Atheros AR8216 switches" ++ tristate "Driver for Atheros AR8216/8327 switches" + select SWCONFIG ++ select ETHERNET_PACKET_MANGLE + +config AR8216_PHY_LEDS + bool "Atheros AR8216 switch LED support" @@ -52,7 +53,6 @@ Signed-off-by: Felix Fietkau +config PSB6970_PHY + tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch" + select SWCONFIG -+ select ETHERNET_PACKET_MANGLE + +config RTL8306_PHY + tristate "Driver for Realtek RTL8306S switches" @@ -95,13 +95,15 @@ Signed-off-by: Felix Fietkau config AMD_PHY --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile -@@ -24,6 +24,19 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_ +@@ -24,6 +24,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_ obj-$(CONFIG_PHYLINK) += phylink.o obj-$(CONFIG_PHYLIB) += libphy.o +obj-$(CONFIG_SWCONFIG) += swconfig.o +obj-$(CONFIG_ADM6996_PHY) += adm6996.o -+obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o ++obj-$(CONFIG_AR8216_PHY) += ar8xxx.o ++ar8xxx-y += ar8216.o ++ar8xxx-y += ar8327.o +obj-$(CONFIG_SWCONFIG_B53) += b53/ +obj-$(CONFIG_IP17XX_PHY) += ip17xx.o +obj-$(CONFIG_PSB6970_PHY) += psb6970.o diff --git a/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch b/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch new file mode 100644 index 000000000..be2b86a0c --- /dev/null +++ b/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch @@ -0,0 +1,21 @@ +From ebd924d773223593142d417c41d4ee6fa16f1805 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:45:56 +0200 +Subject: [PATCH] net/dsa/mv88e6xxx: disable ATU violation + +--- + drivers/net/dsa/mv88e6xxx/chip.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -3461,6 +3461,9 @@ static int mv88e6xxx_setup_port(struct m + else + reg = 1 << port; + ++ /* Disable ATU member violation interrupt */ ++ reg |= MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG; ++ + err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, + reg); + if (err) diff --git a/target/linux/generic/hack-6.1/720-net-phy-add-aqr-phys.patch b/target/linux/generic/hack-6.1/720-net-phy-add-aqr-phys.patch new file mode 100644 index 000000000..fd2687d8b --- /dev/null +++ b/target/linux/generic/hack-6.1/720-net-phy-add-aqr-phys.patch @@ -0,0 +1,120 @@ +From: Birger Koblitz +Date: Sun, 5 Sep 2021 15:13:10 +0200 +Subject: [PATCH] kernel: Add AQR113C and AQR813 support + +This hack adds support for the Aquantia 4th generation, 10GBit +PHYs AQR113C and AQR813. + +Signed-off-by: Birger Koblitz + +--- a/drivers/net/phy/aquantia_main.c ++++ b/drivers/net/phy/aquantia_main.c +@@ -23,6 +23,7 @@ + #define PHY_ID_AQCS109 0x03a1b5c2 + #define PHY_ID_AQR405 0x03a1b4b0 + #define PHY_ID_AQR113C 0x31c31c12 ++#define PHY_ID_AQR813 0x31c31cb2 + + #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 + #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) +@@ -415,6 +416,49 @@ static int aqr107_read_rate(struct phy_d + return 0; + } + ++static int aqr113c_read_status(struct phy_device *phydev) ++{ ++ int val, ret; ++ ++ ret = aqr_read_status(phydev); ++ if (ret) ++ return ret; ++ ++ if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE) ++ return 0; ++ ++ // On AQR113C, the speed returned by aqr_read_status is wrong ++ aqr107_read_rate(phydev); ++ ++ val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS); ++ if (val < 0) ++ return val; ++ ++ switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) { ++ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR: ++ phydev->interface = PHY_INTERFACE_MODE_10GKR; ++ break; ++ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI: ++ phydev->interface = PHY_INTERFACE_MODE_10GBASER; ++ break; ++ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII: ++ phydev->interface = PHY_INTERFACE_MODE_USXGMII; ++ break; ++ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII: ++ phydev->interface = PHY_INTERFACE_MODE_SGMII; ++ break; ++ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII: ++ phydev->interface = PHY_INTERFACE_MODE_2500BASEX; ++ break; ++ default: ++ phydev->interface = PHY_INTERFACE_MODE_NA; ++ break; ++ } ++ ++ /* Read downshifted rate from vendor register */ ++ return aqr107_read_rate(phydev); ++} ++ + static int aqr107_read_status(struct phy_device *phydev) + { + int val, ret; +@@ -554,7 +598,7 @@ static void aqr107_chip_info(struct phy_ + build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val); + prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val); + +- phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n", ++ phydev_info(phydev, "FW %u.%u, Build %u, Provisioning %u\n", + fw_major, fw_minor, build_id, prov_id); + } + +@@ -809,7 +853,7 @@ static struct phy_driver aqr_driver[] = + .config_aneg = aqr_config_aneg, + .config_intr = aqr_config_intr, + .handle_interrupt = aqr_handle_interrupt, +- .read_status = aqr107_read_status, ++ .read_status = aqr113c_read_status, + .get_tunable = aqr107_get_tunable, + .set_tunable = aqr107_set_tunable, + .suspend = aqr107_suspend, +@@ -819,6 +863,24 @@ static struct phy_driver aqr_driver[] = + .get_stats = aqr107_get_stats, + .link_change_notify = aqr107_link_change_notify, + }, ++{ ++ PHY_ID_MATCH_MODEL(PHY_ID_AQR813), ++ .name = "Aquantia AQR813", ++ .probe = aqr107_probe, ++ .config_init = aqr107_config_init, ++ .config_aneg = aqr_config_aneg, ++ .config_intr = aqr_config_intr, ++ .handle_interrupt = aqr_handle_interrupt, ++ .read_status = aqr113c_read_status, ++ .get_tunable = aqr107_get_tunable, ++ .set_tunable = aqr107_set_tunable, ++ .suspend = aqr107_suspend, ++ .resume = aqr107_resume, ++ .get_sset_count = aqr107_get_sset_count, ++ .get_strings = aqr107_get_strings, ++ .get_stats = aqr107_get_stats, ++ .link_change_notify = aqr107_link_change_notify, ++}, + }; + + module_phy_driver(aqr_driver); +@@ -832,6 +894,7 @@ static struct mdio_device_id __maybe_unu + { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, ++ { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, + { } + }; + diff --git a/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch new file mode 100644 index 000000000..2470738e6 --- /dev/null +++ b/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch @@ -0,0 +1,167 @@ +From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Fri, 7 Jul 2017 17:25:00 +0200 +Subject: net: add packet mangeling + +ar8216 switches have a hardware bug, which renders normal 802.1q support +unusable. Packet mangling is required to fix up the vlan for incoming +packets. + +Signed-off-by: Felix Fietkau +--- + include/linux/netdevice.h | 11 +++++++++++ + include/linux/skbuff.h | 14 ++++---------- + net/Kconfig | 6 ++++++ + net/core/dev.c | 20 +++++++++++++++----- + net/core/skbuff.c | 17 +++++++++++++++++ + net/ethernet/eth.c | 6 ++++++ + 6 files changed, 59 insertions(+), 15 deletions(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1695,6 +1695,7 @@ enum netdev_priv_flags { + IFF_LIVE_RENAME_OK = 1<<30, + IFF_TX_SKB_NO_LINEAR = BIT_ULL(31), + IFF_CHANGE_PROTO_DOWN = BIT_ULL(32), ++ IFF_NO_IP_ALIGN = BIT_ULL(33), + }; + + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN +@@ -1729,6 +1730,7 @@ enum netdev_priv_flags { + #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER + #define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK + #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR ++#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN + + /* Specifies the type of the struct net_device::ml_priv pointer */ + enum netdev_ml_priv_type { +@@ -2097,6 +2099,11 @@ struct net_device { + const struct tlsdev_ops *tlsdev_ops; + #endif + ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb); ++ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb); ++#endif ++ + const struct header_ops *header_ops; + + unsigned char operstate; +@@ -2172,6 +2179,10 @@ struct net_device { + struct mctp_dev __rcu *mctp_ptr; + #endif + ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ void *phy_ptr; /* PHY device specific data */ ++#endif ++ + /* + * Cache lines mostly used on receive path (including eth_type_trans()) + */ +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -3021,6 +3021,10 @@ static inline int pskb_trim(struct sk_bu + return (len < skb->len) ? __pskb_trim(skb, len) : 0; + } + ++extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, ++ unsigned int length, gfp_t gfp); ++ ++ + /** + * pskb_trim_unique - remove end from a paged unique (not cloned) buffer + * @skb: buffer to alter +@@ -3170,16 +3174,6 @@ static inline struct sk_buff *dev_alloc_ + } + + +-static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, +- unsigned int length, gfp_t gfp) +-{ +- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); +- +- if (NET_IP_ALIGN && skb) +- skb_reserve(skb, NET_IP_ALIGN); +- return skb; +-} +- + static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, + unsigned int length) + { +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -26,6 +26,12 @@ menuconfig NET + + if NET + ++config ETHERNET_PACKET_MANGLE ++ bool ++ help ++ This option can be selected by phy drivers that need to mangle ++ packets going in or out of an ethernet device. ++ + config WANT_COMPAT_NETLINK_MESSAGES + bool + help +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3585,6 +3585,11 @@ static int xmit_one(struct sk_buff *skb, + if (dev_nit_active(dev)) + dev_queue_xmit_nit(skb, dev); + ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb))) ++ return NETDEV_TX_OK; ++#endif ++ + len = skb->len; + trace_net_dev_start_xmit(skb, dev); + rc = netdev_start_xmit(skb, dev, txq, more); +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -707,6 +708,22 @@ skb_fail: + } + EXPORT_SYMBOL(__napi_alloc_skb); + ++struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, ++ unsigned int length, gfp_t gfp) ++{ ++ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); ++ ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN)) ++ return skb; ++#endif ++ ++ if (NET_IP_ALIGN && skb) ++ skb_reserve(skb, NET_IP_ALIGN); ++ return skb; ++} ++EXPORT_SYMBOL(__netdev_alloc_skb_ip_align); ++ + void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, + int size, unsigned int truesize) + { +--- a/net/ethernet/eth.c ++++ b/net/ethernet/eth.c +@@ -171,6 +171,12 @@ __be16 eth_type_trans(struct sk_buff *sk + const struct ethhdr *eth; + + skb->dev = dev; ++ ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ if (dev->eth_mangle_rx) ++ dev->eth_mangle_rx(dev, skb); ++#endif ++ + skb_reset_mac_header(skb); + + eth = (struct ethhdr *)skb->data; diff --git a/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch b/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch new file mode 100644 index 000000000..77b190464 --- /dev/null +++ b/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch @@ -0,0 +1,148 @@ +From 5f62951fba63a9f9cfff564209426bdea5fcc371 Mon Sep 17 00:00:00 2001 +From: Alex Marginean +Date: Tue, 27 Aug 2019 15:16:56 +0300 +Subject: [PATCH] drivers: net: phy: aquantia: enable AQR112 and AQR412 + +Adds support for AQR112 and AQR412 which is mostly based on existing code +with the addition of code configuring the protocol on system side. +This allows changing the system side protocol without having to deploy a +different firmware on the PHY. + +Signed-off-by: Alex Marginean +--- + drivers/net/phy/aquantia_main.c | 88 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 88 insertions(+) + +--- a/drivers/net/phy/aquantia_main.c ++++ b/drivers/net/phy/aquantia_main.c +@@ -24,6 +24,8 @@ + #define PHY_ID_AQR405 0x03a1b4b0 + #define PHY_ID_AQR113C 0x31c31c12 + #define PHY_ID_AQR813 0x31c31cb2 ++#define PHY_ID_AQR112 0x03a1b662 ++#define PHY_ID_AQR412 0x03a1b712 + + #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 + #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) +@@ -151,6 +153,29 @@ + #define AQR107_OP_IN_PROG_SLEEP 1000 + #define AQR107_OP_IN_PROG_TIMEOUT 100000 + ++/* registers in MDIO_MMD_VEND1 region */ ++#define AQUANTIA_VND1_GLOBAL_SC 0x000 ++#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb) ++ ++/* global start rate, the protocol associated with this speed is used by default ++ * on SI. ++ */ ++#define AQUANTIA_VND1_GSTART_RATE 0x31a ++#define AQUANTIA_VND1_GSTART_RATE_OFF 0 ++#define AQUANTIA_VND1_GSTART_RATE_100M 1 ++#define AQUANTIA_VND1_GSTART_RATE_1G 2 ++#define AQUANTIA_VND1_GSTART_RATE_10G 3 ++#define AQUANTIA_VND1_GSTART_RATE_2_5G 4 ++#define AQUANTIA_VND1_GSTART_RATE_5G 5 ++ ++/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */ ++#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b ++#define AQUANTIA_VND1_GSYSCFG_100M 0 ++#define AQUANTIA_VND1_GSYSCFG_1G 1 ++#define AQUANTIA_VND1_GSYSCFG_2_5G 2 ++#define AQUANTIA_VND1_GSYSCFG_5G 3 ++#define AQUANTIA_VND1_GSYSCFG_10G 4 ++ + struct aqr107_hw_stat { + const char *name; + int reg; +@@ -282,6 +307,51 @@ static int aqr_config_aneg(struct phy_de + return genphy_c45_check_and_restart_aneg(phydev, changed); + } + ++static struct { ++ u16 syscfg; ++ int cnt; ++ u16 start_rate; ++} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = { ++ [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G, ++ AQUANTIA_VND1_GSTART_RATE_1G}, ++ [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G, ++ AQUANTIA_VND1_GSTART_RATE_2_5G}, ++ [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G, ++ AQUANTIA_VND1_GSTART_RATE_10G}, ++ [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G, ++ AQUANTIA_VND1_GSTART_RATE_10G}, ++}; ++ ++/* Sets up protocol on system side before calling aqr_config_aneg */ ++static int aqr_config_aneg_set_prot(struct phy_device *phydev) ++{ ++ int if_type = phydev->interface; ++ int i; ++ ++ if (!aquantia_syscfg[if_type].cnt) ++ return 0; ++ ++ /* set PHY in low power mode so we can configure protocols */ ++ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, ++ AQUANTIA_VND1_GLOBAL_SC_LP); ++ mdelay(10); ++ ++ /* set the default rate to enable the SI link */ ++ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, ++ aquantia_syscfg[if_type].start_rate); ++ ++ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) ++ phy_write_mmd(phydev, MDIO_MMD_VEND1, ++ AQUANTIA_VND1_GSYSCFG_BASE + i, ++ aquantia_syscfg[if_type].syscfg); ++ ++ /* wake PHY back up */ ++ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); ++ mdelay(10); ++ ++ return aqr_config_aneg(phydev); ++} ++ + static int aqr_config_intr(struct phy_device *phydev) + { + bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; +@@ -881,6 +951,30 @@ static struct phy_driver aqr_driver[] = + .get_stats = aqr107_get_stats, + .link_change_notify = aqr107_link_change_notify, + }, ++{ ++ PHY_ID_MATCH_MODEL(PHY_ID_AQR112), ++ .name = "Aquantia AQR112", ++ .probe = aqr107_probe, ++ .config_aneg = aqr_config_aneg_set_prot, ++ .config_intr = aqr_config_intr, ++ .handle_interrupt = aqr_handle_interrupt, ++ .read_status = aqr107_read_status, ++ .get_sset_count = aqr107_get_sset_count, ++ .get_strings = aqr107_get_strings, ++ .get_stats = aqr107_get_stats, ++}, ++{ ++ PHY_ID_MATCH_MODEL(PHY_ID_AQR412), ++ .name = "Aquantia AQR412", ++ .probe = aqr107_probe, ++ .config_aneg = aqr_config_aneg_set_prot, ++ .config_intr = aqr_config_intr, ++ .handle_interrupt = aqr_handle_interrupt, ++ .read_status = aqr107_read_status, ++ .get_sset_count = aqr107_get_sset_count, ++ .get_strings = aqr107_get_strings, ++ .get_stats = aqr107_get_stats, ++}, + }; + + module_phy_driver(aqr_driver); +@@ -895,6 +989,8 @@ static struct mdio_device_id __maybe_unu + { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, ++ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) }, ++ { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) }, + { } + }; + diff --git a/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch b/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch new file mode 100644 index 000000000..8e204cb14 --- /dev/null +++ b/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch @@ -0,0 +1,34 @@ +From 5f008cb22f60da4e10375f22266c1a4e20b1252e Mon Sep 17 00:00:00 2001 +From: Alex Marginean +Date: Fri, 20 Sep 2019 18:22:52 +0300 +Subject: [PATCH] drivers: net: phy: aquantia: fix system side protocol + misconfiguration + +Do not set up protocols for speeds that are not supported by FW. Enabling +these protocols leads to link issues on system side. + +Signed-off-by: Alex Marginean +--- + drivers/net/phy/aquantia_main.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/aquantia_main.c ++++ b/drivers/net/phy/aquantia_main.c +@@ -340,10 +340,16 @@ static int aqr_config_aneg_set_prot(stru + phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, + aquantia_syscfg[if_type].start_rate); + +- for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) ++ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) { ++ u16 reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ++ AQUANTIA_VND1_GSYSCFG_BASE + i); ++ if (!reg) ++ continue; ++ + phy_write_mmd(phydev, MDIO_MMD_VEND1, + AQUANTIA_VND1_GSYSCFG_BASE + i, + aquantia_syscfg[if_type].syscfg); ++ } + + /* wake PHY back up */ + phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); diff --git a/target/linux/generic/hack-6.1/724-net-phy-aquantia-Add-AQR113-driver-support.patch b/target/linux/generic/hack-6.1/724-net-phy-aquantia-Add-AQR113-driver-support.patch new file mode 100644 index 000000000..0a1e97062 --- /dev/null +++ b/target/linux/generic/hack-6.1/724-net-phy-aquantia-Add-AQR113-driver-support.patch @@ -0,0 +1,43 @@ +From 2e677e4ae8f8330f68013163b060d0fda3a43095 Mon Sep 17 00:00:00 2001 +From: "Langer, Thomas" +Date: Fri, 9 Jul 2021 17:36:46 +0200 +Subject: [PATCH] PONRTSYS-8842: aquantia: Add AQR113 driver support + +Add a new entry for AQR113 PHY_ID +--- + drivers/net/phy/aquantia_main.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/net/phy/aquantia_main.c ++++ b/drivers/net/phy/aquantia_main.c +@@ -26,6 +26,7 @@ + #define PHY_ID_AQR813 0x31c31cb2 + #define PHY_ID_AQR112 0x03a1b662 + #define PHY_ID_AQR412 0x03a1b712 ++#define PHY_ID_AQR113 0x31c31c40 + + #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 + #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) +@@ -981,6 +982,14 @@ static struct phy_driver aqr_driver[] = + .get_strings = aqr107_get_strings, + .get_stats = aqr107_get_stats, + }, ++{ ++ PHY_ID_MATCH_MODEL(PHY_ID_AQR113), ++ .name = "Aquantia AQR113", ++ .config_aneg = aqr_config_aneg, ++ .config_intr = aqr_config_intr, ++ .handle_interrupt = aqr_handle_interrupt, ++ .read_status = aqr107_read_status, ++}, + }; + + module_phy_driver(aqr_driver); +@@ -997,6 +1006,7 @@ static struct mdio_device_id __maybe_unu + { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) }, ++ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, + { } + }; + diff --git a/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch b/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch new file mode 100644 index 000000000..654fea566 --- /dev/null +++ b/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch @@ -0,0 +1,63 @@ +From 3b92ee7b7899b6beffb2b484c58326e36612a873 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Thu, 23 Dec 2021 14:52:56 +0000 +Subject: [PATCH] net: phy: aquantia: add PHY_ID for AQR112R + +As advised by Ian Chang this PHY is used in Puzzle devices. + +Signed-off-by: Daniel Golle +--- + drivers/net/phy/aquantia_main.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/net/phy/aquantia_main.c ++++ b/drivers/net/phy/aquantia_main.c +@@ -27,6 +27,8 @@ + #define PHY_ID_AQR112 0x03a1b662 + #define PHY_ID_AQR412 0x03a1b712 + #define PHY_ID_AQR113 0x31c31c40 ++#define PHY_ID_AQR112C 0x03a1b790 ++#define PHY_ID_AQR112R 0x31c31d12 + + #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 + #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) +@@ -990,6 +992,30 @@ static struct phy_driver aqr_driver[] = + .handle_interrupt = aqr_handle_interrupt, + .read_status = aqr107_read_status, + }, ++{ ++ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C), ++ .name = "Aquantia AQR112C", ++ .probe = aqr107_probe, ++ .config_aneg = aqr_config_aneg_set_prot, ++ .config_intr = aqr_config_intr, ++ .handle_interrupt = aqr_handle_interrupt, ++ .read_status = aqr107_read_status, ++ .get_sset_count = aqr107_get_sset_count, ++ .get_strings = aqr107_get_strings, ++ .get_stats = aqr107_get_stats, ++}, ++{ ++ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R), ++ .name = "Aquantia AQR112R", ++ .probe = aqr107_probe, ++ .config_aneg = aqr_config_aneg_set_prot, ++ .config_intr = aqr_config_intr, ++ .handle_interrupt = aqr_handle_interrupt, ++ .read_status = aqr107_read_status, ++ .get_sset_count = aqr107_get_sset_count, ++ .get_strings = aqr107_get_strings, ++ .get_stats = aqr107_get_stats, ++}, + }; + + module_phy_driver(aqr_driver); +@@ -1007,6 +1033,8 @@ static struct mdio_device_id __maybe_unu + { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) }, + { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, ++ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) }, ++ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) }, + { } + }; + diff --git a/target/linux/generic/hack-6.0/760-net-usb-r8152-add-LED-configuration-from-OF.patch b/target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch similarity index 87% rename from target/linux/generic/hack-6.0/760-net-usb-r8152-add-LED-configuration-from-OF.patch rename to target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch index db471b4f0..91ee2b82b 100644 --- a/target/linux/generic/hack-6.0/760-net-usb-r8152-add-LED-configuration-from-OF.patch +++ b/target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch @@ -22,7 +22,7 @@ Signed-off-by: David Bauer #include #include #include -@@ -6866,6 +6867,22 @@ static void rtl_tally_reset(struct r8152 +@@ -6871,6 +6872,22 @@ static void rtl_tally_reset(struct r8152 ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); } @@ -45,7 +45,7 @@ Signed-off-by: David Bauer static void r8152b_init(struct r8152 *tp) { u32 ocp_data; -@@ -6907,6 +6924,8 @@ static void r8152b_init(struct r8152 *tp +@@ -6912,6 +6929,8 @@ static void r8152b_init(struct r8152 *tp ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); @@ -54,7 +54,7 @@ Signed-off-by: David Bauer } static void r8153_init(struct r8152 *tp) -@@ -7047,6 +7066,8 @@ static void r8153_init(struct r8152 *tp) +@@ -7052,6 +7071,8 @@ static void r8153_init(struct r8152 *tp) tp->coalesce = COALESCE_SLOW; break; } @@ -63,7 +63,7 @@ Signed-off-by: David Bauer } static void r8153b_init(struct r8152 *tp) -@@ -7129,6 +7150,8 @@ static void r8153b_init(struct r8152 *tp +@@ -7134,6 +7155,8 @@ static void r8153b_init(struct r8152 *tp rtl_tally_reset(tp); tp->coalesce = 15000; /* 15 us */ diff --git a/target/linux/generic/hack-6.0/761-dt-bindings-net-add-RTL8152-binding-documentation.patch b/target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch similarity index 100% rename from target/linux/generic/hack-6.0/761-dt-bindings-net-add-RTL8152-binding-documentation.patch rename to target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch diff --git a/target/linux/generic/hack-6.0/773-bgmac-add-srab-switch.patch b/target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch similarity index 98% rename from target/linux/generic/hack-6.0/773-bgmac-add-srab-switch.patch rename to target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch index 076051b5b..63903e267 100644 --- a/target/linux/generic/hack-6.0/773-bgmac-add-srab-switch.patch +++ b/target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch @@ -55,7 +55,7 @@ Signed-off-by: Hauke Mehrtens net_dev->max_mtu = BGMAC_RX_MAX_FRAME_SIZE - ETH_FCS_LEN; + if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) { -+ bgmac_b53_pdata.regs = ioremap_nocache(0x18007000, 0x1000); ++ bgmac_b53_pdata.regs = ioremap(0x18007000, 0x1000); + + err = platform_device_register(&bgmac_b53_dev); + if (!err) diff --git a/target/linux/generic/hack-6.0/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch similarity index 83% rename from target/linux/generic/hack-6.0/780-usb-net-MeigLink_modem_support.patch rename to target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch index e10ffa844..0ff8b96e4 100644 --- a/target/linux/generic/hack-6.0/780-usb-net-MeigLink_modem_support.patch +++ b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch @@ -1,3 +1,13 @@ +From f81700b6bb2eda3756247bce472d8eaf6f466f61 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:49:26 +0200 +Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support + +--- + drivers/net/usb/qmi_wwan.c | 1 + + drivers/usb/serial/option.c | 7 +++++++ + 2 files changed, 8 insertions(+) + --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1088,6 +1088,7 @@ static const struct usb_device_id produc diff --git a/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch b/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch new file mode 100644 index 000000000..e109d0660 --- /dev/null +++ b/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch @@ -0,0 +1,63 @@ +From 7cc39a6bedbd85f3ff7e16845f310e4ce8d9833f Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 6 Sep 2022 00:31:19 +0100 +Subject: [PATCH] net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module +To: netdev@vger.kernel.org, + linux-kernel@vger.kernel.org, + Russell King , + Andrew Lunn , + Heiner Kallweit +Cc: David S. Miller , + Eric Dumazet , + Jakub Kicinski , + Paolo Abeni , + Josef Schlehofer + +This copper module comes with broken TX_FAULT indicator which must be +ignored for it to work. Implement ignoring TX_FAULT state bit also +during reset/insertion and mute the warning telling the user that the +module indicates TX_FAULT. + +Co-authored-by: Josef Schlehofer +Signed-off-by: Daniel Golle +--- + drivers/net/phy/sfp.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -394,6 +394,9 @@ static const struct sfp_quirk sfp_quirks + SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex, + sfp_fixup_ignore_tx_fault), + ++ // OEM SFP-GE-T is 1000Base-T module ++ SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault), ++ + // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report + // 2500MBd NRZ in their EEPROM + SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex), +@@ -2328,7 +2331,8 @@ static void sfp_sm_main(struct sfp *sfp, + * or t_start_up, so assume there is a fault. + */ + sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT, +- sfp->sm_fault_retries == N_FAULT_INIT); ++ !sfp->tx_fault_ignore && ++ (sfp->sm_fault_retries == N_FAULT_INIT)); + } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { + init_done: + /* Create mdiobus and start trying for PHY */ +@@ -2557,10 +2561,12 @@ static void sfp_check_state(struct sfp * + mutex_lock(&sfp->st_mutex); + state = sfp_get_state(sfp); + changed = state ^ sfp->state; +- if (sfp->tx_fault_ignore) ++ if (sfp->tx_fault_ignore) { + changed &= SFP_F_PRESENT | SFP_F_LOS; +- else ++ state &= ~SFP_F_TX_FAULT; ++ } else { + changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT; ++ } + + for (i = 0; i < GPIO_MAX; i++) + if (changed & BIT(i)) diff --git a/target/linux/generic/hack-6.0/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch similarity index 96% rename from target/linux/generic/hack-6.0/800-GPIO-add-named-gpio-exports.patch rename to target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch index 8894874ed..658d9c380 100644 --- a/target/linux/generic/hack-6.0/800-GPIO-add-named-gpio-exports.patch +++ b/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch @@ -15,7 +15,7 @@ Signed-off-by: John Crispin #include "gpiolib.h" #include "gpiolib-of.h" -@@ -1066,3 +1068,72 @@ void of_gpio_dev_init(struct gpio_chip * +@@ -1030,3 +1032,72 @@ void of_gpio_dev_init(struct gpio_chip * else gc->of_node = gdev->dev.of_node; } @@ -105,7 +105,7 @@ Signed-off-by: John Crispin { --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h -@@ -728,6 +728,7 @@ static inline struct gpio_desc *acpi_get +@@ -715,6 +715,7 @@ static inline struct gpio_desc *acpi_get #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) @@ -113,7 +113,7 @@ Signed-off-by: John Crispin int gpiod_export(struct gpio_desc *desc, bool direction_may_change); int gpiod_export_link(struct device *dev, const char *name, struct gpio_desc *desc); -@@ -735,6 +736,13 @@ void gpiod_unexport(struct gpio_desc *de +@@ -722,6 +723,13 @@ void gpiod_unexport(struct gpio_desc *de #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ diff --git a/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch b/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch new file mode 100644 index 000000000..dd51fdd2c --- /dev/null +++ b/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch @@ -0,0 +1,175 @@ +From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sat, 8 Jul 2017 08:16:31 +0200 +Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS + +Signed-off-by: Felix Fietkau +--- + net/Kconfig | 3 +++ + net/core/Makefile | 3 ++- + net/core/sock.c | 2 ++ + net/ipv4/Kconfig | 1 + + net/netlink/Kconfig | 1 + + net/packet/Kconfig | 1 + + net/unix/Kconfig | 1 + + 7 files changed, 11 insertions(+), 1 deletion(-) + +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -104,6 +104,9 @@ source "net/mptcp/Kconfig" + + endif # if INET + ++config SOCK_DIAG ++ bool ++ + config NETWORK_SECMARK + bool "Security Marking" + help +--- a/net/core/Makefile ++++ b/net/core/Makefile +@@ -11,11 +11,12 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core. + + obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ + neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ +- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ ++ dev_ioctl.o tso.o sock_reuseport.o \ + fib_notifier.o xdp.o flow_offload.o gro.o + + obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o + ++obj-$(CONFIG_SOCK_DIAG) += sock_diag.o + obj-y += net-sysfs.o + obj-$(CONFIG_PAGE_POOL) += page_pool.o + obj-$(CONFIG_PROC_FS) += net-procfs.o +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -114,6 +114,7 @@ + #include + #include + #include ++#include + + #include + +@@ -145,6 +146,7 @@ + + static DEFINE_MUTEX(proto_list_mutex); + static LIST_HEAD(proto_list); ++DEFINE_COOKIE(sock_cookie); + + static void sock_def_write_space_wfree(struct sock *sk); + static void sock_def_write_space(struct sock *sk); +@@ -582,6 +584,18 @@ discard_and_relse: + } + EXPORT_SYMBOL(__sk_receive_skb); + ++u64 __sock_gen_cookie(struct sock *sk) ++{ ++ while (1) { ++ u64 res = atomic64_read(&sk->sk_cookie); ++ ++ if (res) ++ return res; ++ res = gen_cookie_next(&sock_cookie); ++ atomic64_cmpxchg(&sk->sk_cookie, 0, res); ++ } ++} ++ + INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *, + u32)); + INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *, +@@ -2172,9 +2186,11 @@ static void __sk_free(struct sock *sk) + if (likely(sk->sk_net_refcnt)) + sock_inuse_add(sock_net(sk), -1); + ++#ifdef CONFIG_SOCK_DIAG + if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk))) + sock_diag_broadcast_destroy(sk); + else ++#endif + sk_destruct(sk); + } + +--- a/net/core/sock_diag.c ++++ b/net/core/sock_diag.c +@@ -12,7 +12,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -21,20 +20,6 @@ static int (*inet_rcv_compat)(struct sk_ + static DEFINE_MUTEX(sock_diag_table_mutex); + static struct workqueue_struct *broadcast_wq; + +-DEFINE_COOKIE(sock_cookie); +- +-u64 __sock_gen_cookie(struct sock *sk) +-{ +- while (1) { +- u64 res = atomic64_read(&sk->sk_cookie); +- +- if (res) +- return res; +- res = gen_cookie_next(&sock_cookie); +- atomic64_cmpxchg(&sk->sk_cookie, 0, res); +- } +-} +- + int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie) + { + u64 res; +--- a/net/ipv4/Kconfig ++++ b/net/ipv4/Kconfig +@@ -423,6 +423,7 @@ config INET_TUNNEL + + config INET_DIAG + tristate "INET: socket monitoring interface" ++ select SOCK_DIAG + default y + help + Support for INET (TCP, DCCP, etc) socket monitoring interface used by +--- a/net/netlink/Kconfig ++++ b/net/netlink/Kconfig +@@ -5,6 +5,7 @@ + + config NETLINK_DIAG + tristate "NETLINK: socket monitoring interface" ++ select SOCK_DIAG + default n + help + Support for NETLINK socket monitoring interface used by the ss tool. +--- a/net/netlink/genetlink.c ++++ b/net/netlink/genetlink.c +@@ -380,8 +380,6 @@ static int genl_validate_ops(const struc + genl_get_cmd_by_index(i, family, &op); + if (op.dumpit == NULL && op.doit == NULL) + return -EINVAL; +- if (WARN_ON(op.cmd >= family->resv_start_op && op.validate)) +- return -EINVAL; + for (j = i + 1; j < genl_get_cmd_cnt(family); j++) { + struct genl_ops op2; + +--- a/net/packet/Kconfig ++++ b/net/packet/Kconfig +@@ -19,6 +19,7 @@ config PACKET + config PACKET_DIAG + tristate "Packet: sockets monitoring interface" + depends on PACKET ++ select SOCK_DIAG + default n + help + Support for PF_PACKET sockets monitoring interface used by the ss tool. +--- a/net/unix/Kconfig ++++ b/net/unix/Kconfig +@@ -33,6 +33,7 @@ config AF_UNIX_OOB + config UNIX_DIAG + tristate "UNIX: socket monitoring interface" + depends on UNIX ++ select SOCK_DIAG + default n + help + Support for UNIX socket monitoring interface used by the ss tool. diff --git a/target/linux/generic/hack-6.0/902-debloat_proc.patch b/target/linux/generic/hack-6.1/902-debloat_proc.patch similarity index 96% rename from target/linux/generic/hack-6.0/902-debloat_proc.patch rename to target/linux/generic/hack-6.1/902-debloat_proc.patch index 2f6e483a9..6ca18ab39 100644 --- a/target/linux/generic/hack-6.0/902-debloat_proc.patch +++ b/target/linux/generic/hack-6.1/902-debloat_proc.patch @@ -40,7 +40,7 @@ Signed-off-by: Felix Fietkau return 0; --- a/fs/proc/Kconfig +++ b/fs/proc/Kconfig -@@ -100,6 +100,11 @@ config PROC_CHILDREN +@@ -101,6 +101,11 @@ config PROC_CHILDREN Say Y if you are running any user-space software which takes benefit from this interface. For example, rkt is such a piece of software. @@ -135,7 +135,7 @@ Signed-off-by: Felix Fietkau do { \ --- a/ipc/msg.c +++ b/ipc/msg.c -@@ -1350,6 +1350,9 @@ void __init msg_init(void) +@@ -1370,6 +1370,9 @@ void __init msg_init(void) { msg_init_ns(&init_ipc_ns); @@ -235,7 +235,7 @@ Signed-off-by: Felix Fietkau if (!pe) --- a/mm/vmalloc.c +++ b/mm/vmalloc.c -@@ -4160,6 +4160,8 @@ static const struct seq_operations vmall +@@ -4177,6 +4177,8 @@ static const struct seq_operations vmall static int __init proc_vmalloc_init(void) { @@ -246,9 +246,9 @@ Signed-off-by: Felix Fietkau &vmalloc_op, --- a/mm/vmstat.c +++ b/mm/vmstat.c -@@ -2127,10 +2127,12 @@ void __init init_mm_internals(void) +@@ -2109,10 +2109,12 @@ void __init init_mm_internals(void) + start_shepherd_timer(); #endif - migrate_on_reclaim_init(); #ifdef CONFIG_PROC_FS - proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); - proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); @@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -4005,6 +4005,8 @@ static __net_initdata struct pernet_oper +@@ -4077,6 +4077,8 @@ static __net_initdata struct pernet_oper static int __init proto_init(void) { @@ -341,7 +341,7 @@ Signed-off-by: Felix Fietkau --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c -@@ -3029,11 +3029,13 @@ static const struct seq_operations fib_r +@@ -3031,11 +3031,13 @@ static const struct seq_operations fib_r int __net_init fib_proc_init(struct net *net) { @@ -357,7 +357,7 @@ Signed-off-by: Felix Fietkau fib_triestat_seq_show, NULL)) goto out2; -@@ -3044,17 +3046,21 @@ int __net_init fib_proc_init(struct net +@@ -3046,17 +3048,21 @@ int __net_init fib_proc_init(struct net return 0; out3: diff --git a/target/linux/generic/hack-6.0/904-debloat_dma_buf.patch b/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch similarity index 91% rename from target/linux/generic/hack-6.0/904-debloat_dma_buf.patch rename to target/linux/generic/hack-6.1/904-debloat_dma_buf.patch index 6e03eb808..d4ea2eb8a 100644 --- a/target/linux/generic/hack-6.0/904-debloat_dma_buf.patch +++ b/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch @@ -50,7 +50,7 @@ Signed-off-by: Felix Fietkau +dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o +dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o +dma-buf-objs-$(CONFIG_UDMABUF) += udmabuf.o -+dma-buf-objs-$(CONFIG_DMABUF_SYSFS_STATS) += udmabuf.o ++dma-buf-objs-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o dmabuf_selftests-y := \ selftest.o \ @@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau +dma-shared-buffer-objs := $(dma-buf-objs-y) --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c -@@ -1578,4 +1578,5 @@ static void __exit dma_buf_deinit(void) +@@ -1589,4 +1589,5 @@ static void __exit dma_buf_deinit(void) kern_unmount(dma_buf_mnt); dma_buf_uninit_sysfs_statistics(); } @@ -73,7 +73,7 @@ Signed-off-by: Felix Fietkau +MODULE_LICENSE("GPL"); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -4319,6 +4319,7 @@ int wake_up_state(struct task_struct *p, +@@ -4331,6 +4331,7 @@ int wake_up_state(struct task_struct *p, { return try_to_wake_up(p, state, 0); } @@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau * Perform scheduler related setup for a newly forked process p. --- a/fs/d_path.c +++ b/fs/d_path.c -@@ -314,6 +314,7 @@ char *dynamic_dname(struct dentry *dentr +@@ -313,6 +313,7 @@ char *dynamic_dname(char *buffer, int bu buffer += buflen - sz; return memcpy(buffer, temp, sz); } diff --git a/target/linux/generic/hack-6.0/910-kobject_uevent.patch b/target/linux/generic/hack-6.1/910-kobject_uevent.patch similarity index 100% rename from target/linux/generic/hack-6.0/910-kobject_uevent.patch rename to target/linux/generic/hack-6.1/910-kobject_uevent.patch diff --git a/target/linux/generic/hack-6.0/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch similarity index 100% rename from target/linux/generic/hack-6.0/911-kobject_add_broadcast_uevent.patch rename to target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch diff --git a/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch b/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch new file mode 100644 index 000000000..240bc1d75 --- /dev/null +++ b/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch @@ -0,0 +1,21 @@ +From e08bcbbaa52fcc41f02743fd2e62a33255ce52da Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 13:52:28 +0200 +Subject: [PATCH] of/ftd: add device tree cmdline + +--- + drivers/of/fdt.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -1172,6 +1172,9 @@ int __init early_init_dt_scan_chosen(cha + p = of_get_flat_dt_prop(node, "bootargs", &l); + if (p != NULL && l > 0) + strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); ++ p = of_get_flat_dt_prop(node, "bootargs-append", &l); ++ if (p != NULL && l > 0) ++ strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE)); + + /* + * CONFIG_CMDLINE is meant to be a default in case nothing else diff --git a/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch b/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch new file mode 100644 index 000000000..42f39197a --- /dev/null +++ b/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch @@ -0,0 +1,30 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 19 Jul 2022 06:17:48 +0200 +Subject: [PATCH] Revert "Revert "Revert "driver core: Set fw_devlink=on by + default""" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit ea718c699055c8566eb64432388a04974c43b2ea. + +With of_platform_populate() called for MTD partitions that commit breaks +probing devices which reference MTD in device tree. + +Link: https://lore.kernel.org/all/696cb2da-20b9-b3dd-46d9-de4bf91a1506@gmail.com/T/#u +Signed-off-by: RafaÅ‚ MiÅ‚ecki +--- + drivers/base/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -1606,7 +1606,7 @@ static void device_links_purge(struct de + #define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \ + DL_FLAG_PM_RUNTIME) + +-static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_ON; ++static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_PERMISSIVE; + static int __init fw_devlink_setup(char *arg) + { + if (!arg) diff --git a/target/linux/generic/hack-6.0/952-add-net-conntrack-events-support-multiple-registrant.patch b/target/linux/generic/hack-6.1/952-add-net-conntrack-events-support-multiple-registrant.patch similarity index 97% rename from target/linux/generic/hack-6.0/952-add-net-conntrack-events-support-multiple-registrant.patch rename to target/linux/generic/hack-6.1/952-add-net-conntrack-events-support-multiple-registrant.patch index 8c9cd95bb..dff53e022 100644 --- a/target/linux/generic/hack-6.0/952-add-net-conntrack-events-support-multiple-registrant.patch +++ b/target/linux/generic/hack-6.1/952-add-net-conntrack-events-support-multiple-registrant.patch @@ -123,7 +123,7 @@ Signed-off-by: Zhi Chen depends on NETFILTER_ADVANCED --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c -@@ -2803,6 +2803,10 @@ int nf_conntrack_init_net(struct net *ne +@@ -2804,6 +2804,10 @@ int nf_conntrack_init_net(struct net *ne nf_conntrack_ecache_pernet_init(net); nf_conntrack_proto_pernet_init(net); @@ -299,7 +299,7 @@ Signed-off-by: Zhi Chen void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state) --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c -@@ -712,12 +712,19 @@ static size_t ctnetlink_nlmsg_size(const +@@ -717,12 +717,19 @@ static size_t ctnetlink_nlmsg_size(const } static int @@ -319,7 +319,7 @@ Signed-off-by: Zhi Chen struct nf_conn *ct = item->ct; struct sk_buff *skb; unsigned int type; -@@ -3745,11 +3752,17 @@ static int ctnetlink_stat_exp_cpu(struct +@@ -3750,11 +3757,17 @@ static int ctnetlink_stat_exp_cpu(struct } #ifdef CONFIG_NF_CONNTRACK_EVENTS @@ -337,7 +337,7 @@ Signed-off-by: Zhi Chen static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { [IPCTNL_MSG_CT_NEW] = { -@@ -3848,8 +3861,12 @@ static int __net_init ctnetlink_net_init +@@ -3853,8 +3866,12 @@ static int __net_init ctnetlink_net_init static void ctnetlink_net_pre_exit(struct net *net) { #ifdef CONFIG_NF_CONNTRACK_EVENTS diff --git a/target/linux/generic/hack-6.0/953-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-6.1/953-net-patch-linux-kernel-to-support-shortcut-fe.patch similarity index 92% rename from target/linux/generic/hack-6.0/953-net-patch-linux-kernel-to-support-shortcut-fe.patch rename to target/linux/generic/hack-6.1/953-net-patch-linux-kernel-to-support-shortcut-fe.patch index 5737a0da7..1f6ade809 100644 --- a/target/linux/generic/hack-6.0/953-net-patch-linux-kernel-to-support-shortcut-fe.patch +++ b/target/linux/generic/hack-6.1/953-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -1,6 +1,6 @@ --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h -@@ -69,6 +69,9 @@ void brioctl_set(int (*hook)(struct net +@@ -71,6 +71,9 @@ void brioctl_set(int (*hook)(struct net int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, struct ifreq *ifr, void __user *uarg); @@ -12,7 +12,7 @@ struct list_head *br_ip_list); --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -979,6 +979,10 @@ struct sk_buff { +@@ -986,6 +986,10 @@ struct sk_buff { __u8 csum_not_inet:1; __u8 scm_io_uring:1; @@ -49,7 +49,7 @@ const struct nf_ct_event_notifier *nb); --- a/net/Kconfig +++ b/net/Kconfig -@@ -460,6 +460,9 @@ config FAILOVER +@@ -467,6 +467,9 @@ config FAILOVER migration of VMs with direct attached VFs by failing over to the paravirtual datapath when the VF is unplugged. @@ -61,8 +61,8 @@ default y --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c -@@ -774,6 +774,28 @@ void br_port_flags_change(struct net_bri - br_recalculate_neigh_suppress_enabled(br); +@@ -767,6 +767,28 @@ void br_port_flags_change(struct net_bri + br_offload_port_state(p); } +void br_dev_update_stats(struct net_device *dev, @@ -109,9 +109,9 @@ + } +#endif - len = skb->len; - trace_net_dev_start_xmit(skb, dev); -@@ -5237,6 +5245,11 @@ void netdev_rx_handler_unregister(struct + #ifdef CONFIG_ETHERNET_PACKET_MANGLE + if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb))) +@@ -5242,6 +5250,11 @@ void netdev_rx_handler_unregister(struct } EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); @@ -123,7 +123,7 @@ /* * Limit the use of PFMEMALLOC reserves to those protocols that implement * the special handling of PFMEMALLOC skbs. -@@ -5285,6 +5298,10 @@ static int __netif_receive_skb_core(stru +@@ -5290,6 +5303,10 @@ static int __netif_receive_skb_core(stru int ret = NET_RX_DROP; __be16 type; @@ -134,7 +134,7 @@ net_timestamp_check(!READ_ONCE(netdev_tstamp_prequeue), skb); trace_netif_receive_skb(skb); -@@ -5322,6 +5339,15 @@ another_round: +@@ -5327,6 +5344,15 @@ another_round: goto out; } diff --git a/target/linux/generic/hack-6.0/982-add-bcm-fullconenat-support.patch b/target/linux/generic/hack-6.1/982-add-bcm-fullconenat-support.patch similarity index 98% rename from target/linux/generic/hack-6.0/982-add-bcm-fullconenat-support.patch rename to target/linux/generic/hack-6.1/982-add-bcm-fullconenat-support.patch index 41b16c36d..446f6bba5 100644 --- a/target/linux/generic/hack-6.0/982-add-bcm-fullconenat-support.patch +++ b/target/linux/generic/hack-6.1/982-add-bcm-fullconenat-support.patch @@ -10,7 +10,7 @@ struct masq_dev_work { struct work_struct work; -@@ -23,6 +26,129 @@ static DEFINE_MUTEX(masq_mutex); +@@ -24,6 +27,129 @@ static DEFINE_MUTEX(masq_mutex); static unsigned int masq_refcnt __read_mostly; static atomic_t masq_worker_count __read_mostly; @@ -140,7 +140,7 @@ unsigned int nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum, const struct nf_nat_range2 *range, -@@ -60,6 +186,72 @@ nf_nat_masquerade_ipv4(struct sk_buff *s +@@ -61,6 +187,72 @@ nf_nat_masquerade_ipv4(struct sk_buff *s if (nat) nat->masq_index = out->ifindex; @@ -213,7 +213,7 @@ /* Transfer from original range. */ memset(&newrange.min_addr, 0, sizeof(newrange.min_addr)); memset(&newrange.max_addr, 0, sizeof(newrange.max_addr)); -@@ -347,6 +539,7 @@ EXPORT_SYMBOL_GPL(nf_nat_masquerade_inet +@@ -352,6 +544,7 @@ EXPORT_SYMBOL_GPL(nf_nat_masquerade_inet void nf_nat_masquerade_inet_unregister_notifiers(void) { diff --git a/target/linux/generic/hack-6.0/992-add-ndo-do-ioctl.patch b/target/linux/generic/hack-6.1/992-add-ndo-do-ioctl.patch similarity index 100% rename from target/linux/generic/hack-6.0/992-add-ndo-do-ioctl.patch rename to target/linux/generic/hack-6.1/992-add-ndo-do-ioctl.patch diff --git a/target/linux/generic/pending-6.0/101-Use-stddefs.h-instead-of-compiler.h.patch b/target/linux/generic/pending-6.0/101-Use-stddefs.h-instead-of-compiler.h.patch deleted file mode 100644 index 824b9444e..000000000 --- a/target/linux/generic/pending-6.0/101-Use-stddefs.h-instead-of-compiler.h.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/include/uapi/linux/swab.h -+++ b/include/uapi/linux/swab.h -@@ -3,7 +3,7 @@ - #define _UAPI_LINUX_SWAB_H - - #include --#include -+#include - #include - #include - diff --git a/target/linux/generic/pending-6.0/201-extra_optimization.patch b/target/linux/generic/pending-6.0/201-extra_optimization.patch deleted file mode 100644 index fa958eb04..000000000 --- a/target/linux/generic/pending-6.0/201-extra_optimization.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Felix Fietkau -Subject: Upgrade to Linux 2.6.19 - -- Includes large parts of the patch from #1021 by dpalffy -- Includes RB532 NAND driver changes by n0-1 - -[john@phrozen.org: feix will add this to his upstream queue] - -lede-commit: bff468813f78f81e36ebb2a3f4354de7365e640f -Signed-off-by: Felix Fietkau ---- - Makefile | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -759,7 +759,7 @@ KBUILD_CFLAGS += $(call cc-disable-warni - ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE - KBUILD_CFLAGS += -O2 - else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE --KBUILD_CFLAGS += -Os -+KBUILD_CFLAGS += -Os -fno-reorder-blocks -fno-tree-ch - endif - - # Tell gcc to never replace conditional load with a non-conditional one diff --git a/target/linux/generic/pending-6.0/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch b/target/linux/generic/pending-6.0/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch deleted file mode 100644 index a91f88718..000000000 --- a/target/linux/generic/pending-6.0/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch +++ /dev/null @@ -1,389 +0,0 @@ -From patchwork Tue Jun 8 04:07:19 2021 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: John Thomson -X-Patchwork-Id: 1489105 -X-Patchwork-Delegate: tudor.ambarus@gmail.com -Return-Path: - -X-Original-To: incoming@patchwork.ozlabs.org -Delivered-To: patchwork-incoming@bilbo.ozlabs.org -Authentication-Results: ozlabs.org; - spf=none (no SPF record) smtp.mailfrom=lists.infradead.org - (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; - envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; - receiver=) -Authentication-Results: ozlabs.org; - dkim=pass (2048-bit key; - secure) header.d=lists.infradead.org header.i=@lists.infradead.org - header.a=rsa-sha256 header.s=bombadil.20210309 header.b=EMabhVoR; - dkim=fail reason="signature verification failed" (2048-bit key; - unprotected) header.d=fastmail.com.au header.i=@fastmail.com.au - header.a=rsa-sha256 header.s=fm3 header.b=dLzuZ6dB; - dkim=fail reason="signature verification failed" (2048-bit key; - unprotected) header.d=messagingengine.com header.i=@messagingengine.com - header.a=rsa-sha256 header.s=fm3 header.b=nSRGsW+C; - dkim-atps=neutral -Received: from bombadil.infradead.org (bombadil.infradead.org - [IPv6:2607:7c80:54:e::133]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest - SHA256) - (No client certificate requested) - by ozlabs.org (Postfix) with ESMTPS id 4FzcFN1j1nz9sW8 - for ; Tue, 8 Jun 2021 14:09:28 +1000 (AEST) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender: - Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: - List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc - :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: - List-Owner; bh=6mUWQd71FwsINycGYY1qOhKz+ecWJVNtwDkTebG3XkA=; b=EMabhVoRE3ad89 - o3L2AgyKrs+blSofUC3hoSsQe7gi3m4si8S9HW8Z+8SsS5TufUsvGwDl80qSYGlQOytQF+1yRUWvE - 6FJ/+bqv+TwjqZFibgJ6+9OVsQN9dZ/no1R0bBXIpmrf8ORUmv58QK4ZQquaFKbyXKpFeWOC2MSv4 - H2MAhyhTU8a3gtooH6G8+KvsJEfVgh6C+aDbwxyh2UY3chHKuw1kvL6AktbfUE2xl4zxi3x3kc70B - Wi3LiJBFokxVdgnROXxTU5tI0XboWYkQV64gLuQNV4XKClcuhVpzloDK8Iok6NTd7b32a7TdEFlCS - lGKsEKmxtUlW2FpfoduA==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) - id 1lqT1r-006OAW-DX; Tue, 08 Jun 2021 04:07:51 +0000 -Received: from new1-smtp.messagingengine.com ([66.111.4.221]) - by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) - id 1lqT1l-006O9b-Fq - for linux-mtd@lists.infradead.org; Tue, 08 Jun 2021 04:07:50 +0000 -Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) - by mailnew.nyi.internal (Postfix) with ESMTP id 4456B580622; - Tue, 8 Jun 2021 00:07:42 -0400 (EDT) -Received: from mailfrontend2 ([10.202.2.163]) - by compute2.internal (MEProxy); Tue, 08 Jun 2021 00:07:42 -0400 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fastmail.com.au; - h=from:to:cc:subject:date:message-id:mime-version - :content-transfer-encoding; s=fm3; bh=ZXRH+YluM1mHCS1EWUiCY/Sg8O - LccfHe1oW5iAay6y8=; b=dLzuZ6dBYf7ZA8tWLOBFZYLi7ERsGe/4vnMXG+ovvb - dNBO0+SaFGwoqYSFrfq/TeyHfKyvxrA7+LCdopIuT4abpLHxtRwtRiafQcDYCPat - qJIqOZO+wCZC5S9Jc1OP7+t1FviGpgevqIMotci37P+RWc5u3AweMzFljZk90E8C - uorV6rXagD+OssJQzllRnAIK88+rOAC9ZyXv2gWxy4d1HSCwSWgzx2vnV9CNp918 - YC/3tiHas9krbrPIaAsdBROr7Bvoe/ShRRzruKRuvZVgg5NN90vX+/5ZjI8u04GM - p2bWCbC62CP6wlcgDaz+c/Sgr5ITd2GPENJsHfqmLRBA== -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= - messagingengine.com; h=cc:content-transfer-encoding:date:from - :message-id:mime-version:subject:to:x-me-proxy:x-me-proxy - :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; bh=ZXRH+YluM1mHCS1EW - UiCY/Sg8OLccfHe1oW5iAay6y8=; b=nSRGsW+CQ2Zx1RVpIUu8W/VD/k5P+32BW - 5k2ltd+UhI3dfldBPzHrYiOP/IJqGkNW+V+rHASacW/vFygnaZoxNjRYKnOsu+26 - wb2yK3jpl6lsNTg3N1Z4XJrYY2lf9H29DMFbhC67l0PTc050rcZk4XsKTLAlv14Q - VA4WREYSaX/4IN4O+ES4TMq0a/3gKZh6nvbbJXbsXfK0WlSHTGZtZmW3fyrqvbXa - t+R7L8vvqWvwls0pV+Sn8LeQqb7+A69w0UOnuznjkcA3sCc2YehcHbxcUEnMH+9N - bxOjmIDeg9/4X/829tUWUJiLhE5SFmQZ1P6oFtmbWoLrDz0ZJIVBw== -X-ME-Sender: - -X-ME-Received: - -X-ME-Proxy-Cause: - gggruggvucftvghtrhhoucdtuddrgeduledrfedtkedgjeduucetufdoteggodetrfdotf - fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen - uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne - cujfgurhephffvufffkffoggfgsedtkeertdertddtnecuhfhrohhmpeflohhhnhcuvfhh - ohhmshhonhcuoehgihhtsehjohhhnhhthhhomhhsohhnrdhfrghsthhmrghilhdrtghomh - drrghuqeenucggtffrrghtthgvrhhnpefffeeihfdukedtuedufeetieeuudfhhefhkefh - tefgtdeuffekffelleetveduieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmh - epmhgrihhlfhhrohhmpehgihhtsehjohhhnhhthhhomhhsohhnrdhfrghsthhmrghilhdr - tghomhdrrghu -X-ME-Proxy: - - - -Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, - 8 Jun 2021 00:07:35 -0400 (EDT) -From: John Thomson -To: Miquel Raynal , - Richard Weinberger , Vignesh Raghavendra , - Tudor Ambarus , - Michael Walle , Pratyush Yadav , - linux-mtd@lists.infradead.org -Cc: linux-kernel@vger.kernel.org, - John Thomson , - kernel test robot , Dan Carpenter -Subject: [PATCH] mtd: spi-nor: write support for minor aligned partitions -Date: Tue, 8 Jun 2021 14:07:19 +1000 -Message-Id: <20210608040719.14431-1-git@johnthomson.fastmail.com.au> -X-Mailer: git-send-email 2.31.1 -MIME-Version: 1.0 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20210607_210745_712053_67A7D864 -X-CRM114-Status: GOOD ( 26.99 ) -X-Spam-Score: -0.8 (/) -X-Spam-Report: Spam detection software, - running on the system "bombadil.infradead.org", - has NOT identified this incoming email as spam. The original - message has been attached to this so you can view it or label - similar future email. If you have any questions, see - the administrator of that system for details. - Content preview: Do not prevent writing to mtd partitions where a partition - boundary sits on a minor erasesize boundary. This addresses a FIXME that - has been present since the start of the linux git history: /* Doesn' [...] - Content analysis details: (-0.8 points, 5.0 required) - pts rule name description - ---- ---------------------- - -------------------------------------------------- - -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, - low trust [66.111.4.221 listed in list.dnswl.org] - -0.0 SPF_PASS SPF: sender matches SPF record - -0.0 SPF_HELO_PASS SPF: HELO matches SPF record - 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) - [66.111.4.221 listed in wl.mailspike.net] - -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature - 0.1 DKIM_SIGNED Message has a DKIM or DK signature, - not necessarily - valid - -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from - envelope-from domain - 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders -X-BeenThere: linux-mtd@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: Linux MTD discussion mailing list -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "linux-mtd" -Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org - -Do not prevent writing to mtd partitions where a partition boundary sits -on a minor erasesize boundary. -This addresses a FIXME that has been present since the start of the -linux git history: -/* Doesn't start on a boundary of major erase size */ -/* FIXME: Let it be writable if it is on a boundary of - * _minor_ erase size though */ - -Allow a uniform erase region spi-nor device to be configured -to use the non-uniform erase regions code path for an erase with: -CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y - -On supporting hardware (SECT_4K: majority of current SPI-NOR device) -provide the facility for an erase to use the least number -of SPI-NOR operations, as well as access to 4K erase without -requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS - -Introduce erasesize_minor to the mtd struct, -the smallest erasesize supported by the device - -On existing devices, this is useful where write support is wanted -for data on a 4K partition, such as some u-boot-env partitions, -or RouterBoot soft_config, while still netting the performance -benefits of using 64K sectors - -Performance: -time mtd erase firmware -OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length - -Without this patch -MTD_SPI_NOR_USE_4K_SECTORS=y |n -real 2m 11.66s |0m 50.86s -user 0m 0.00s |0m 0.00s -sys 1m 56.20s |0m 50.80s - -With this patch -MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y -real 0m 51.68s |0m 50.85s |2m 12.89s -user 0m 0.00s |0m 0.00s |0m 0.01s -sys 0m 46.94s |0m 50.38s |2m 12.46s - -Signed-off-by: John Thomson ---- -Have not tested on variable erase regions device. - -checkpatch does not like the printk(KERN_WARNING -these should be changed separately beforehand? - -Changes RFC -> v1: -Fix uninitialized variable smatch warning -Reported-by: kernel test robot -Reported-by: Dan Carpenter ---- - drivers/mtd/mtdpart.c | 52 ++++++++++++++++++++++++++++--------- - drivers/mtd/spi-nor/Kconfig | 10 +++++++ - drivers/mtd/spi-nor/core.c | 10 +++++-- - include/linux/mtd/mtd.h | 2 ++ - 4 files changed, 60 insertions(+), 14 deletions(-) - ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -41,10 +41,11 @@ static struct mtd_info *allocate_partiti - struct mtd_info *master = mtd_get_master(parent); - int wr_alignment = (parent->flags & MTD_NO_ERASE) ? - master->writesize : master->erasesize; -+ int wr_alignment_minor = 0; - u64 parent_size = mtd_is_partition(parent) ? - parent->part.size : parent->size; - struct mtd_info *child; -- u32 remainder; -+ u32 remainder, remainder_minor; - char *name; - u64 tmp; - -@@ -146,6 +147,7 @@ static struct mtd_info *allocate_partiti - int i, max = parent->numeraseregions; - u64 end = child->part.offset + child->part.size; - struct mtd_erase_region_info *regions = parent->eraseregions; -+ uint32_t erasesize_minor = child->erasesize; - - /* Find the first erase regions which is part of this - * partition. */ -@@ -156,15 +158,24 @@ static struct mtd_info *allocate_partiti - if (i > 0) - i--; - -- /* Pick biggest erasesize */ - for (; i < max && regions[i].offset < end; i++) { -+ /* Pick biggest erasesize */ - if (child->erasesize < regions[i].erasesize) - child->erasesize = regions[i].erasesize; -+ /* Pick smallest non-zero erasesize */ -+ if ((erasesize_minor > regions[i].erasesize) && (regions[i].erasesize > 0)) -+ erasesize_minor = regions[i].erasesize; - } -+ -+ if (erasesize_minor < child->erasesize) -+ child->erasesize_minor = erasesize_minor; -+ - BUG_ON(child->erasesize == 0); - } else { - /* Single erase size */ - child->erasesize = master->erasesize; -+ if (master->erasesize_minor) -+ child->erasesize_minor = master->erasesize_minor; - } - - /* -@@ -172,26 +183,43 @@ static struct mtd_info *allocate_partiti - * exposes several regions with different erasesize. Adjust - * wr_alignment accordingly. - */ -- if (!(child->flags & MTD_NO_ERASE)) -+ if (!(child->flags & MTD_NO_ERASE)) { - wr_alignment = child->erasesize; -+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) && child->erasesize_minor) -+ wr_alignment_minor = child->erasesize_minor; -+ } - - tmp = mtd_get_master_ofs(child, 0); - remainder = do_div(tmp, wr_alignment); - if ((child->flags & MTD_WRITEABLE) && remainder) { -- /* Doesn't start on a boundary of major erase size */ -- /* FIXME: Let it be writable if it is on a boundary of -- * _minor_ erase size though */ -- child->flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -- part->name); -+ if (wr_alignment_minor) { -+ tmp = mtd_get_master_ofs(child, 0); -+ remainder_minor = do_div(tmp, wr_alignment_minor); -+ if (remainder_minor == 0) -+ child->erasesize = child->erasesize_minor; -+ } -+ -+ if ((!wr_alignment_minor) || (wr_alignment_minor && remainder_minor != 0)) { -+ child->flags &= ~MTD_WRITEABLE; -+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -+ part->name); -+ } - } - - tmp = mtd_get_master_ofs(child, 0) + child->part.size; - remainder = do_div(tmp, wr_alignment); - if ((child->flags & MTD_WRITEABLE) && remainder) { -- child->flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -- part->name); -+ if (wr_alignment_minor) { -+ tmp = mtd_get_master_ofs(child, 0) + child->part.size; -+ remainder_minor = do_div(tmp, wr_alignment_minor); -+ if (remainder_minor == 0) -+ child->erasesize = child->erasesize_minor; -+ } -+ if ((!wr_alignment_minor) || (wr_alignment_minor && remainder_minor != 0)) { -+ child->flags &= ~MTD_WRITEABLE; -+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -+ part->name); -+ } - } - - child->size = child->part.size; ---- a/drivers/mtd/spi-nor/Kconfig -+++ b/drivers/mtd/spi-nor/Kconfig -@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR - - if MTD_SPI_NOR - -+config MTD_SPI_NOR_USE_VARIABLE_ERASE -+ bool "Disable uniform_erase to allow use of all hardware supported erasesizes" -+ depends on !MTD_SPI_NOR_USE_4K_SECTORS -+ default n -+ help -+ Allow mixed use of all hardware supported erasesizes, -+ by forcing spi_nor to use the multiple eraseregions code path. -+ For example: A 68K erase will use one 64K erase, and one 4K erase -+ on supporting hardware. -+ - config MTD_SPI_NOR_USE_4K_SECTORS - bool "Use small 4096 B erase sectors" - default y ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1048,6 +1048,8 @@ static u8 spi_nor_convert_3to4_erase(u8 - - static bool spi_nor_has_uniform_erase(const struct spi_nor *nor) - { -+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE)) -+ return false; - return !!nor->params->erase_map.uniform_erase_type; - } - -@@ -2144,6 +2146,7 @@ static int spi_nor_select_erase(struct s - { - struct spi_nor_erase_map *map = &nor->params->erase_map; - const struct spi_nor_erase_type *erase = NULL; -+ const struct spi_nor_erase_type *erase_minor = NULL; - struct mtd_info *mtd = &nor->mtd; - u32 wanted_size = nor->info->sector_size; - int i; -@@ -2176,8 +2179,9 @@ static int spi_nor_select_erase(struct s - */ - for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { - if (map->erase_type[i].size) { -- erase = &map->erase_type[i]; -- break; -+ if (!erase) -+ erase = &map->erase_type[i]; -+ erase_minor = &map->erase_type[i]; - } - } - -@@ -2185,6 +2189,8 @@ static int spi_nor_select_erase(struct s - return -EINVAL; - - mtd->erasesize = erase->size; -+ if (erase_minor && erase_minor->size < erase->size) -+ mtd->erasesize_minor = erase_minor->size; - return 0; - } - ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -238,6 +238,8 @@ struct mtd_info { - * information below if they desire - */ - uint32_t erasesize; -+ /* "Minor" (smallest) erase size supported by the whole device */ -+ uint32_t erasesize_minor; - /* Minimal writable flash unit size. In case of NOR flash it is 1 (even - * though individual bits can be cleared), in case of NAND flash it is - * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR diff --git a/target/linux/generic/pending-6.0/419-mtd-redboot-add-of_match_table-with-DT-binding.patch b/target/linux/generic/pending-6.0/419-mtd-redboot-add-of_match_table-with-DT-binding.patch deleted file mode 100644 index ade36033d..000000000 --- a/target/linux/generic/pending-6.0/419-mtd-redboot-add-of_match_table-with-DT-binding.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH] mtd: redboot: add of_match_table with DT binding -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows parsing RedBoot compatible partitions for properly described -flash device in DT. - -Signed-off-by: RafaÅ‚ MiÅ‚ecki ---- - ---- a/drivers/mtd/parsers/redboot.c -+++ b/drivers/mtd/parsers/redboot.c -@@ -305,6 +305,7 @@ nogood: - - static const struct of_device_id mtd_parser_redboot_of_match_table[] = { - { .compatible = "redboot-fis" }, -+ { .compatible = "ecoscentric,redboot-fis-partitions" }, - {}, - }; - MODULE_DEVICE_TABLE(of, mtd_parser_redboot_of_match_table); diff --git a/target/linux/generic/pending-6.0/495-mtd-core-add-get_mtd_device_by_node.patch b/target/linux/generic/pending-6.0/495-mtd-core-add-get_mtd_device_by_node.patch deleted file mode 100644 index c89969edf..000000000 --- a/target/linux/generic/pending-6.0/495-mtd-core-add-get_mtd_device_by_node.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 1bd1b740f208d1cf4071932cc51860d37266c402 Mon Sep 17 00:00:00 2001 -From: Bernhard Frauendienst -Date: Sat, 1 Sep 2018 00:30:11 +0200 -Subject: [PATCH 495/497] mtd: core: add get_mtd_device_by_node - -Add function to retrieve a mtd device by its OF node. Since drivers can -assign arbitrary names to mtd devices in the absence of a label -property, there is no other reliable way to retrieve a mtd device for a -given OF node. - -Signed-off-by: Bernhard Frauendienst -Reviewed-by: Miquel Raynal ---- - drivers/mtd/mtdcore.c | 38 ++++++++++++++++++++++++++++++++++++++ - include/linux/mtd/mtd.h | 2 ++ - 2 files changed, 40 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -1255,6 +1255,44 @@ out_unlock: - } - EXPORT_SYMBOL_GPL(get_mtd_device_nm); - -+/** -+ * get_mtd_device_by_node - obtain a validated handle for an MTD device -+ * by of_node -+ * @of_node: OF node of MTD device to open -+ * -+ * This function returns MTD device description structure in case of -+ * success and an error code in case of failure. -+ */ -+struct mtd_info *get_mtd_device_by_node(const struct device_node *of_node) -+{ -+ int err = -ENODEV; -+ struct mtd_info *mtd = NULL, *other; -+ -+ mutex_lock(&mtd_table_mutex); -+ -+ mtd_for_each_device(other) { -+ if (of_node == other->dev.of_node) { -+ mtd = other; -+ break; -+ } -+ } -+ -+ if (!mtd) -+ goto out_unlock; -+ -+ err = __get_mtd_device(mtd); -+ if (err) -+ goto out_unlock; -+ -+ mutex_unlock(&mtd_table_mutex); -+ return mtd; -+ -+out_unlock: -+ mutex_unlock(&mtd_table_mutex); -+ return ERR_PTR(err); -+} -+EXPORT_SYMBOL_GPL(get_mtd_device_by_node); -+ - void put_mtd_device(struct mtd_info *mtd) - { - mutex_lock(&mtd_table_mutex); ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -698,6 +698,8 @@ extern struct mtd_info *get_mtd_device(s - extern int __get_mtd_device(struct mtd_info *mtd); - extern void __put_mtd_device(struct mtd_info *mtd); - extern struct mtd_info *get_mtd_device_nm(const char *name); -+extern struct mtd_info *get_mtd_device_by_node( -+ const struct device_node *of_node); - extern void put_mtd_device(struct mtd_info *mtd); - - static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) diff --git a/target/linux/generic/pending-6.0/700-net-ethernet-mtk_eth_soc-avoid-creating-duplicate-of.patch b/target/linux/generic/pending-6.0/700-net-ethernet-mtk_eth_soc-avoid-creating-duplicate-of.patch deleted file mode 100644 index 4e8042380..000000000 --- a/target/linux/generic/pending-6.0/700-net-ethernet-mtk_eth_soc-avoid-creating-duplicate-of.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Felix Fietkau -Date: Thu, 8 Jul 2021 07:08:29 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid creating duplicate offload - entries - -Sometimes multiple CLS_REPLACE calls are issued for the same connection. -rhashtable_insert_fast does not check for these duplicates, so multiple -hardware flow entries can be created. -Fix this by checking for an existing entry early - -Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support") -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -233,6 +233,9 @@ mtk_flow_offload_replace(struct mtk_eth - if (rhashtable_lookup(ð->flow_table, &f->cookie, mtk_flow_ht_params)) - return -EEXIST; - -+ if (rhashtable_lookup(ð->flow_table, &f->cookie, mtk_flow_ht_params)) -+ return -EEXIST; -+ - if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) { - struct flow_match_meta match; - diff --git a/target/linux/generic/pending-6.0/731-net-dsa-mt7530-add-support-for-in-band-link-status.patch b/target/linux/generic/pending-6.0/731-net-dsa-mt7530-add-support-for-in-band-link-status.patch deleted file mode 100644 index 852114de7..000000000 --- a/target/linux/generic/pending-6.0/731-net-dsa-mt7530-add-support-for-in-band-link-status.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 8e18c5fef75debfae3531fbd6901f3bf317d91ed Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 9 Sep 2022 04:28:43 +0100 -Subject: [PATCH] net: dsa: mt7530: add support for in-band link status -To: linux-mediatek@lists.infradead.org, - netdev@vger.kernel.org -Cc: Russell King , - Sean Wang , - Landen Chao , - DENG Qingfang , - Andrew Lunn , - Vivien Didelot , - Florian Fainelli , - Vladimir Oltean , - David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - Philipp Zabel - -Read link status from SGMII PCS for in-band managed 2500Base-X and -1000Base-X connection on a MAC port of the MT7531. This is needed to -get the SFP cage working which is connected to SGMII interface of -port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board. - -Signed-off-by: Daniel Golle ---- - drivers/net/dsa/mt7530.c | 48 +++++++++++++++++++++++++++++----------- - 1 file changed, 35 insertions(+), 13 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2708,9 +2708,6 @@ mt7531_mac_config(struct dsa_switch *ds, - case PHY_INTERFACE_MODE_NA: - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_2500BASEX: -- if (phylink_autoneg_inband(mode)) -- return -EINVAL; -- - return mt7531_sgmii_setup_mode_force(priv, port, interface); - default: - return -EINVAL; -@@ -2786,13 +2783,6 @@ unsupported: - return; - } - -- if (phylink_autoneg_inband(mode) && -- state->interface != PHY_INTERFACE_MODE_SGMII) { -- dev_err(ds->dev, "%s: in-band negotiation unsupported\n", -- __func__); -- return; -- } -- - mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); - mcr_new = mcr_cur; - mcr_new &= ~PMCR_LINK_SETTINGS_MASK; -@@ -2929,6 +2919,9 @@ static void mt753x_phylink_get_caps(stru - config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000FD; - -+ if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port)) -+ config->mac_capabilities |= MAC_2500FD; -+ - /* This driver does not make use of the speed, duplex, pause or the - * advertisement in its mac_config, so it is safe to mark this driver - * as non-legacy. -@@ -3024,16 +3017,43 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 - return 0; - } - -+static void -+mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port, -+ struct phylink_link_state *state) -+{ -+ unsigned int val; -+ -+ val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); -+ state->link = !!(val & MT7531_SGMII_LINK_STATUS); -+ if (!state->link) -+ return; -+ -+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) -+ state->speed = SPEED_2500; -+ else -+ state->speed = SPEED_1000; -+ -+ state->duplex = DUPLEX_FULL; -+ state->pause = 0; -+} -+ - static void mt7531_pcs_get_state(struct phylink_pcs *pcs, - struct phylink_link_state *state) - { - struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; - int port = pcs_to_mt753x_pcs(pcs)->port; -+ unsigned int val; - -- if (state->interface == PHY_INTERFACE_MODE_SGMII) -+ if (state->interface == PHY_INTERFACE_MODE_SGMII) { - mt7531_sgmii_pcs_get_state_an(priv, port, state); -- else -- state->link = false; -+ return; -+ } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) || -+ (state->interface == PHY_INTERFACE_MODE_2500BASEX)) { -+ mt7531_sgmii_pcs_get_state_inband(priv, port, state); -+ return; -+ } -+ -+ state->link = false; - } - - static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -3074,6 +3094,8 @@ mt753x_setup(struct dsa_switch *ds) - priv->pcs[i].pcs.ops = priv->info->pcs_ops; - priv->pcs[i].priv = priv; - priv->pcs[i].port = i; -+ if (mt753x_is_mac_port(i)) -+ priv->pcs[i].pcs.poll = 1; - } - - ret = priv->info->sw_setup(ds); diff --git a/target/linux/generic/pending-6.0/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/pending-6.0/735-net-phy-at803x-fix-at8033-sgmii-mode.patch deleted file mode 100644 index 8fc90aeb9..000000000 --- a/target/linux/generic/pending-6.0/735-net-phy-at803x-fix-at8033-sgmii-mode.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Roman Yeryomin -Subject: kernel: add at803x fix for sgmii mode - -Some (possibly broken) bootloaders incorreclty initialize at8033 -phy. This patch enables sgmii autonegotiation mode. - -[john@phrozen.org: felix added this to his upstream queue] - -Signed-off-by: Roman Yeryomin ---- - drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -84,6 +84,7 @@ - #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A - #define AT803X_REG_CHIP_CONFIG 0x1f - #define AT803X_BT_BX_REG_SEL 0x8000 -+#define AT803X_SGMII_ANEG_EN 0x1000 - - #define AT803X_DEBUG_ADDR 0x1D - #define AT803X_DEBUG_DATA 0x1E -@@ -946,6 +947,27 @@ static int at803x_smarteee_config(struct - struct at803x_priv *priv = phydev->priv; - u16 mask = 0, val = 0; - int ret; -+ u32 v; -+ -+ if (phydev->drv->phy_id == ATH8031_PHY_ID && -+ phydev->interface == PHY_INTERFACE_MODE_SGMII) -+ { -+ v = phy_read(phydev, AT803X_REG_CHIP_CONFIG); -+ /* select SGMII/fiber page */ -+ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, -+ v & ~AT803X_BT_BX_REG_SEL); -+ if (ret) -+ return ret; -+ /* enable SGMII autonegotiation */ -+ ret = phy_write(phydev, MII_BMCR, AT803X_SGMII_ANEG_EN); -+ if (ret) -+ return ret; -+ /* select copper page */ -+ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, -+ v | AT803X_BT_BX_REG_SEL); -+ if (ret) -+ return ret; -+ } - - if (priv->flags & AT803X_DISABLE_SMARTEEE) - return phy_modify_mmd(phydev, MDIO_MMD_PCS, diff --git a/target/linux/generic/pending-6.0/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch b/target/linux/generic/pending-6.0/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch deleted file mode 100644 index 530432a7c..000000000 --- a/target/linux/generic/pending-6.0/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a1b291f3f6c80a6c5ccad7283fc472d77a2a4763 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Sun, 22 Dec 2019 12:40:11 +0000 -Subject: [PATCH] net: dsa: mv88e6xxx: fix vlan setup - -Provide an option that drivers can set to indicate they want to receive -vlan configuration even when vlan filtering is disabled. This is safe -for Marvell DSA bridges, which do not look up ingress traffic in the -VTU if the port is in 8021Q disabled state. Whether this change is -suitable for all DSA bridges is not known. - -Signed-off-by: Russell King -Signed-off-by: DENG Qingfang ---- - drivers/net/dsa/mv88e6xxx/chip.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3678,6 +3678,7 @@ static int mv88e6xxx_setup(struct dsa_sw - - chip->ds = ds; - ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip); -+ ds->configure_vlan_while_not_filtering = true; - - /* Since virtual bridges are mapped in the PVT, the number we support - * depends on the physical switch topology. We need to let DSA figure diff --git a/target/linux/generic/pending-6.0/761-net-dsa-mt7530-Support-EEE-features.patch b/target/linux/generic/pending-6.0/761-net-dsa-mt7530-Support-EEE-features.patch deleted file mode 100644 index e7c54249b..000000000 --- a/target/linux/generic/pending-6.0/761-net-dsa-mt7530-Support-EEE-features.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 9cfb2d426c38272f245e9e6f62b3552d1ed5852b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= -Date: Tue, 21 Apr 2020 00:18:08 +0200 -Subject: [PATCH] net: dsa: mt7530: Support EEE features -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: René van Dorst ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2839,9 +2839,13 @@ static void mt753x_phylink_mac_link_up(s - switch (speed) { - case SPEED_1000: - mcr |= PMCR_FORCE_SPEED_1000; -+ if (priv->eee_enable & BIT(port)) -+ mcr |= PMCR_FORCE_EEE1G; - break; - case SPEED_100: - mcr |= PMCR_FORCE_SPEED_100; -+ if (priv->eee_enable & BIT(port)) -+ mcr |= PMCR_FORCE_EEE100; - break; - } - if (duplex == DUPLEX_FULL) { -@@ -3142,6 +3146,54 @@ static int mt753x_set_mac_eee(struct dsa - - return 0; - } -+ -+static int mt7530_get_mac_eee(struct dsa_switch *ds, int port, -+ struct ethtool_eee *e) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ u32 eeecr, pmsr; -+ -+ e->eee_enabled = !!(priv->eee_enable & BIT(port)); -+ -+ if (e->eee_enabled) { -+ eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port)); -+ e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN); -+ e->tx_lpi_timer = (eeecr >> 4) & 0xFFF; -+ pmsr = mt7530_read(priv, MT7530_PMSR_P(port)); -+ e->eee_active = e->eee_enabled && !!(pmsr & PMSR_EEE1G); -+ } else { -+ e->tx_lpi_enabled = 0; -+ e->tx_lpi_timer = 0; -+ e->eee_active = 0; -+ } -+ -+ return 0; -+} -+ -+static int mt7530_set_mac_eee(struct dsa_switch *ds, int port, -+ struct ethtool_eee *e) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ u32 eeecr; -+ -+ if (e->tx_lpi_enabled && e->tx_lpi_timer > 0xFFF) -+ return -EINVAL; -+ -+ if (e->eee_enabled) { -+ priv->eee_enable |= BIT(port); -+ //MT7530_PMEEECR_P -+ eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port)); -+ eeecr &= 0xFFFF0000; -+ if (!e->tx_lpi_enabled) -+ eeecr |= LPI_MODE_EN; -+ eeecr = LPI_THRESH(e->tx_lpi_timer); -+ mt7530_write(priv, MT7530_PMEEECR_P(port), eeecr); -+ } else { -+ priv->eee_enable &= ~(BIT(port)); -+ } -+ -+ return 0; -+} - - static const struct dsa_switch_ops mt7530_switch_ops = { - .get_tag_protocol = mtk_get_tag_protocol, ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -345,6 +345,12 @@ enum mt7530_vlan_port_acc_frm { - #define MAX_RX_PKT_LEN_1552 0x2 - #define MAX_RX_PKT_LEN_JUMBO 0x3 - -+#define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100) -+#define WAKEUP_TIME_1000(x) ((x & 0xFF) << 24) -+#define WAKEUP_TIME_100(x) ((x & 0xFF) << 16) -+#define LPI_THRESH(x) ((x & 0xFFF) << 4) -+#define LPI_MODE_EN BIT(0) -+ - /* Register for MIB */ - #define MT7530_PORT_MIB_COUNTER(x) (0x4000 + (x) * 0x100) - #define MT7530_MIB_CCR 0x4fe0 -@@ -817,6 +823,7 @@ struct mt7530_priv { - unsigned int p5_intf_sel; - u8 mirror_rx; - u8 mirror_tx; -+ u8 eee_enable; - - struct mt7530_port ports[MT7530_NUM_PORTS]; - struct mt753x_pcs pcs[MT7530_NUM_PORTS]; diff --git a/target/linux/generic/pending-6.0/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch b/target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch similarity index 80% rename from target/linux/generic/pending-6.0/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch rename to target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch index 15f1e4171..7b342e696 100644 --- a/target/linux/generic/pending-6.0/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch +++ b/target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch @@ -11,16 +11,16 @@ Signed-off-by: Felix Fietkau --- a/include/linux/compiler.h +++ b/include/linux/compiler.h -@@ -213,6 +213,8 @@ void ftrace_likely_update(struct ftrace_ - #define function_nocfi(x) (x) - #endif +@@ -203,6 +203,8 @@ void ftrace_likely_update(struct ftrace_ + __v; \ + }) +#include + #endif /* __KERNEL__ */ /* -@@ -251,6 +253,4 @@ static inline void *offset_to_ptr(const +@@ -243,6 +245,4 @@ static inline void *offset_to_ptr(const */ #define prevent_tail_call_optimization() mb() diff --git a/target/linux/generic/pending-6.1/101-Use-stddefs.h-instead-of-compiler.h.patch b/target/linux/generic/pending-6.1/101-Use-stddefs.h-instead-of-compiler.h.patch new file mode 100644 index 000000000..55388fb58 --- /dev/null +++ b/target/linux/generic/pending-6.1/101-Use-stddefs.h-instead-of-compiler.h.patch @@ -0,0 +1,22 @@ +From d3c5b26768dbe990c4e1bd79e420c11ce7491d51 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 11:36:00 +0200 +Subject: [PATCH] swab: use stddefs.h instead of compiler.h + +Fix an issue with kernel headers that broke perf. + +--- + include/uapi/linux/swab.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/uapi/linux/swab.h ++++ b/include/uapi/linux/swab.h +@@ -3,7 +3,7 @@ + #define _UAPI_LINUX_SWAB_H + + #include +-#include ++#include + #include + #include + diff --git a/target/linux/generic/pending-6.0/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch b/target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch similarity index 100% rename from target/linux/generic/pending-6.0/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch rename to target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch diff --git a/target/linux/generic/backport-6.0/011-kbuild-export-SUBARCH.patch b/target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch similarity index 73% rename from target/linux/generic/backport-6.0/011-kbuild-export-SUBARCH.patch rename to target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch index b6688332d..ea7a25d8a 100644 --- a/target/linux/generic/backport-6.0/011-kbuild-export-SUBARCH.patch +++ b/target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch @@ -10,12 +10,12 @@ Signed-off-by: Felix Fietkau --- a/Makefile +++ b/Makefile -@@ -537,7 +537,7 @@ KBUILD_LDFLAGS_MODULE := - KBUILD_LDFLAGS := - CLANG_FLAGS := +@@ -599,7 +599,7 @@ endif + # Allows the usage of unstable features in stable compilers. + export RUSTC_BOOTSTRAP := 1 -export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG +export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG + export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO + export HOSTRUSTC KBUILD_HOSTRUSTFLAGS export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL - export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX - export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD diff --git a/target/linux/generic/pending-6.0/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch similarity index 97% rename from target/linux/generic/pending-6.0/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch rename to target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch index a2fd96a95..c7755e7da 100644 --- a/target/linux/generic/pending-6.0/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch +++ b/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch @@ -71,7 +71,7 @@ Signed-off-by: Tobias Wolf --- a/mm/page_alloc.c +++ b/mm/page_alloc.c -@@ -7838,7 +7838,7 @@ static void __init alloc_node_mem_map(st +@@ -7891,7 +7891,7 @@ static void __init alloc_node_mem_map(st if (pgdat == NODE_DATA(0)) { mem_map = NODE_DATA(0)->node_mem_map; if (page_to_pfn(mem_map) != pgdat->node_start_pfn) diff --git a/target/linux/generic/pending-6.1/130-add-linux-spidev-compatible-si3210.patch b/target/linux/generic/pending-6.1/130-add-linux-spidev-compatible-si3210.patch new file mode 100644 index 000000000..7eefbc727 --- /dev/null +++ b/target/linux/generic/pending-6.1/130-add-linux-spidev-compatible-si3210.patch @@ -0,0 +1,18 @@ +From: Giuseppe Lippolis +Subject: Add the linux,spidev compatible in spidev Several device in ramips have this binding in the dts + +Signed-off-by: Giuseppe Lippolis +--- + drivers/spi/spidev.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -717,6 +717,7 @@ static const struct of_device_id spidev_ + { .compatible = "menlo,m53cpld", .data = &spidev_of_check }, + { .compatible = "cisco,spi-petra", .data = &spidev_of_check }, + { .compatible = "micron,spi-authenta", .data = &spidev_of_check }, ++ { .compatible = "siliconlabs,si3210" }, + {}, + }; + MODULE_DEVICE_TABLE(of, spidev_dt_ids); diff --git a/target/linux/generic/pending-6.0/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch similarity index 100% rename from target/linux/generic/pending-6.0/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch rename to target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch diff --git a/target/linux/generic/pending-6.0/141-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch similarity index 100% rename from target/linux/generic/pending-6.0/141-jffs2-add-RENAME_EXCHANGE-support.patch rename to target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch diff --git a/target/linux/generic/pending-6.0/142-jffs2-add-splice-ops.patch b/target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch similarity index 100% rename from target/linux/generic/pending-6.0/142-jffs2-add-splice-ops.patch rename to target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch diff --git a/target/linux/generic/pending-6.0/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch similarity index 100% rename from target/linux/generic/pending-6.0/150-bridge_allow_receiption_on_disabled_port.patch rename to target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch diff --git a/target/linux/generic/pending-6.0/190-rtc-rs5c372-support_alarms_up_to_1_week.patch b/target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch similarity index 100% rename from target/linux/generic/pending-6.0/190-rtc-rs5c372-support_alarms_up_to_1_week.patch rename to target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch diff --git a/target/linux/generic/pending-6.0/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch b/target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch similarity index 90% rename from target/linux/generic/pending-6.0/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch rename to target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch index 0ed070bc5..a9a5cdf8b 100644 --- a/target/linux/generic/pending-6.0/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch +++ b/target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch @@ -58,12 +58,13 @@ Signed-off-by: Daniel González Cabanelas rs5c372->rtc = devm_rtc_device_register(&client->dev, rs5c372_driver.driver.name, &rs5c372_rtc_ops, THIS_MODULE); -@@ -940,6 +953,9 @@ static int rs5c372_probe(struct i2c_clie +@@ -940,6 +953,10 @@ static int rs5c372_probe(struct i2c_clie if (err) goto exit; + /* the rs5c372 alarm only supports a minute accuracy */ -+ ++ set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rs5c372->rtc->features); ++ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rs5c372->rtc->features); + return 0; diff --git a/target/linux/generic/pending-6.0/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch similarity index 77% rename from target/linux/generic/pending-6.0/203-kallsyms_uncompressed.patch rename to target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch index 70f3cb00d..7b7aea060 100644 --- a/target/linux/generic/pending-6.0/203-kallsyms_uncompressed.patch +++ b/target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch @@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau --- a/init/Kconfig +++ b/init/Kconfig -@@ -1464,6 +1464,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW +@@ -1481,6 +1481,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW the unaligned access emulation. see arch/parisc/kernel/unaligned.c for reference @@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c -@@ -61,6 +61,11 @@ static unsigned int kallsyms_expand_symb +@@ -69,6 +69,11 @@ static unsigned int kallsyms_expand_symb * For every byte on the compressed symbol data, copy the table * entry for that byte. */ @@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau while (len) { tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; data++; -@@ -93,6 +98,9 @@ tail: +@@ -101,6 +106,9 @@ tail: */ static char kallsyms_get_symbol_type(unsigned int off) { @@ -57,7 +57,7 @@ Signed-off-by: Felix Fietkau * and return the first char from this token. --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c -@@ -58,6 +58,7 @@ static struct addr_range percpu_range = +@@ -75,6 +75,7 @@ static struct addr_range percpu_range = static struct sym_entry **table; static unsigned int table_size, table_cnt; static int all_symbols; @@ -65,7 +65,7 @@ Signed-off-by: Felix Fietkau static int absolute_percpu; static int base_relative; -@@ -487,6 +488,9 @@ static void write_src(void) +@@ -535,6 +536,9 @@ static void write_src(void) free(markers); @@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau output_label("kallsyms_token_table"); off = 0; for (i = 0; i < 256; i++) { -@@ -538,6 +542,9 @@ static unsigned char *find_token(unsigne +@@ -586,6 +590,9 @@ static unsigned char *find_token(unsigne { int i; @@ -85,7 +85,7 @@ Signed-off-by: Felix Fietkau for (i = 0; i < len - 1; i++) { if (str[i] == token[0] && str[i+1] == token[1]) return &str[i]; -@@ -610,6 +617,9 @@ static void optimize_result(void) +@@ -658,6 +665,9 @@ static void optimize_result(void) { int i, best; @@ -95,25 +95,24 @@ Signed-off-by: Felix Fietkau /* using the '\0' symbol last allows compress_symbols to use standard * fast string functions */ for (i = 255; i >= 0; i--) { -@@ -774,6 +784,8 @@ int main(int argc, char **argv) - absolute_percpu = 1; - else if (strcmp(argv[i], "--base-relative") == 0) - base_relative = 1; -+ else if (strcmp(argv[i], "--uncompressed") == 0) -+ uncompressed = 1; - else - usage(); - } +@@ -818,6 +828,7 @@ int main(int argc, char **argv) + {"all-symbols", no_argument, &all_symbols, 1}, + {"absolute-percpu", no_argument, &absolute_percpu, 1}, + {"base-relative", no_argument, &base_relative, 1}, ++ {"uncompressed", no_argument, &uncompressed, 1}, + {}, + }; + --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -156,6 +156,10 @@ kallsyms() kallsymopt="${kallsymopt} --base-relative" fi -+ if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then ++ if is_enabled CONFIG_KALLSYMS_UNCOMPRESSED; then + kallsymopt="${kallsymopt} --uncompressed" + fi + info KSYMS ${2} - ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2} + scripts/kallsyms ${kallsymopt} ${1} > ${2} } diff --git a/target/linux/generic/pending-6.0/205-backtrace_module_info.patch b/target/linux/generic/pending-6.1/205-backtrace_module_info.patch similarity index 89% rename from target/linux/generic/pending-6.0/205-backtrace_module_info.patch rename to target/linux/generic/pending-6.1/205-backtrace_module_info.patch index 5f4f6e493..27a134798 100644 --- a/target/linux/generic/pending-6.0/205-backtrace_module_info.patch +++ b/target/linux/generic/pending-6.1/205-backtrace_module_info.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/lib/vsprintf.c +++ b/lib/vsprintf.c -@@ -980,8 +980,10 @@ char *symbol_string(char *buf, char *end +@@ -985,8 +985,10 @@ char *symbol_string(char *buf, char *end struct printf_spec spec, const char *fmt) { unsigned long value; @@ -23,7 +23,7 @@ Signed-off-by: Felix Fietkau #endif if (fmt[1] == 'R') -@@ -1002,8 +1004,14 @@ char *symbol_string(char *buf, char *end +@@ -1007,8 +1009,14 @@ char *symbol_string(char *buf, char *end return string_nocheck(buf, end, sym, spec); #else diff --git a/target/linux/generic/pending-6.0/240-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch similarity index 100% rename from target/linux/generic/pending-6.0/240-remove-unsane-filenames-from-deps_initramfs-list.patch rename to target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch diff --git a/target/linux/generic/pending-6.0/261-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch similarity index 100% rename from target/linux/generic/pending-6.0/261-enable_wilink_platform_without_drivers.patch rename to target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch diff --git a/target/linux/generic/pending-6.0/270-platform-mikrotik-build-bits.patch b/target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch similarity index 80% rename from target/linux/generic/pending-6.0/270-platform-mikrotik-build-bits.patch rename to target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch index cda3c5472..997e6142a 100644 --- a/target/linux/generic/pending-6.0/270-platform-mikrotik-build-bits.patch +++ b/target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch @@ -16,20 +16,16 @@ Signed-off-by: Thibaut VARÈNE --- a/drivers/platform/Kconfig +++ b/drivers/platform/Kconfig -@@ -9,6 +9,8 @@ source "drivers/platform/chrome/Kconfig" - - source "drivers/platform/mellanox/Kconfig" - -+source "drivers/platform/mikrotik/Kconfig" -+ - source "drivers/platform/olpc/Kconfig" - +@@ -16,3 +16,5 @@ source "drivers/platform/olpc/Kconfig" source "drivers/platform/surface/Kconfig" + + source "drivers/platform/x86/Kconfig" ++ ++source "drivers/platform/mikrotik/Kconfig" --- a/drivers/platform/Makefile +++ b/drivers/platform/Makefile -@@ -9,4 +9,5 @@ obj-$(CONFIG_MIPS) += mips/ - obj-$(CONFIG_OLPC_EC) += olpc/ +@@ -11,3 +11,4 @@ obj-$(CONFIG_OLPC_EC) += olpc/ obj-$(CONFIG_GOLDFISH) += goldfish/ obj-$(CONFIG_CHROME_PLATFORMS) += chrome/ -+obj-$(CONFIG_MIKROTIK) += mikrotik/ obj-$(CONFIG_SURFACE_PLATFORMS) += surface/ ++obj-$(CONFIG_MIKROTIK) += mikrotik/ diff --git a/target/linux/generic/pending-6.0/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch similarity index 100% rename from target/linux/generic/pending-6.0/300-mips_expose_boot_raw.patch rename to target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch diff --git a/target/linux/generic/pending-6.0/302-mips_no_branch_likely.patch b/target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch similarity index 100% rename from target/linux/generic/pending-6.0/302-mips_no_branch_likely.patch rename to target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch diff --git a/target/linux/generic/pending-6.0/305-mips_module_reloc.patch b/target/linux/generic/pending-6.1/305-mips_module_reloc.patch similarity index 100% rename from target/linux/generic/pending-6.0/305-mips_module_reloc.patch rename to target/linux/generic/pending-6.1/305-mips_module_reloc.patch index e8936ae08..5de901967 100644 --- a/target/linux/generic/pending-6.0/305-mips_module_reloc.patch +++ b/target/linux/generic/pending-6.1/305-mips_module_reloc.patch @@ -165,6 +165,7 @@ Signed-off-by: Felix Fietkau + page++; + } while (free); +} ++ + void *module_alloc(unsigned long size) { @@ -299,7 +300,6 @@ Signed-off-by: Felix Fietkau + me->arch.virt_plt_tbl, v); + +} -+ + static int apply_r_mips_26(struct module *me, u32 *location, u32 base, Elf_Addr v) diff --git a/target/linux/generic/pending-6.0/307-mips_highmem_offset.patch b/target/linux/generic/pending-6.1/307-mips_highmem_offset.patch similarity index 100% rename from target/linux/generic/pending-6.0/307-mips_highmem_offset.patch rename to target/linux/generic/pending-6.1/307-mips_highmem_offset.patch diff --git a/target/linux/generic/pending-6.0/308-mips32r2_tune.patch b/target/linux/generic/pending-6.1/308-mips32r2_tune.patch similarity index 100% rename from target/linux/generic/pending-6.0/308-mips32r2_tune.patch rename to target/linux/generic/pending-6.1/308-mips32r2_tune.patch diff --git a/target/linux/generic/pending-6.0/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch similarity index 100% rename from target/linux/generic/pending-6.0/310-arm_module_unresolved_weak_sym.patch rename to target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch diff --git a/target/linux/generic/pending-6.0/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch similarity index 97% rename from target/linux/generic/pending-6.0/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch rename to target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch index 1c75eff1b..3f553b28b 100644 --- a/target/linux/generic/pending-6.0/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch +++ b/target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch @@ -267,13 +267,13 @@ Signed-off-by: Yousong Zhou -relocate_new_kernel_end: +kexec_argv_buf: + EXPORT(kexec_argv_buf) -+ .skip KEXEC_COMMAND_LINE_SIZE -+ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE ++ .skip KEXEC_COMMAND_LINE_SIZE ++ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE + +kexec_argv: + EXPORT(kexec_argv) -+ .skip KEXEC_ARGV_SIZE -+ .size kexec_argv, KEXEC_ARGV_SIZE ++ .skip KEXEC_ARGV_SIZE ++ .size kexec_argv, KEXEC_ARGV_SIZE -EXPORT(relocate_new_kernel_size) - PTR_WD relocate_new_kernel_end - relocate_new_kernel diff --git a/target/linux/generic/pending-6.0/332-arc-add-OWRTDTB-section.patch b/target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch similarity index 100% rename from target/linux/generic/pending-6.0/332-arc-add-OWRTDTB-section.patch rename to target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch diff --git a/target/linux/generic/pending-6.0/333-arc-enable-unaligned-access-in-kernel-mode.patch b/target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch similarity index 100% rename from target/linux/generic/pending-6.0/333-arc-enable-unaligned-access-in-kernel-mode.patch rename to target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch diff --git a/target/linux/generic/pending-6.0/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch b/target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch similarity index 96% rename from target/linux/generic/pending-6.0/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch rename to target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch index 5c29d1c45..7a68c4088 100644 --- a/target/linux/generic/pending-6.0/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch +++ b/target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch @@ -14,7 +14,7 @@ Signed-off-by: Pawel Dembicki --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig -@@ -228,7 +228,7 @@ config PPC +@@ -230,7 +230,7 @@ config PPC select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE select HAVE_KERNEL_LZO if DEFAULT_UIMAGE diff --git a/target/linux/generic/pending-6.0/400-mtd-mtdsplit-support.patch b/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch similarity index 92% rename from target/linux/generic/pending-6.0/400-mtd-mtdsplit-support.patch rename to target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch index d24122afc..d9e8bd92e 100644 --- a/target/linux/generic/pending-6.0/400-mtd-mtdsplit-support.patch +++ b/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch @@ -1,3 +1,16 @@ +From 39717277d5c87bdb183cf2f258957b44ba99b4df Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 11:47:35 +0200 +Subject: [PATCH] mtd: mtdsplit support + +--- + drivers/mtd/Kconfig | 19 ++++ + drivers/mtd/Makefile | 2 + + drivers/mtd/mtdpart.c | 169 ++++++++++++++++++++++++++++----- + include/linux/mtd/mtd.h | 25 +++++ + include/linux/mtd/partitions.h | 7 ++ + 5 files changed, 197 insertions(+), 25 deletions(-) + --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -12,6 +12,25 @@ menuconfig MTD @@ -26,6 +39,17 @@ config MTD_TESTS tristate "MTD tests support (DANGEROUS)" depends on m +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconc + + obj-y += parsers/ + ++obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ ++ + # 'Users' - code which presents functionality to userspace. + obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o + obj-$(CONFIG_MTD_BLOCK) += mtdblock.o --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -15,11 +15,13 @@ @@ -237,43 +261,9 @@ /* * Many partition parsers just expected the core to kfree() all their data in * one chunk. Do that by default. ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -75,6 +75,12 @@ struct mtd_part_parser_data { - * Functions dealing with the various ways of partitioning the space - */ - -+enum mtd_parser_type { -+ MTD_PARSER_TYPE_DEVICE = 0, -+ MTD_PARSER_TYPE_ROOTFS, -+ MTD_PARSER_TYPE_FIRMWARE, -+}; -+ - struct mtd_part_parser { - struct list_head list; - struct module *owner; -@@ -83,6 +89,7 @@ struct mtd_part_parser { - int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, - struct mtd_part_parser_data *); - void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); -+ enum mtd_parser_type type; - }; - - /* Container for passing around a set of parsed partitions */ ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconc - - obj-y += parsers/ - -+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ -+ - # 'Users' - code which presents functionality to userspace. - obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o - obj-$(CONFIG_MTD_BLOCK) += mtdblock.o --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h -@@ -608,6 +608,24 @@ static inline void mtd_align_erase_req(s +@@ -615,6 +615,24 @@ static inline void mtd_align_erase_req(s req->len += mtd->erasesize - mod; } @@ -298,7 +288,7 @@ static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) { if (mtd->writesize_shift) -@@ -680,6 +698,13 @@ extern void __put_mtd_device(struct mtd_ +@@ -688,6 +706,13 @@ extern struct mtd_info *of_get_mtd_devic extern struct mtd_info *get_mtd_device_nm(const char *name); extern void put_mtd_device(struct mtd_info *mtd); @@ -312,3 +302,26 @@ struct mtd_notifier { void (*add)(struct mtd_info *mtd); +--- a/include/linux/mtd/partitions.h ++++ b/include/linux/mtd/partitions.h +@@ -75,6 +75,12 @@ struct mtd_part_parser_data { + * Functions dealing with the various ways of partitioning the space + */ + ++enum mtd_parser_type { ++ MTD_PARSER_TYPE_DEVICE = 0, ++ MTD_PARSER_TYPE_ROOTFS, ++ MTD_PARSER_TYPE_FIRMWARE, ++}; ++ + struct mtd_part_parser { + struct list_head list; + struct module *owner; +@@ -83,6 +89,7 @@ struct mtd_part_parser { + int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, + struct mtd_part_parser_data *); + void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); ++ enum mtd_parser_type type; + }; + + /* Container for passing around a set of parsed partitions */ diff --git a/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch b/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch new file mode 100644 index 000000000..30ae7b287 --- /dev/null +++ b/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch @@ -0,0 +1,245 @@ +From acacdac272927ae1d96e0bca51eb82899671eaea Mon Sep 17 00:00:00 2001 +From: John Thomson +Date: Fri, 25 Dec 2020 18:50:08 +1000 +Subject: [PATCH] mtd: spi-nor: write support for minor aligned partitions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Do not prevent writing to mtd partitions where a partition boundary sits +on a minor erasesize boundary. +This addresses a FIXME that has been present since the start of the +linux git history: +/* Doesn't start on a boundary of major erase size */ +/* FIXME: Let it be writable if it is on a boundary of + * _minor_ erase size though */ + +Allow a uniform erase region spi-nor device to be configured +to use the non-uniform erase regions code path for an erase with: +CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y + +On supporting hardware (SECT_4K: majority of current SPI-NOR device) +provide the facility for an erase to use the least number +of SPI-NOR operations, as well as access to 4K erase without +requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS + +Introduce erasesize_minor to the mtd struct, +the smallest erasesize supported by the device + +On existing devices, this is useful where write support is wanted +for data on a 4K partition, such as some u-boot-env partitions, +or RouterBoot soft_config, while still netting the performance +benefits of using 64K sectors + +Performance: +time mtd erase firmware +OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length + +Without this patch +MTD_SPI_NOR_USE_4K_SECTORS=y |n +real 2m 11.66s |0m 50.86s +user 0m 0.00s |0m 0.00s +sys 1m 56.20s |0m 50.80s + +With this patch +MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y +real 0m 51.68s |0m 50.85s |2m 12.89s +user 0m 0.00s |0m 0.00s |0m 0.01s +sys 0m 46.94s |0m 50.38s |2m 12.46s + +Signed-off-by: John Thomson +Signed-off-by: Thibaut VARÈNE + +--- + +checkpatch does not like the printk(KERN_WARNING +these should be changed separately beforehand? + +Changes v1 -> v2: +Added mtdcore sysfs for erasesize_minor +Removed finding minor erasesize for variable erase regions device, +as untested and no responses regarding it. +Moved IF_ENABLED for SPINOR variable erase to guard setting +erasesize_minor in spi-nor/core.c +Removed setting erasesize to minor where partition boundaries require +minor erase to be writable +Simplified minor boundary check by relying on minor being a factor of +major + +Changes RFC -> v1: +Fix uninitialized variable smatch warning +Reported-by: kernel test robot +Reported-by: Dan Carpenter +--- + drivers/mtd/mtdcore.c | 10 ++++++++++ + drivers/mtd/mtdpart.c | 35 +++++++++++++++++++++++++---------- + drivers/mtd/spi-nor/Kconfig | 10 ++++++++++ + drivers/mtd/spi-nor/core.c | 11 +++++++++-- + include/linux/mtd/mtd.h | 2 ++ + 5 files changed, 56 insertions(+), 12 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -168,6 +168,15 @@ static ssize_t mtd_erasesize_show(struct + } + MTD_DEVICE_ATTR_RO(erasesize); + ++static ssize_t mtd_erasesize_minor_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct mtd_info *mtd = dev_get_drvdata(dev); ++ ++ return sysfs_emit(buf, "%lu\n", (unsigned long)mtd->erasesize_minor); ++} ++MTD_DEVICE_ATTR_RO(erasesize_minor); ++ + static ssize_t mtd_writesize_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -313,6 +322,7 @@ static struct attribute *mtd_attrs[] = { + &dev_attr_flags.attr, + &dev_attr_size.attr, + &dev_attr_erasesize.attr, ++ &dev_attr_erasesize_minor.attr, + &dev_attr_writesize.attr, + &dev_attr_subpagesize.attr, + &dev_attr_oobsize.attr, +--- a/drivers/mtd/mtdpart.c ++++ b/drivers/mtd/mtdpart.c +@@ -41,6 +41,7 @@ static struct mtd_info *allocate_partiti + struct mtd_info *master = mtd_get_master(parent); + int wr_alignment = (parent->flags & MTD_NO_ERASE) ? + master->writesize : master->erasesize; ++ int wr_alignment_minor = 0; + u64 parent_size = mtd_is_partition(parent) ? + parent->part.size : parent->size; + struct mtd_info *child; +@@ -165,6 +166,7 @@ static struct mtd_info *allocate_partiti + } else { + /* Single erase size */ + child->erasesize = master->erasesize; ++ child->erasesize_minor = master->erasesize_minor; + } + + /* +@@ -172,26 +174,39 @@ static struct mtd_info *allocate_partiti + * exposes several regions with different erasesize. Adjust + * wr_alignment accordingly. + */ +- if (!(child->flags & MTD_NO_ERASE)) ++ if (!(child->flags & MTD_NO_ERASE)) { + wr_alignment = child->erasesize; ++ wr_alignment_minor = child->erasesize_minor; ++ } + + tmp = mtd_get_master_ofs(child, 0); + remainder = do_div(tmp, wr_alignment); + if ((child->flags & MTD_WRITEABLE) && remainder) { +- /* Doesn't start on a boundary of major erase size */ +- /* FIXME: Let it be writable if it is on a boundary of +- * _minor_ erase size though */ +- child->flags &= ~MTD_WRITEABLE; +- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", +- part->name); ++ if (wr_alignment_minor) { ++ /* rely on minor being a factor of major erasesize */ ++ tmp = remainder; ++ remainder = do_div(tmp, wr_alignment_minor); ++ } ++ if (remainder) { ++ child->flags &= ~MTD_WRITEABLE; ++ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", ++ part->name); ++ } + } + + tmp = mtd_get_master_ofs(child, 0) + child->part.size; + remainder = do_div(tmp, wr_alignment); + if ((child->flags & MTD_WRITEABLE) && remainder) { +- child->flags &= ~MTD_WRITEABLE; +- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", +- part->name); ++ if (wr_alignment_minor) { ++ tmp = remainder; ++ remainder = do_div(tmp, wr_alignment_minor); ++ } ++ ++ if (remainder) { ++ child->flags &= ~MTD_WRITEABLE; ++ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", ++ part->name); ++ } + } + + child->size = child->part.size; +--- a/drivers/mtd/spi-nor/Kconfig ++++ b/drivers/mtd/spi-nor/Kconfig +@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR + + if MTD_SPI_NOR + ++config MTD_SPI_NOR_USE_VARIABLE_ERASE ++ bool "Disable uniform_erase to allow use of all hardware supported erasesizes" ++ depends on !MTD_SPI_NOR_USE_4K_SECTORS ++ default n ++ help ++ Allow mixed use of all hardware supported erasesizes, ++ by forcing spi_nor to use the multiple eraseregions code path. ++ For example: A 68K erase will use one 64K erase, and one 4K erase ++ on supporting hardware. ++ + config MTD_SPI_NOR_USE_4K_SECTORS + bool "Use small 4096 B erase sectors" + default y +--- a/drivers/mtd/spi-nor/core.c ++++ b/drivers/mtd/spi-nor/core.c +@@ -1048,6 +1048,8 @@ static u8 spi_nor_convert_3to4_erase(u8 + + static bool spi_nor_has_uniform_erase(const struct spi_nor *nor) + { ++ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE)) ++ return false; + return !!nor->params->erase_map.uniform_erase_type; + } + +@@ -2144,6 +2146,7 @@ static int spi_nor_select_erase(struct s + { + struct spi_nor_erase_map *map = &nor->params->erase_map; + const struct spi_nor_erase_type *erase = NULL; ++ const struct spi_nor_erase_type *erase_minor = NULL; + struct mtd_info *mtd = &nor->mtd; + u32 wanted_size = nor->info->sector_size; + int i; +@@ -2176,8 +2179,9 @@ static int spi_nor_select_erase(struct s + */ + for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { + if (map->erase_type[i].size) { +- erase = &map->erase_type[i]; +- break; ++ if (!erase) ++ erase = &map->erase_type[i]; ++ erase_minor = &map->erase_type[i]; + } + } + +@@ -2185,6 +2189,9 @@ static int spi_nor_select_erase(struct s + return -EINVAL; + + mtd->erasesize = erase->size; ++ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) && ++ erase_minor && erase_minor->size < erase->size) ++ mtd->erasesize_minor = erase_minor->size; + return 0; + } + +--- a/include/linux/mtd/mtd.h ++++ b/include/linux/mtd/mtd.h +@@ -245,6 +245,8 @@ struct mtd_info { + * information below if they desire + */ + uint32_t erasesize; ++ /* "Minor" (smallest) erase size supported by the whole device */ ++ uint32_t erasesize_minor; + /* Minimal writable flash unit size. In case of NOR flash it is 1 (even + * though individual bits can be cleared), in case of NAND flash it is + * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR diff --git a/target/linux/generic/pending-6.0/420-mtd-redboot_space.patch b/target/linux/generic/pending-6.1/420-mtd-redboot_space.patch similarity index 100% rename from target/linux/generic/pending-6.0/420-mtd-redboot_space.patch rename to target/linux/generic/pending-6.1/420-mtd-redboot_space.patch diff --git a/target/linux/generic/pending-6.0/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch similarity index 97% rename from target/linux/generic/pending-6.0/430-mtd-add-myloader-partition-parser.patch rename to target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch index 0889c9a34..c8cf3f5d3 100644 --- a/target/linux/generic/pending-6.0/430-mtd-add-myloader-partition-parser.patch +++ b/target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch @@ -10,7 +10,7 @@ Signed-off-by: Adrian Schmutzler --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig -@@ -57,6 +57,22 @@ config MTD_CMDLINE_PARTS +@@ -67,6 +67,22 @@ config MTD_CMDLINE_PARTS If unsure, say 'N'. @@ -20,7 +20,7 @@ Signed-off-by: Adrian Schmutzler + help + MyLoader is a bootloader which allows the user to define partitions + in flash devices, by putting a table in the second erase block -+ on the device, similar to a partition table. This table gives the ++ on the device, similar to a partition table. This table gives the + offsets and lengths of the user defined partitions. + + If you need code which can detect and parse these tables, and @@ -35,9 +35,9 @@ Signed-off-by: Adrian Schmutzler default y --- a/drivers/mtd/parsers/Makefile +++ b/drivers/mtd/parsers/Makefile -@@ -3,6 +3,7 @@ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part. - obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o +@@ -4,6 +4,7 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm4 obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o + obj-$(CONFIG_MTD_BRCM_U_BOOT) += brcm_u-boot.o obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o +obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o diff --git a/target/linux/generic/pending-6.0/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch similarity index 100% rename from target/linux/generic/pending-6.0/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch rename to target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch diff --git a/target/linux/generic/pending-6.0/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch similarity index 100% rename from target/linux/generic/pending-6.0/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch rename to target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch diff --git a/target/linux/generic/pending-6.0/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch similarity index 93% rename from target/linux/generic/pending-6.0/435-mtd-add-routerbootpart-parser-config.patch rename to target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch index 30f5334af..a42dcc868 100644 --- a/target/linux/generic/pending-6.0/435-mtd-add-routerbootpart-parser-config.patch +++ b/target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch @@ -16,7 +16,7 @@ Signed-off-by: Thibaut VARÈNE --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig -@@ -211,3 +211,12 @@ config MTD_SERCOMM_PARTS +@@ -236,3 +236,12 @@ config MTD_SERCOMM_PARTS partition map. This partition table contains real partition offsets, which may differ from device to device depending on the number and location of bad blocks on NAND. @@ -31,7 +31,7 @@ Signed-off-by: Thibaut VARÈNE + formatted DTS. --- a/drivers/mtd/parsers/Makefile +++ b/drivers/mtd/parsers/Makefile -@@ -15,3 +15,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpa +@@ -17,3 +17,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpa obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o diff --git a/target/linux/generic/pending-6.0/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch similarity index 100% rename from target/linux/generic/pending-6.0/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch rename to target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch diff --git a/target/linux/generic/pending-6.0/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch similarity index 100% rename from target/linux/generic/pending-6.0/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch rename to target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch diff --git a/target/linux/generic/pending-6.0/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch similarity index 100% rename from target/linux/generic/pending-6.0/465-m25p80-mx-disable-software-protection.patch rename to target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch diff --git a/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch b/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch new file mode 100644 index 000000000..303e48843 --- /dev/null +++ b/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch @@ -0,0 +1,19 @@ +From: Piotr Dymacz +Subject: kernel/mtd: add support for EON EN25Q128 + +Signed-off-by: Piotr Dymacz +--- + drivers/mtd/spi-nor/spi-nor.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mtd/spi-nor/eon.c ++++ b/drivers/mtd/spi-nor/eon.c +@@ -17,6 +17,8 @@ static const struct flash_info eon_nor_p + { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128) }, + { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128) + NO_SFDP_FLAGS(SECT_4K) }, ++ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256) ++ NO_SFDP_FLAGS(SECT_4K) }, + { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) }, + { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32) diff --git a/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch new file mode 100644 index 000000000..3b730d0f3 --- /dev/null +++ b/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch @@ -0,0 +1,81 @@ +From patchwork Thu Feb 6 17:19:41 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Daniel Golle +X-Patchwork-Id: 1234465 +Date: Thu, 6 Feb 2020 19:19:41 +0200 +From: Daniel Golle +To: linux-mtd@lists.infradead.org +Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip +Message-ID: <20200206171941.GA2398@makrotopia.org> +MIME-Version: 1.0 +Content-Disposition: inline +List-Subscribe: , + +Cc: Eitan Cohen , Piotr Dymacz , + Tudor Ambarus +Sender: "linux-mtd" +Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org + +Add XT25F128B made by XTX Technology (Shenzhen) Limited. +This chip supports dual and quad read and uniform 4K-byte erase. +Verified on Teltonika RUT955 which comes with XT25F128B in recent +versions of the device. + +Signed-off-by: Daniel Golle +Signed-off-by: Felix Fietkau +--- + drivers/mtd/spi-nor/spi-nor.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/mtd/spi-nor/Makefile ++++ b/drivers/mtd/spi-nor/Makefile +@@ -17,6 +17,7 @@ spi-nor-objs += sst.o + spi-nor-objs += winbond.o + spi-nor-objs += xilinx.o + spi-nor-objs += xmc.o ++spi-nor-objs += xtx.o + spi-nor-$(CONFIG_DEBUG_FS) += debugfs.o + obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o + +--- /dev/null ++++ b/drivers/mtd/spi-nor/xtx.c +@@ -0,0 +1,17 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include ++ ++#include "core.h" ++ ++static const struct flash_info xtx_parts[] = { ++ /* XTX Technology (Shenzhen) Limited */ ++ { "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256) ++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | ++ SPI_NOR_QUAD_READ) }, ++}; ++ ++const struct spi_nor_manufacturer spi_nor_xtx = { ++ .name = "xtx", ++ .parts = xtx_parts, ++ .nparts = ARRAY_SIZE(xtx_parts), ++}; +--- a/drivers/mtd/spi-nor/core.c ++++ b/drivers/mtd/spi-nor/core.c +@@ -1632,6 +1632,7 @@ static const struct spi_nor_manufacturer + &spi_nor_winbond, + &spi_nor_xilinx, + &spi_nor_xmc, ++ &spi_nor_xtx, + }; + + static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, +--- a/drivers/mtd/spi-nor/core.h ++++ b/drivers/mtd/spi-nor/core.h +@@ -627,6 +627,7 @@ extern const struct spi_nor_manufacturer + extern const struct spi_nor_manufacturer spi_nor_winbond; + extern const struct spi_nor_manufacturer spi_nor_xilinx; + extern const struct spi_nor_manufacturer spi_nor_xmc; ++extern const struct spi_nor_manufacturer spi_nor_xtx; + + extern const struct attribute_group *spi_nor_sysfs_groups[]; + diff --git a/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch b/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch new file mode 100644 index 000000000..7f4b48881 --- /dev/null +++ b/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch @@ -0,0 +1,23 @@ +From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001 +From: Koen Vandeputte +Date: Mon, 6 Jan 2020 13:07:56 +0100 +Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05 + +Signed-off-by: Koen Vandeputte +--- + drivers/mtd/spi-nor/spi-nor.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/mtd/spi-nor/gigadevice.c ++++ b/drivers/mtd/spi-nor/gigadevice.c +@@ -24,6 +24,10 @@ static const struct spi_nor_fixups gd25q + }; + + static const struct flash_info gigadevice_nor_parts[] = { ++ { "gd25q05", INFO(0xc84010, 0, 64 * 1024, 1) ++ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) ++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | ++ SPI_NOR_QUAD_READ) }, + { "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32) + FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | diff --git a/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch b/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch new file mode 100644 index 000000000..4d7b5cf9b --- /dev/null +++ b/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch @@ -0,0 +1,23 @@ +From f8943df3beb0d3f9754bb35320c3a378727175a8 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Thu, 14 Jul 2022 08:38:07 +0200 +Subject: [PATCH] spi-nor/gigadevic: add gd25q512 + +--- + drivers/mtd/spi-nor/gigadevice.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/mtd/spi-nor/gigadevice.c ++++ b/drivers/mtd/spi-nor/gigadevice.c +@@ -61,6 +61,11 @@ static const struct flash_info gigadevic + FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6) + FIXUP_FLAGS(SPI_NOR_4B_OPCODES) + .fixups = &gd25q256_fixups }, ++ { "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024) ++ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) ++ FIXUP_FLAGS(SPI_NOR_4B_OPCODES) ++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | ++ SPI_NOR_QUAD_READ) }, + }; + + const struct spi_nor_manufacturer spi_nor_gigadevice = { diff --git a/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch b/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch new file mode 100644 index 000000000..d5ebe2030 --- /dev/null +++ b/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch @@ -0,0 +1,24 @@ +From 87363cc0e522de3294ea6ae10fb468d2a8d6fb2f Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 12:17:21 +0200 +Subject: [PATCH] spi-nor/esmt.c: add esmt f25l16pa + +This fixes support for Dongwon T&I DW02-412H which uses F25L16PA(2S) +flash. + +--- + drivers/mtd/spi-nor/esmt.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/mtd/spi-nor/esmt.c ++++ b/drivers/mtd/spi-nor/esmt.c +@@ -10,6 +10,9 @@ + + static const struct flash_info esmt_nor_parts[] = { + /* ESMT */ ++ { "f25l16pa-2s", INFO(0x8c2115, 0, 64 * 1024, 32) ++ FLAGS(SPI_NOR_HAS_LOCK) ++ NO_SFDP_FLAGS(SECT_4K) }, + { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64) + FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) + NO_SFDP_FLAGS(SECT_4K) }, diff --git a/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch b/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch new file mode 100644 index 000000000..e8583cc25 --- /dev/null +++ b/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch @@ -0,0 +1,25 @@ +From f6b33d850f7f12555df2fa0e3349b33427bf5890 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 12:19:01 +0200 +Subject: [PATCH] spi-nor/xmc.c: add xm25qh128c + +The XMC XM25QH128C is a 16MB SPI NOR chip. The patch is verified on +Ruijie RG-EW3200GX PRO. +Datasheet available at https://www.xmcwh.com/uploads/435/XM25QH128C.pdf + +--- + drivers/mtd/spi-nor/xmc.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/mtd/spi-nor/xmc.c ++++ b/drivers/mtd/spi-nor/xmc.c +@@ -16,6 +16,9 @@ static const struct flash_info xmc_nor_p + { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ) }, ++ { "XM25QH128C", INFO(0x204018, 0, 64 * 1024, 256) ++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | ++ SPI_NOR_QUAD_READ) }, + }; + + const struct spi_nor_manufacturer spi_nor_xmc = { diff --git a/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch b/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch new file mode 100644 index 000000000..b8116db84 --- /dev/null +++ b/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch @@ -0,0 +1,143 @@ +From a43b844cb40bf1b783055fdc81b7f991e21e7e76 Mon Sep 17 00:00:00 2001 +From: Chuanhong Guo +Date: Wed, 13 Apr 2022 11:58:17 +0800 +Subject: [PATCH] mtd: spinand: add support for ESMT F50x1G41LB + +This patch adds support for ESMT F50L1G41LB and F50D1G41LB. +It seems that ESMT likes to use random JEDEC ID from other vendors. +Their 1G chips uses 0xc8 from GigaDevice and 2G/4G chips uses 0x2c from +Micron. For this reason, the ESMT entry is named esmt_c8 with explicit +JEDEC ID in variable name. + +Datasheets: +https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50L1G41LB(2M).pdf +https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50D1G41LB(2M).pdf + +Signed-off-by: Chuanhong Guo +--- + drivers/mtd/nand/spi/Makefile | 2 +- + drivers/mtd/nand/spi/core.c | 1 + + drivers/mtd/nand/spi/esmt.c | 89 +++++++++++++++++++++++++++++++++++ + include/linux/mtd/spinand.h | 1 + + 4 files changed, 92 insertions(+), 1 deletion(-) + create mode 100644 drivers/mtd/nand/spi/esmt.c + +--- a/drivers/mtd/nand/spi/Makefile ++++ b/drivers/mtd/nand/spi/Makefile +@@ -1,3 +1,3 @@ + # SPDX-License-Identifier: GPL-2.0 +-spinand-objs := core.o ato.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o ++spinand-objs := core.o ato.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o + obj-$(CONFIG_MTD_SPI_NAND) += spinand.o +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -938,6 +938,7 @@ static const struct nand_ops spinand_ops + + static const struct spinand_manufacturer *spinand_manufacturers[] = { + &ato_spinand_manufacturer, ++ &esmt_c8_spinand_manufacturer, + &gigadevice_spinand_manufacturer, + ¯onix_spinand_manufacturer, + µn_spinand_manufacturer, +--- /dev/null ++++ b/drivers/mtd/nand/spi/esmt.c +@@ -0,0 +1,89 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Author: ++ * Chuanhong Guo ++ */ ++ ++#include ++#include ++#include ++ ++/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ ++#define SPINAND_MFR_ESMT_C8 0xc8 ++ ++static SPINAND_OP_VARIANTS(read_cache_variants, ++ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); ++ ++static SPINAND_OP_VARIANTS(write_cache_variants, ++ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), ++ SPINAND_PROG_LOAD(true, 0, NULL, 0)); ++ ++static SPINAND_OP_VARIANTS(update_cache_variants, ++ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), ++ SPINAND_PROG_LOAD(false, 0, NULL, 0)); ++ ++static int f50l1g41lb_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) ++{ ++ if (section > 3) ++ return -ERANGE; ++ ++ region->offset = 16 * section + 8; ++ region->length = 8; ++ ++ return 0; ++} ++ ++static int f50l1g41lb_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) ++{ ++ if (section > 3) ++ return -ERANGE; ++ ++ region->offset = 16 * section + 2; ++ region->length = 6; ++ ++ return 0; ++} ++ ++static const struct mtd_ooblayout_ops f50l1g41lb_ooblayout = { ++ .ecc = f50l1g41lb_ooblayout_ecc, ++ .free = f50l1g41lb_ooblayout_free, ++}; ++ ++static const struct spinand_info esmt_c8_spinand_table[] = { ++ SPINAND_INFO("F50L1G41LB", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(1, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), ++ SPINAND_INFO("F50D1G41LB", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(1, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), ++}; ++ ++static const struct spinand_manufacturer_ops esmt_spinand_manuf_ops = { ++}; ++ ++const struct spinand_manufacturer esmt_c8_spinand_manufacturer = { ++ .id = SPINAND_MFR_ESMT_C8, ++ .name = "ESMT", ++ .chips = esmt_c8_spinand_table, ++ .nchips = ARRAY_SIZE(esmt_c8_spinand_table), ++ .ops = &esmt_spinand_manuf_ops, ++}; +--- a/include/linux/mtd/spinand.h ++++ b/include/linux/mtd/spinand.h +@@ -261,6 +261,7 @@ struct spinand_manufacturer { + + /* SPI NAND manufacturers */ + extern const struct spinand_manufacturer ato_spinand_manufacturer; ++extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; + extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; + extern const struct spinand_manufacturer macronix_spinand_manufacturer; + extern const struct spinand_manufacturer micron_spinand_manufacturer; diff --git a/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch b/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch new file mode 100644 index 000000000..81378fba8 --- /dev/null +++ b/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch @@ -0,0 +1,168 @@ +From f32085fc0b87049491b07e198d924d738a1a2834 Mon Sep 17 00:00:00 2001 +From: Daniel Danzberger +Date: Wed, 3 Aug 2022 17:31:03 +0200 +Subject: [PATCH] mtd: spinand: Add support for Etron EM73D044VCx + +Airoha is a new ARM platform based on Cortex-A53 which has recently been +merged into linux-next. + +Due to BootROM limitations on this platform, the Cortex-A53 can't run in +Aarch64 mode and code must be compiled for 32-Bit ARM. + +This support is based mostly on those linux-next commits backported +for kernel 5.15. + +Patches: +1 - platform support = linux-next +2 - clock driver = linux-next +3 - gpio driver = linux-next +4 - linux,usable-memory-range dts support = linux-next +5 - mtd spinand driver +6 - spi driver +7 - pci driver (kconfig only, uses mediatek PCI) = linux-next + +Still missing: +- Ethernet driver +- Sysupgrade support + +A.t.m there exists one subtarget EN7523 with only one evaluation +board. + +The initramfs can be run with the following commands from u-boot: +- +u-boot> setenv bootfile \ + openwrt-airoha-airoha_en7523-evb-initramfs-kernel.bin +u-boot> tftpboot +u-boot> bootm 0x81800000 +- + +Submitted-by: Daniel Danzberger + +--- a/drivers/mtd/nand/spi/Makefile ++++ b/drivers/mtd/nand/spi/Makefile +@@ -1,3 +1,3 @@ + # SPDX-License-Identifier: GPL-2.0 +-spinand-objs := core.o ato.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o ++spinand-objs := core.o ato.o esmt.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o + obj-$(CONFIG_MTD_SPI_NAND) += spinand.o +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -939,6 +939,7 @@ static const struct nand_ops spinand_ops + static const struct spinand_manufacturer *spinand_manufacturers[] = { + &ato_spinand_manufacturer, + &esmt_c8_spinand_manufacturer, ++ &etron_spinand_manufacturer, + &gigadevice_spinand_manufacturer, + ¯onix_spinand_manufacturer, + µn_spinand_manufacturer, +--- /dev/null ++++ b/drivers/mtd/nand/spi/etron.c +@@ -0,0 +1,98 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++#include ++#include ++ ++#define SPINAND_MFR_ETRON 0xd5 ++ ++ ++static SPINAND_OP_VARIANTS(read_cache_variants, ++ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); ++ ++static SPINAND_OP_VARIANTS(write_cache_variants, ++ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), ++ SPINAND_PROG_LOAD(true, 0, NULL, 0)); ++ ++static SPINAND_OP_VARIANTS(update_cache_variants, ++ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), ++ SPINAND_PROG_LOAD(false, 0, NULL, 0)); ++ ++static int etron_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ if (section) ++ return -ERANGE; ++ ++ oobregion->offset = 72; ++ oobregion->length = 56; ++ ++ return 0; ++} ++ ++static int etron_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ if (section) ++ return -ERANGE; ++ ++ oobregion->offset = 1; ++ oobregion->length = 71; ++ ++ return 0; ++} ++ ++static int etron_ecc_get_status(struct spinand_device *spinand, u8 status) ++{ ++ switch (status & STATUS_ECC_MASK) { ++ case STATUS_ECC_NO_BITFLIPS: ++ return 0; ++ ++ case STATUS_ECC_HAS_BITFLIPS: ++ /* Between 1-7 bitflips were corrected */ ++ return 7; ++ ++ case STATUS_ECC_MASK: ++ /* Maximum bitflips were corrected */ ++ return 8; ++ ++ case STATUS_ECC_UNCOR_ERROR: ++ return -EBADMSG; ++ } ++ ++ return -EINVAL; ++} ++ ++static const struct mtd_ooblayout_ops etron_ooblayout = { ++ .ecc = etron_ooblayout_ecc, ++ .free = etron_ooblayout_free, ++}; ++ ++static const struct spinand_info etron_spinand_table[] = { ++ SPINAND_INFO("EM73D044VCx", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f), ++ // bpc, pagesize, oobsize, pagesperblock, bperlun, maxbadplun, ppl, lpt, #t ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)), ++}; ++ ++static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = { ++}; ++ ++const struct spinand_manufacturer etron_spinand_manufacturer = { ++ .id = SPINAND_MFR_ETRON, ++ .name = "Etron", ++ .chips = etron_spinand_table, ++ .nchips = ARRAY_SIZE(etron_spinand_table), ++ .ops = &etron_spinand_manuf_ops, ++}; +--- a/include/linux/mtd/spinand.h ++++ b/include/linux/mtd/spinand.h +@@ -262,6 +262,7 @@ struct spinand_manufacturer { + /* SPI NAND manufacturers */ + extern const struct spinand_manufacturer ato_spinand_manufacturer; + extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; ++extern const struct spinand_manufacturer etron_spinand_manufacturer; + extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; + extern const struct spinand_manufacturer macronix_spinand_manufacturer; + extern const struct spinand_manufacturer micron_spinand_manufacturer; diff --git a/target/linux/generic/pending-6.0/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch similarity index 92% rename from target/linux/generic/pending-6.0/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch rename to target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch index b120548d2..eae8bdc9b 100644 --- a/target/linux/generic/pending-6.0/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch +++ b/target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch @@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c -@@ -1184,6 +1184,73 @@ static struct mtd_info * __init open_mtd +@@ -1189,6 +1189,73 @@ static struct mtd_info * __init open_mtd return mtd; } @@ -66,7 +66,7 @@ Signed-off-by: Daniel Golle + + mutex_lock(&ubi_devices_mutex); + pr_notice("UBI: auto-attach mtd%d\n", mtd->index); -+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0); ++ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false); + mutex_unlock(&ubi_devices_mutex); + if (err < 0) { + pr_err("UBI error: cannot attach mtd%d\n", mtd->index); @@ -82,7 +82,7 @@ Signed-off-by: Daniel Golle static int __init ubi_init(void) { int err, i, k; -@@ -1267,6 +1334,12 @@ static int __init ubi_init(void) +@@ -1273,6 +1340,12 @@ static int __init ubi_init(void) } } diff --git a/target/linux/generic/pending-6.0/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch similarity index 100% rename from target/linux/generic/pending-6.0/491-ubi-auto-create-ubiblock-device-for-rootfs.patch rename to target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch diff --git a/target/linux/generic/pending-6.0/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch similarity index 72% rename from target/linux/generic/pending-6.0/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch rename to target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch index 1db73cf17..f95ec46f1 100644 --- a/target/linux/generic/pending-6.0/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch +++ b/target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch @@ -3,17 +3,18 @@ Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c Signed-off-by: Daniel Golle --- - init/do_mounts.c | 28 +++++++++++++++++++++++++++- - 1 file changed, 27 insertions(+), 1 deletion(-) + init/do_mounts.c | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) --- a/init/do_mounts.c +++ b/init/do_mounts.c -@@ -446,7 +446,28 @@ retry: +@@ -446,7 +446,30 @@ retry: out: put_page(page); } - + ++#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV +static int __init mount_ubi_rootfs(void) +{ + int flags = MS_SILENT; @@ -34,19 +35,19 @@ Signed-off-by: Daniel Golle + + return -EINVAL; +} ++#endif + #ifdef CONFIG_ROOT_NFS #define NFSROOT_TIMEOUT_MIN 5 -@@ -583,6 +604,11 @@ void __init mount_root(void) - if (mount_nodev_root() == 0) - return; +@@ -579,6 +602,10 @@ void __init mount_root(void) + return; } -+ + #endif +#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV + if (!mount_ubi_rootfs()) + return; +#endif - #ifdef CONFIG_BLOCK - { - int err = create_dev("/dev/root", ROOT_DEV); + if (ROOT_DEV == 0 && root_device_name && root_fs_names) { + if (mount_nodev_root() == 0) + return; diff --git a/target/linux/generic/pending-6.0/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch similarity index 100% rename from target/linux/generic/pending-6.0/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch rename to target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch diff --git a/target/linux/generic/pending-6.0/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch similarity index 100% rename from target/linux/generic/pending-6.0/494-mtd-ubi-add-EOF-marker-support.patch rename to target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch diff --git a/target/linux/generic/pending-6.0/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch b/target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch similarity index 100% rename from target/linux/generic/pending-6.0/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch rename to target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch diff --git a/target/linux/generic/pending-6.0/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch b/target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch similarity index 100% rename from target/linux/generic/pending-6.0/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch rename to target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch diff --git a/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch b/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch new file mode 100644 index 000000000..1a4d5a766 --- /dev/null +++ b/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch @@ -0,0 +1,32 @@ +From 8bf2ce6ea4ee840b70f55a27f80e1cd308051b13 Mon Sep 17 00:00:00 2001 +From: Nick Hainke +Date: Mon, 27 Dec 2021 00:38:13 +0100 +Subject: [PATCH 1/2] mtd: spi-nor: locking support for MX25L6405D + +Macronix MX25L6405D supports locking with four block-protection bits. +Currently, the driver only sets three bits. If the bootloader does not +sustain the flash chip in an unlocked state, the flash might be +non-writeable. Add the corresponding flag to enable locking support with +four bits in the status register. + +Tested on Nanostation M2 XM. + +Similar to commit 7ea40b54e83b ("mtd: spi-nor: enable locking support for +MX25L12805D") + +Signed-off-by: David Bauer +Signed-off-by: Nick Hainke +--- + drivers/mtd/spi-nor/macronix.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/spi-nor/macronix.c ++++ b/drivers/mtd/spi-nor/macronix.c +@@ -48,6 +48,7 @@ static const struct flash_info macronix_ + { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64) + NO_SFDP_FLAGS(SECT_4K) }, + { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128) ++ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) + NO_SFDP_FLAGS(SECT_4K) }, + { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4) + NO_SFDP_FLAGS(SECT_4K) }, diff --git a/target/linux/generic/pending-6.0/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch b/target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch similarity index 94% rename from target/linux/generic/pending-6.0/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch rename to target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch index e9060e16e..99e0fc72b 100644 --- a/target/linux/generic/pending-6.0/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch +++ b/target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch @@ -20,7 +20,7 @@ Signed-off-by: Nick Hainke --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c -@@ -106,6 +106,7 @@ static void macronix_nor_default_init(st +@@ -107,6 +107,7 @@ static void macronix_nor_default_init(st { nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; diff --git a/target/linux/generic/pending-6.0/500-fs_cdrom_dependencies.patch b/target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch similarity index 73% rename from target/linux/generic/pending-6.0/500-fs_cdrom_dependencies.patch rename to target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch index 0a5a3aae5..2053c0fbe 100644 --- a/target/linux/generic/pending-6.0/500-fs_cdrom_dependencies.patch +++ b/target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch @@ -1,3 +1,15 @@ +From af7b91bcecce0eae24e90acd35d96ecee73e1407 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 12:21:15 +0200 +Subject: [PATCH] fs: add cdrom dependency + +--- + fs/hfs/Kconfig | 1 + + fs/hfsplus/Kconfig | 1 + + fs/isofs/Kconfig | 1 + + fs/udf/Kconfig | 1 + + 4 files changed, 4 insertions(+) + --- a/fs/hfs/Kconfig +++ b/fs/hfs/Kconfig @@ -2,6 +2,7 @@ diff --git a/target/linux/generic/pending-6.0/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch similarity index 99% rename from target/linux/generic/pending-6.0/530-jffs2_make_lzma_available.patch rename to target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch index 38635562a..b6b75d4ac 100644 --- a/target/linux/generic/pending-6.0/530-jffs2_make_lzma_available.patch +++ b/target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch @@ -1087,7 +1087,7 @@ Signed-off-by: Alexandros C. Couloumbis #define JFFS2_NODE_ACCURATE 0x2000 --- a/lib/Kconfig +++ b/lib/Kconfig -@@ -353,6 +353,12 @@ config ZSTD_DECOMPRESS +@@ -354,6 +354,12 @@ config ZSTD_DECOMPRESS source "lib/xz/Kconfig" @@ -1102,7 +1102,7 @@ Signed-off-by: Alexandros C. Couloumbis # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) --- a/lib/Makefile +++ b/lib/Makefile -@@ -137,6 +137,16 @@ CFLAGS_kobject.o += -DDEBUG +@@ -134,6 +134,16 @@ CFLAGS_kobject.o += -DDEBUG CFLAGS_kobject_uevent.o += -DDEBUG endif @@ -1119,7 +1119,7 @@ Signed-off-by: Alexandros C. Couloumbis obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any) -@@ -197,6 +207,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ +@@ -194,6 +204,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ obj-$(CONFIG_XZ_DEC) += xz/ obj-$(CONFIG_RAID6_PQ) += raid6/ diff --git a/target/linux/generic/pending-6.0/532-jffs2_eofdetect.patch b/target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch similarity index 100% rename from target/linux/generic/pending-6.0/532-jffs2_eofdetect.patch rename to target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch diff --git a/target/linux/generic/pending-6.0/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch similarity index 89% rename from target/linux/generic/pending-6.0/600-netfilter_conntrack_flush.patch rename to target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch index e4b03b9c5..d7548c141 100644 --- a/target/linux/generic/pending-6.0/600-netfilter_conntrack_flush.patch +++ b/target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch @@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau #include #ifdef CONFIG_SYSCTL #include -@@ -465,6 +466,56 @@ static int ct_cpu_seq_show(struct seq_fi +@@ -465,6 +466,58 @@ static int ct_cpu_seq_show(struct seq_fi return 0; } @@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau +static int ct_file_write(struct file *file, char *buf, size_t count) +{ + struct seq_file *seq = file->private_data; -+ struct net *net = seq_file_net(seq); ++ struct nf_ct_iter_data iter_data; + struct kill_request kr = { }; + + if (count == 0) @@ -66,7 +66,9 @@ Signed-off-by: Felix Fietkau + return -EINVAL; + } + -+ ++ iter_data.net = seq_file_net(seq); ++ iter_data.data = &kr; ++ nf_ct_iterate_cleanup_net(kill_matching, &iter_data); + + return 0; +} @@ -74,7 +76,7 @@ Signed-off-by: Felix Fietkau static const struct seq_operations ct_cpu_seq_ops = { .start = ct_cpu_seq_start, .next = ct_cpu_seq_next, -@@ -478,8 +529,9 @@ static int nf_conntrack_standalone_init_ +@@ -478,8 +531,9 @@ static int nf_conntrack_standalone_init_ kuid_t root_uid; kgid_t root_gid; diff --git a/target/linux/generic/pending-6.0/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch similarity index 100% rename from target/linux/generic/pending-6.0/610-netfilter_match_bypass_default_checks.patch rename to target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch diff --git a/target/linux/generic/pending-6.0/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch similarity index 100% rename from target/linux/generic/pending-6.0/611-netfilter_match_bypass_default_table.patch rename to target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch diff --git a/target/linux/generic/pending-6.0/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch similarity index 100% rename from target/linux/generic/pending-6.0/612-netfilter_match_reduce_memory_access.patch rename to target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch diff --git a/target/linux/generic/pending-6.0/613-netfilter_optional_tcp_window_check.patch b/target/linux/generic/pending-6.1/613-netfilter_optional_tcp_window_check.patch similarity index 77% rename from target/linux/generic/pending-6.0/613-netfilter_optional_tcp_window_check.patch rename to target/linux/generic/pending-6.1/613-netfilter_optional_tcp_window_check.patch index a262ad680..9962a030c 100644 --- a/target/linux/generic/pending-6.0/613-netfilter_optional_tcp_window_check.patch +++ b/target/linux/generic/pending-6.1/613-netfilter_optional_tcp_window_check.patch @@ -9,17 +9,23 @@ Signed-off-by: Christian 'Ansuel' Marangi --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -490,6 +490,9 @@ static bool tcp_in_window(struct nf_conn +@@ -513,11 +513,15 @@ tcp_in_window(struct nf_conn *ct, enum i + struct ip_ct_tcp *state = &ct->proto.tcp; + struct ip_ct_tcp_state *sender = &state->seen[dir]; + struct ip_ct_tcp_state *receiver = &state->seen[!dir]; ++ const struct nf_tcp_net *tn = nf_tcp_pernet(nf_ct_net(ct)); + __u32 seq, ack, sack, end, win, swin; + bool in_recv_win, seq_ok; s32 receiver_offset; - bool res, in_recv_win; + u16 win_raw; + if (tn->tcp_no_window_check) -+ return true; ++ return NFCT_TCP_ACCEPT; + /* * Get the required data from the packet. */ -@@ -1161,7 +1164,7 @@ int nf_conntrack_tcp_packet(struct nf_co +@@ -1242,7 +1246,7 @@ int nf_conntrack_tcp_packet(struct nf_co IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) timeout = timeouts[TCP_CONNTRACK_UNACK]; @@ -28,7 +34,7 @@ Signed-off-by: Christian 'Ansuel' Marangi timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) timeout = timeouts[TCP_CONNTRACK_RETRANS]; else -@@ -1477,6 +1480,9 @@ void nf_conntrack_tcp_init_net(struct ne +@@ -1558,6 +1562,9 @@ void nf_conntrack_tcp_init_net(struct ne */ tn->tcp_be_liberal = 0; @@ -40,7 +46,7 @@ Signed-off-by: Christian 'Ansuel' Marangi --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c -@@ -635,6 +635,7 @@ enum nf_ct_sysctl_index { +@@ -637,6 +637,7 @@ enum nf_ct_sysctl_index { #endif NF_SYSCTL_CT_PROTO_TCP_LOOSE, NF_SYSCTL_CT_PROTO_TCP_LIBERAL, @@ -48,7 +54,7 @@ Signed-off-by: Christian 'Ansuel' Marangi NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST, NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS, NF_SYSCTL_CT_PROTO_TIMEOUT_UDP, -@@ -843,6 +844,14 @@ static struct ctl_table nf_ct_sysctl_tab +@@ -845,6 +846,14 @@ static struct ctl_table nf_ct_sysctl_tab .extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, }, @@ -63,7 +69,7 @@ Signed-off-by: Christian 'Ansuel' Marangi [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = { .procname = "nf_conntrack_tcp_ignore_invalid_rst", .maxlen = sizeof(u8), -@@ -1059,6 +1068,7 @@ static void nf_conntrack_standalone_init +@@ -1061,6 +1070,7 @@ static void nf_conntrack_standalone_init XASSIGN(LOOSE, &tn->tcp_loose); XASSIGN(LIBERAL, &tn->tcp_be_liberal); diff --git a/target/linux/generic/pending-6.0/620-net_sched-codel-do-not-defer-queue-length-update.patch b/target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch similarity index 100% rename from target/linux/generic/pending-6.0/620-net_sched-codel-do-not-defer-queue-length-update.patch rename to target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch diff --git a/target/linux/generic/pending-6.0/630-packet_socket_type.patch b/target/linux/generic/pending-6.1/630-packet_socket_type.patch similarity index 95% rename from target/linux/generic/pending-6.0/630-packet_socket_type.patch rename to target/linux/generic/pending-6.1/630-packet_socket_type.patch index b11d87af2..db6f4a69d 100644 --- a/target/linux/generic/pending-6.0/630-packet_socket_type.patch +++ b/target/linux/generic/pending-6.1/630-packet_socket_type.patch @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -3372,6 +3374,7 @@ static int packet_create(struct net *net +@@ -3371,6 +3373,7 @@ static int packet_create(struct net *net mutex_init(&po->pg_vec_lock); po->rollover = NULL; po->prot_hook.func = packet_rcv; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; -@@ -4011,6 +4014,16 @@ packet_setsockopt(struct socket *sock, i +@@ -4009,6 +4012,16 @@ packet_setsockopt(struct socket *sock, i po->xmit = val ? packet_direct_xmit : dev_queue_xmit; return 0; } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau default: return -ENOPROTOOPT; } -@@ -4067,6 +4080,13 @@ static int packet_getsockopt(struct sock +@@ -4065,6 +4078,13 @@ static int packet_getsockopt(struct sock case PACKET_VNET_HDR: val = po->has_vnet_hdr; break; diff --git a/target/linux/generic/pending-6.0/655-increase_skb_pad.patch b/target/linux/generic/pending-6.1/655-increase_skb_pad.patch similarity index 91% rename from target/linux/generic/pending-6.0/655-increase_skb_pad.patch rename to target/linux/generic/pending-6.1/655-increase_skb_pad.patch index b117a3e61..29842665f 100644 --- a/target/linux/generic/pending-6.0/655-increase_skb_pad.patch +++ b/target/linux/generic/pending-6.1/655-increase_skb_pad.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -2984,7 +2984,7 @@ static inline int pskb_network_may_pull( +@@ -2987,7 +2987,7 @@ static inline int pskb_network_may_pull( * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) */ #ifndef NET_SKB_PAD diff --git a/target/linux/generic/pending-6.0/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch similarity index 97% rename from target/linux/generic/pending-6.0/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch rename to target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch index d596fde88..2bc25eb4f 100644 --- a/target/linux/generic/pending-6.0/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch +++ b/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch @@ -423,8 +423,8 @@ Signed-off-by: Steven Barth + } } - static bool ip6_tnl_netlink_encap_parms(struct nlattr *data[], -@@ -2103,6 +2322,12 @@ static void ip6_tnl_dellink(struct net_d + static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev, +@@ -2070,6 +2289,12 @@ static void ip6_tnl_dellink(struct net_d static size_t ip6_tnl_get_size(const struct net_device *dev) { @@ -437,7 +437,7 @@ Signed-off-by: Steven Barth return /* IFLA_IPTUN_LINK */ nla_total_size(4) + -@@ -2132,6 +2357,24 @@ static size_t ip6_tnl_get_size(const str +@@ -2099,6 +2324,24 @@ static size_t ip6_tnl_get_size(const str nla_total_size(0) + /* IFLA_IPTUN_FWMARK */ nla_total_size(4) + @@ -462,7 +462,7 @@ Signed-off-by: Steven Barth 0; } -@@ -2139,6 +2382,9 @@ static int ip6_tnl_fill_info(struct sk_b +@@ -2106,6 +2349,9 @@ static int ip6_tnl_fill_info(struct sk_b { struct ip6_tnl *tunnel = netdev_priv(dev); struct __ip6_tnl_parm *parm = &tunnel->parms; @@ -472,7 +472,7 @@ Signed-off-by: Steven Barth if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) || -@@ -2148,9 +2394,27 @@ static int ip6_tnl_fill_info(struct sk_b +@@ -2115,9 +2361,27 @@ static int ip6_tnl_fill_info(struct sk_b nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) || nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) || @@ -501,7 +501,7 @@ Signed-off-by: Steven Barth if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) || nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) || nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) || -@@ -2190,6 +2454,7 @@ static const struct nla_policy ip6_tnl_p +@@ -2157,6 +2421,7 @@ static const struct nla_policy ip6_tnl_p [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG }, [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, diff --git a/target/linux/generic/pending-6.0/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch similarity index 99% rename from target/linux/generic/pending-6.0/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch rename to target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch index f9d00e3bb..4db488655 100644 --- a/target/linux/generic/pending-6.0/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +++ b/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch @@ -66,7 +66,7 @@ Signed-off-by: Jonas Gorski static void rt_fibinfo_free(struct rtable __rcu **rtp) --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c -@@ -2776,6 +2776,7 @@ static const char *const rtn_type_names[ +@@ -2778,6 +2778,7 @@ static const char *const rtn_type_names[ [RTN_THROW] = "THROW", [RTN_NAT] = "NAT", [RTN_XRESOLVE] = "XRESOLVE", diff --git a/target/linux/generic/pending-6.0/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch similarity index 100% rename from target/linux/generic/pending-6.0/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch rename to target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch diff --git a/target/linux/generic/pending-6.0/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch similarity index 83% rename from target/linux/generic/pending-6.0/680-NET-skip-GRO-for-foreign-MAC-addresses.patch rename to target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch index b52b94c23..1d40e7601 100644 --- a/target/linux/generic/pending-6.0/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ b/target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2117,6 +2117,8 @@ struct net_device { +@@ -2124,6 +2124,8 @@ struct net_device { struct netdev_hw_addr_list mc; struct netdev_hw_addr_list dev_addrs; @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau #endif --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -956,6 +956,7 @@ struct sk_buff { +@@ -963,6 +963,7 @@ struct sk_buff { #ifdef CONFIG_IPV6_NDISC_NODETYPE __u8 ndisc_nodetype:2; #endif @@ -30,9 +30,21 @@ Signed-off-by: Felix Fietkau __u8 ipvs_property:1; __u8 inner_protocol_type:1; +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -482,6 +482,9 @@ static enum gro_result dev_gro_receive(s + int same_flow; + int grow; + ++ if (skb->gro_skip) ++ goto normal; ++ + if (netif_elide_gro(skb->dev)) + goto normal; + --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -7618,6 +7618,48 @@ static void __netdev_adjacent_dev_unlink +@@ -7601,6 +7601,48 @@ static void __netdev_adjacent_dev_unlink &upper_dev->adj_list.lower); } @@ -81,7 +93,7 @@ Signed-off-by: Felix Fietkau static int __netdev_upper_dev_link(struct net_device *dev, struct net_device *upper_dev, bool master, void *upper_priv, void *upper_info, -@@ -7669,6 +7711,7 @@ static int __netdev_upper_dev_link(struc +@@ -7652,6 +7694,7 @@ static int __netdev_upper_dev_link(struc if (ret) return ret; @@ -89,15 +101,15 @@ Signed-off-by: Felix Fietkau ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, &changeupper_info.info); ret = notifier_to_errno(ret); -@@ -7760,6 +7803,7 @@ static void __netdev_upper_dev_unlink(st +@@ -7748,6 +7791,7 @@ static void __netdev_upper_dev_unlink(st - changeupper_info.master = netdev_master_upper_dev_get(dev) == upper_dev; + __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); + netdev_update_addr_mask(dev); - call_netdevice_notifiers_info(NETDEV_PRECHANGEUPPER, + call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, &changeupper_info.info); -@@ -8817,6 +8861,7 @@ int dev_set_mac_address(struct net_devic +@@ -8800,6 +8844,7 @@ int dev_set_mac_address(struct net_devic if (err) return err; dev->addr_assign_type = NET_ADDR_SET; diff --git a/target/linux/generic/pending-6.0/682-of_net-add-mac-address-increment-support.patch b/target/linux/generic/pending-6.1/682-of_net-add-mac-address-increment-support.patch similarity index 100% rename from target/linux/generic/pending-6.0/682-of_net-add-mac-address-increment-support.patch rename to target/linux/generic/pending-6.1/682-of_net-add-mac-address-increment-support.patch diff --git a/target/linux/generic/pending-6.0/683-of_net-add-mac-address-to-of-tree.patch b/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch similarity index 51% rename from target/linux/generic/pending-6.0/683-of_net-add-mac-address-to-of-tree.patch rename to target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch index 88ade300a..f7ef06a14 100644 --- a/target/linux/generic/pending-6.0/683-of_net-add-mac-address-to-of-tree.patch +++ b/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch @@ -1,3 +1,20 @@ +From 8585756342caa6d27008d1ad0c18023e4211a40a Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Wed, 13 Jul 2022 12:22:48 +0200 +Subject: [PATCH] of/of_net: write back netdev MAC-address to device-tree + +The label-mac logic relies on the mac-address property of a netdev +devices of-node. However, the mac address can also be stored as a +different property or read from e.g. an mtd device. + +Create this node when reading a mac-address from OF if it does not +already exist and copy the mac-address used for the device to this +property. This way, the MAC address can be accessed using procfs. + +--- + net/core/of_net.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + --- a/net/core/of_net.c +++ b/net/core/of_net.c @@ -95,6 +95,27 @@ static int of_get_mac_addr_nvmem(struct diff --git a/target/linux/generic/pending-6.1/684-of_net-do-mac-address-increment-only-once.patch b/target/linux/generic/pending-6.1/684-of_net-do-mac-address-increment-only-once.patch new file mode 100644 index 000000000..44d88e31a --- /dev/null +++ b/target/linux/generic/pending-6.1/684-of_net-do-mac-address-increment-only-once.patch @@ -0,0 +1,31 @@ +From dd07dd394d8bfdb5d527fab18ca54f20815ec4e4 Mon Sep 17 00:00:00 2001 +From: Will Moss +Date: Wed, 3 Aug 2022 13:48:55 +0000 +Subject: [PATCH] of_net: do mac-address-increment only once + +Remove mac-address-increment and mac-address-increment-byte +DT property after incrementing process to make sure MAC address +would not get incremented more if this function is stared again. +It could happen if device initialization is deferred after +unsuccessful attempt. + +Signed-off-by: Will Moss +--- + drivers/of/of_net.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/core/of_net.c ++++ b/net/core/of_net.c +@@ -194,6 +194,12 @@ found: + addr[3] = (mac_val >> 16) & 0xff; + addr[4] = (mac_val >> 8) & 0xff; + addr[5] = (mac_val >> 0) & 0xff; ++ ++ /* Remove mac-address-increment and mac-address-increment-byte ++ * DT property to make sure MAC address would not get incremented ++ * more if this function is stared again. */ ++ of_remove_property(np, of_find_property(np, "mac-address-increment", NULL)); ++ of_remove_property(np, of_find_property(np, "mac-address-increment-byte", NULL)); + } + + of_add_mac_address(np, addr); diff --git a/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch new file mode 100644 index 000000000..182a0cbc6 --- /dev/null +++ b/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch @@ -0,0 +1,110 @@ +From: Pablo Neira Ayuso +Date: Thu, 25 Jan 2018 12:58:55 +0100 +Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from + nf_flow_table + +Move the code that deals with device events to the core. + +Signed-off-by: Pablo Neira Ayuso +--- + +--- a/net/netfilter/nf_flow_table_core.c ++++ b/net/netfilter/nf_flow_table_core.c +@@ -659,6 +659,23 @@ static struct pernet_operations nf_flow_ + .exit_batch = nf_flow_table_pernet_exit, + }; + ++static int nf_flow_table_netdev_event(struct notifier_block *this, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); ++ ++ if (event != NETDEV_DOWN) ++ return NOTIFY_DONE; ++ ++ nf_flow_table_cleanup(dev); ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block flow_offload_netdev_notifier = { ++ .notifier_call = nf_flow_table_netdev_event, ++}; ++ + static int __init nf_flow_table_module_init(void) + { + int ret; +@@ -671,8 +688,14 @@ static int __init nf_flow_table_module_i + if (ret) + goto out_offload; + ++ ret = register_netdevice_notifier(&flow_offload_netdev_notifier); ++ if (ret) ++ goto out_offload_init; ++ + return 0; + ++out_offload_init: ++ nf_flow_table_offload_exit(); + out_offload: + unregister_pernet_subsys(&nf_flow_table_net_ops); + return ret; +@@ -680,6 +703,7 @@ out_offload: + + static void __exit nf_flow_table_module_exit(void) + { ++ unregister_netdevice_notifier(&flow_offload_netdev_notifier); + nf_flow_table_offload_exit(); + unregister_pernet_subsys(&nf_flow_table_net_ops); + } +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -468,47 +468,14 @@ static struct nft_expr_type nft_flow_off + .owner = THIS_MODULE, + }; + +-static int flow_offload_netdev_event(struct notifier_block *this, +- unsigned long event, void *ptr) +-{ +- struct net_device *dev = netdev_notifier_info_to_dev(ptr); +- +- if (event != NETDEV_DOWN) +- return NOTIFY_DONE; +- +- nf_flow_table_cleanup(dev); +- +- return NOTIFY_DONE; +-} +- +-static struct notifier_block flow_offload_netdev_notifier = { +- .notifier_call = flow_offload_netdev_event, +-}; +- + static int __init nft_flow_offload_module_init(void) + { +- int err; +- +- err = register_netdevice_notifier(&flow_offload_netdev_notifier); +- if (err) +- goto err; +- +- err = nft_register_expr(&nft_flow_offload_type); +- if (err < 0) +- goto register_expr; +- +- return 0; +- +-register_expr: +- unregister_netdevice_notifier(&flow_offload_netdev_notifier); +-err: +- return err; ++ return nft_register_expr(&nft_flow_offload_type); + } + + static void __exit nft_flow_offload_module_exit(void) + { + nft_unregister_expr(&nft_flow_offload_type); +- unregister_netdevice_notifier(&flow_offload_netdev_notifier); + } + + module_init(nft_flow_offload_module_init); diff --git a/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch new file mode 100644 index 000000000..29057bd06 --- /dev/null +++ b/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch @@ -0,0 +1,41 @@ +From: Felix Fietkau +Date: Mon, 21 Mar 2022 20:39:59 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: enable threaded NAPI + +This can improve performance under load by ensuring that NAPI processing is +not pinned on CPU 0. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2858,8 +2858,8 @@ static irqreturn_t mtk_handle_irq_rx(int + + eth->rx_events++; + if (likely(napi_schedule_prep(ð->rx_napi))) { +- __napi_schedule(ð->rx_napi); + mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); ++ __napi_schedule(ð->rx_napi); + } + + return IRQ_HANDLED; +@@ -2871,8 +2871,8 @@ static irqreturn_t mtk_handle_irq_tx(int + + eth->tx_events++; + if (likely(napi_schedule_prep(ð->tx_napi))) { +- __napi_schedule(ð->tx_napi); + mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); ++ __napi_schedule(ð->tx_napi); + } + + return IRQ_HANDLED; +@@ -4174,6 +4174,8 @@ static int mtk_probe(struct platform_dev + * for NAPI to work + */ + init_dummy_netdev(ð->dummy_dev); ++ eth->dummy_dev.threaded = 1; ++ strcpy(eth->dummy_dev.name, "mtk_eth"); + netif_napi_add(ð->dummy_dev, ð->tx_napi, mtk_napi_tx); + netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx); + diff --git a/target/linux/generic/pending-6.0/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch similarity index 90% rename from target/linux/generic/pending-6.0/703-phy-add-detach-callback-to-struct-phy_driver.patch rename to target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch index c50f55431..48b1afe3f 100644 --- a/target/linux/generic/pending-6.0/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ b/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -1746,6 +1746,9 @@ void phy_detach(struct phy_device *phyde +@@ -1750,6 +1750,9 @@ void phy_detach(struct phy_device *phyde struct module *ndev_owner = NULL; struct mii_bus *bus; @@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos sysfs_remove_link(&dev->dev.kobj, "phydev"); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -827,6 +827,12 @@ struct phy_driver { +@@ -858,6 +858,12 @@ struct phy_driver { /** @handle_interrupt: Override default interrupt handling */ irqreturn_t (*handle_interrupt)(struct phy_device *phydev); diff --git a/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch b/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch new file mode 100644 index 000000000..e27ac3595 --- /dev/null +++ b/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch @@ -0,0 +1,29 @@ +From: Felix Fietkau +Date: Fri, 6 May 2022 21:38:42 +0200 +Subject: [PATCH] net: dsa: tag_mtk: add padding for tx packets + +Padding for transmitted packets needs to account for the special tag. +With not enough padding, garbage bytes are inserted by the switch at the +end of small packets. + +Fixes: 5cd8985a1909 ("net-next: dsa: add Mediatek tag RX/TX handler") +Signed-off-by: Felix Fietkau +--- + +--- a/net/dsa/tag_mtk.c ++++ b/net/dsa/tag_mtk.c +@@ -25,6 +25,14 @@ static struct sk_buff *mtk_tag_xmit(stru + u8 xmit_tpid; + u8 *mtk_tag; + ++ /* The Ethernet switch we are interfaced with needs packets to be at ++ * least 64 bytes (including FCS) otherwise their padding might be ++ * corrupted. With tags enabled, we need to make sure that packets are ++ * at least 68 bytes (including FCS and tag). ++ */ ++ if (__skb_put_padto(skb, ETH_ZLEN + MTK_HDR_LEN, false)) ++ return NULL; ++ + /* Build the special tag after the MAC Source Address. If VLAN header + * is present, it's required that VLAN header and special tag is + * being combined. Only in this way we can allow the switch can parse diff --git a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch new file mode 100644 index 000000000..0ecb87033 --- /dev/null +++ b/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -0,0 +1,174 @@ +From: Felix Fietkau +Date: Fri, 27 Aug 2021 12:22:32 +0200 +Subject: [PATCH] bridge: add knob for filtering rx/tx BPDU packets on a port + +Some devices (e.g. wireless APs) can't have devices behind them be part of +a bridge topology with redundant links, due to address limitations. +Additionally, broadcast traffic on these devices is somewhat expensive, due to +the low data rate and wakeups of clients in powersave mode. +This knob can be used to ensure that BPDU packets are never sent or forwarded +to/from these devices + +Signed-off-by: Felix Fietkau +--- + +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -59,6 +59,7 @@ struct br_ip_list { + #define BR_MRP_LOST_IN_CONT BIT(19) + #define BR_TX_FWD_OFFLOAD BIT(20) + #define BR_PORT_LOCKED BIT(21) ++#define BR_BPDU_FILTER BIT(22) + + #define BR_DEFAULT_AGEING_TIME (300 * HZ) + +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -199,6 +199,7 @@ out: + void br_flood(struct net_bridge *br, struct sk_buff *skb, + enum br_pkt_type pkt_type, bool local_rcv, bool local_orig) + { ++ const unsigned char *dest = eth_hdr(skb)->h_dest; + struct net_bridge_port *prev = NULL; + struct net_bridge_port *p; + +@@ -214,6 +215,10 @@ void br_flood(struct net_bridge *br, str + case BR_PKT_MULTICAST: + if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev) + continue; ++ if ((p->flags & BR_BPDU_FILTER) && ++ unlikely(is_link_local_ether_addr(dest) && ++ dest[5] == 0)) ++ continue; + break; + case BR_PKT_BROADCAST: + if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev) +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -344,6 +344,8 @@ static rx_handler_result_t br_handle_fra + fwd_mask |= p->group_fwd_mask; + switch (dest[5]) { + case 0x00: /* Bridge Group Address */ ++ if (p->flags & BR_BPDU_FILTER) ++ goto drop; + /* If STP is turned off, + then must forward to keep loop detection */ + if (p->br->stp_enabled == BR_NO_STP || +--- a/net/bridge/br_sysfs_if.c ++++ b/net/bridge/br_sysfs_if.c +@@ -240,6 +240,7 @@ BRPORT_ATTR_FLAG(multicast_flood, BR_MCA + BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD); + BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); + BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); ++BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); + + #ifdef CONFIG_BRIDGE_IGMP_SNOOPING + static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) +@@ -292,6 +293,7 @@ static const struct brport_attribute *br + &brport_attr_group_fwd_mask, + &brport_attr_neigh_suppress, + &brport_attr_isolated, ++ &brport_attr_bpdu_filter, + &brport_attr_backup_port, + NULL + }; +--- a/net/bridge/br_stp_bpdu.c ++++ b/net/bridge/br_stp_bpdu.c +@@ -80,7 +80,8 @@ void br_send_config_bpdu(struct net_brid + { + unsigned char buf[35]; + +- if (p->br->stp_enabled != BR_KERNEL_STP) ++ if (p->br->stp_enabled != BR_KERNEL_STP || ++ (p->flags & BR_BPDU_FILTER)) + return; + + buf[0] = 0; +@@ -127,7 +128,8 @@ void br_send_tcn_bpdu(struct net_bridge_ + { + unsigned char buf[4]; + +- if (p->br->stp_enabled != BR_KERNEL_STP) ++ if (p->br->stp_enabled != BR_KERNEL_STP || ++ (p->flags & BR_BPDU_FILTER)) + return; + + buf[0] = 0; +@@ -172,6 +174,9 @@ void br_stp_rcv(const struct stp_proto * + if (!(br->dev->flags & IFF_UP)) + goto out; + ++ if (p->flags & BR_BPDU_FILTER) ++ goto out; ++ + if (p->state == BR_STATE_DISABLED) + goto out; + +--- a/include/uapi/linux/if_link.h ++++ b/include/uapi/linux/if_link.h +@@ -561,6 +561,7 @@ enum { + IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT, + IFLA_BRPORT_MCAST_EHT_HOSTS_CNT, + IFLA_BRPORT_LOCKED, ++ IFLA_BRPORT_BPDU_FILTER, + __IFLA_BRPORT_MAX + }; + #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) +--- a/net/bridge/br_netlink.c ++++ b/net/bridge/br_netlink.c +@@ -188,6 +188,7 @@ static inline size_t br_port_info_size(v + + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */ + + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */ + + nla_total_size(1) /* IFLA_BRPORT_LOCKED */ ++ + nla_total_size(1) /* IFLA_BRPORT_BPDU_FILTER */ + + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */ + + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */ + + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */ +@@ -274,7 +275,8 @@ static int br_port_fill_attrs(struct sk_ + nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN, + !!(p->flags & BR_MRP_LOST_IN_CONT)) || + nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) || +- nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED))) ++ nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)) || ++ nla_put_u8(skb, IFLA_BRPORT_BPDU_FILTER, !!(p->flags & BR_BPDU_FILTER))) + return -EMSGSIZE; + + timerval = br_timer_value(&p->message_age_timer); +@@ -878,6 +880,7 @@ static const struct nla_policy br_port_p + [IFLA_BRPORT_LOCKED] = { .type = NLA_U8 }, + [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 }, + [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 }, ++ [IFLA_BRPORT_BPDU_FILTER] = { .type = NLA_U8 }, + }; + + /* Change the state of the port and notify spanning tree */ +@@ -943,6 +946,7 @@ static int br_setport(struct net_bridge_ + br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS); + br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED); + br_set_port_flag(p, tb, IFLA_BRPORT_LOCKED, BR_PORT_LOCKED); ++ br_set_port_flag(p, tb, IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER); + + changed_mask = old_flags ^ p->flags; + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -57,7 +57,7 @@ + #include "dev.h" + + #define RTNL_MAX_TYPE 50 +-#define RTNL_SLAVE_MAX_TYPE 40 ++#define RTNL_SLAVE_MAX_TYPE 41 + + struct rtnl_link { + rtnl_doit_func doit; +@@ -4811,7 +4811,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu + brport_nla_put_flag(skb, flags, mask, + IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) || + brport_nla_put_flag(skb, flags, mask, +- IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD)) { ++ IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD) || ++ brport_nla_put_flag(skb, flags, mask, ++ IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER)) { + nla_nest_cancel(skb, protinfo); + goto nla_put_failure; + } diff --git a/target/linux/generic/pending-6.0/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch b/target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch similarity index 94% rename from target/linux/generic/pending-6.0/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch rename to target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch index 703a0b8b7..61ef7ebda 100644 --- a/target/linux/generic/pending-6.0/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch +++ b/target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch @@ -39,7 +39,7 @@ Signed-off-by: Alexander Couzens #define RTL8366RB_POWER_SAVE 0x15 #define RTL8366RB_POWER_SAVE_ON BIT(12) -@@ -841,6 +850,43 @@ static irqreturn_t rtl9000a_handle_inter +@@ -849,6 +858,43 @@ static irqreturn_t rtl9000a_handle_inter return IRQ_HANDLED; } @@ -83,7 +83,7 @@ Signed-off-by: Alexander Couzens static struct phy_driver realtek_drvs[] = { { PHY_ID_MATCH_EXACT(0x00008201), -@@ -981,6 +1027,7 @@ static struct phy_driver realtek_drvs[] +@@ -1001,6 +1047,7 @@ static struct phy_driver realtek_drvs[] PHY_ID_MATCH_EXACT(0x001cc849), .name = "RTL8221B-VB-CG 2.5Gbps PHY", .get_features = rtl822x_get_features, @@ -91,7 +91,7 @@ Signed-off-by: Alexander Couzens .config_aneg = rtl822x_config_aneg, .read_status = rtl822x_read_status, .suspend = genphy_suspend, -@@ -992,6 +1039,7 @@ static struct phy_driver realtek_drvs[] +@@ -1012,6 +1059,7 @@ static struct phy_driver realtek_drvs[] .name = "RTL8221B-VM-CG 2.5Gbps PHY", .get_features = rtl822x_get_features, .config_aneg = rtl822x_config_aneg, diff --git a/target/linux/generic/pending-6.1/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-6.1/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch new file mode 100644 index 000000000..891db44f2 --- /dev/null +++ b/target/linux/generic/pending-6.1/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch @@ -0,0 +1,28 @@ +From 3fb8841513c4ec3a2e5d366df86230c45f239a57 Mon Sep 17 00:00:00 2001 +From: Alexander Couzens +Date: Sat, 13 Aug 2022 13:08:22 +0200 +Subject: [PATCH 03/10] net: mt7531: ensure all MACs are powered down before + reset + +The datasheet [1] explicit describes it as requirement for a reset. + +[1] MT7531 Reference Manual for Development Board rev 1.0, page 735 + +Signed-off-by: Alexander Couzens +--- + drivers/net/dsa/mt7530.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -2184,6 +2184,10 @@ mt7530_setup(struct dsa_switch *ds) + return -ENODEV; + } + ++ /* all MACs must be forced link-down before sw reset */ ++ for (i = 0; i < MT7530_NUM_PORTS; i++) ++ mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK); ++ + /* Reset the switch through internal reset */ + mt7530_write(priv, MT7530_SYS_CTRL, + SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST | diff --git a/target/linux/generic/pending-6.0/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch b/target/linux/generic/pending-6.1/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch similarity index 100% rename from target/linux/generic/pending-6.0/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch rename to target/linux/generic/pending-6.1/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch diff --git a/target/linux/generic/pending-6.0/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch b/target/linux/generic/pending-6.1/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch similarity index 100% rename from target/linux/generic/pending-6.0/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch rename to target/linux/generic/pending-6.1/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch diff --git a/target/linux/generic/pending-6.0/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch b/target/linux/generic/pending-6.1/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch similarity index 100% rename from target/linux/generic/pending-6.0/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch rename to target/linux/generic/pending-6.1/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch diff --git a/target/linux/generic/pending-6.0/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch b/target/linux/generic/pending-6.1/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch similarity index 100% rename from target/linux/generic/pending-6.0/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch rename to target/linux/generic/pending-6.1/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch diff --git a/target/linux/generic/pending-6.0/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch b/target/linux/generic/pending-6.1/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch similarity index 100% rename from target/linux/generic/pending-6.0/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch rename to target/linux/generic/pending-6.1/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch diff --git a/target/linux/generic/pending-6.0/729-net-mtk_eth_soc-improve-comment.patch b/target/linux/generic/pending-6.1/729-net-mtk_eth_soc-improve-comment.patch similarity index 100% rename from target/linux/generic/pending-6.0/729-net-mtk_eth_soc-improve-comment.patch rename to target/linux/generic/pending-6.1/729-net-mtk_eth_soc-improve-comment.patch diff --git a/target/linux/generic/pending-6.0/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch b/target/linux/generic/pending-6.1/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch similarity index 100% rename from target/linux/generic/pending-6.0/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch rename to target/linux/generic/pending-6.1/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch diff --git a/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch b/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch new file mode 100644 index 000000000..dd4eac5f9 --- /dev/null +++ b/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch @@ -0,0 +1,59 @@ +From 686c603f67ae87bf21a61b5e4b1564443f41c3ee Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 20 Oct 2022 03:34:43 +0200 +Subject: [PATCH] net: permit ieee80211_ptr even with no CFG82111 support + +Introduce a new flag CONFIG_CFG80211_HEADERS to compile in ieee80211_ptr +even if CFG80211 support is not compiled in. This is needed for the +backports project and for any downstream wireless driver that loads in +the kernel dynamically. + +Signed-off-by: Christian Marangi +--- + include/linux/netdevice.h | 2 +- + net/batman-adv/hard-interface.c | 2 +- + net/wireless/Kconfig | 4 ++++ + 3 files changed, 6 insertions(+), 2 deletions(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2159,7 +2159,7 @@ struct net_device { + #if IS_ENABLED(CONFIG_AX25) + void *ax25_ptr; + #endif +-#if IS_ENABLED(CONFIG_CFG80211) ++#if IS_ENABLED(CONFIG_CFG80211_HEADERS) + struct wireless_dev *ieee80211_ptr; + #endif + #if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN) +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -308,7 +308,7 @@ static bool batadv_is_cfg80211_netdev(st + if (!net_device) + return false; + +-#if IS_ENABLED(CONFIG_CFG80211) ++#if IS_ENABLED(CONFIG_CFG80211_HEADERS) + /* cfg80211 drivers have to set ieee80211_ptr */ + if (net_device->ieee80211_ptr) + return true; +--- a/net/wireless/Kconfig ++++ b/net/wireless/Kconfig +@@ -26,6 +26,7 @@ config CFG80211 + # using a different algorithm, though right now they shouldn't + # (this is here rather than below to allow it to be a module) + select CRYPTO_SHA256 if CFG80211_USE_KERNEL_REGDB_KEYS ++ select CFG80211_HEADERS + help + cfg80211 is the Linux wireless LAN (802.11) configuration API. + Enable this if you have a wireless device. +@@ -36,6 +37,9 @@ config CFG80211 + + When built as a module it will be called cfg80211. + ++config CFG80211_HEADERS ++ bool "cfg80211 - headers support" ++ + if CFG80211 + + config NL80211_TESTMODE diff --git a/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch b/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch new file mode 100644 index 000000000..45af898cf --- /dev/null +++ b/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch @@ -0,0 +1,22 @@ +From: Felix Fietkau +Date: Thu, 27 Oct 2022 19:50:31 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: account for vlan in rx + header length + +The network stack assumes that devices can handle an extra VLAN tag without +increasing the MTU + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -29,7 +29,7 @@ + #define MTK_TX_DMA_BUF_LEN_V2 0xffff + #define MTK_DMA_SIZE 512 + #define MTK_MAC_COUNT 2 +-#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN) ++#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN) + #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN) + #define MTK_DMA_DUMMY_DESC 0xffffffff + #define MTK_DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | \ diff --git a/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch b/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch new file mode 100644 index 000000000..0cd7f5dba --- /dev/null +++ b/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch @@ -0,0 +1,143 @@ +From: Felix Fietkau +Date: Thu, 27 Oct 2022 19:53:57 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: increase tx ring side for + QDMA devices + +In order to use the hardware traffic shaper feature, a larger tx ring is +needed, especially for the scratch ring, which the hardware shaper uses to +reorder packets. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -938,7 +938,7 @@ static int mtk_init_fq_dma(struct mtk_et + { + const struct mtk_soc_data *soc = eth->soc; + dma_addr_t phy_ring_tail; +- int cnt = MTK_DMA_SIZE; ++ int cnt = MTK_QDMA_RING_SIZE; + dma_addr_t dma_addr; + int i; + +@@ -2202,19 +2202,25 @@ static int mtk_tx_alloc(struct mtk_eth * + struct mtk_tx_ring *ring = ð->tx_ring; + int i, sz = soc->txrx.txd_size; + struct mtk_tx_dma_v2 *txd; ++ int ring_size; + +- ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf), ++ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) ++ ring_size = MTK_QDMA_RING_SIZE; ++ else ++ ring_size = MTK_DMA_SIZE; ++ ++ ring->buf = kcalloc(ring_size, sizeof(*ring->buf), + GFP_KERNEL); + if (!ring->buf) + goto no_tx_mem; + +- ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, ++ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, + &ring->phys, GFP_KERNEL); + if (!ring->dma) + goto no_tx_mem; + +- for (i = 0; i < MTK_DMA_SIZE; i++) { +- int next = (i + 1) % MTK_DMA_SIZE; ++ for (i = 0; i < ring_size; i++) { ++ int next = (i + 1) % ring_size; + u32 next_ptr = ring->phys + next * sz; + + txd = ring->dma + i * sz; +@@ -2234,22 +2240,22 @@ static int mtk_tx_alloc(struct mtk_eth * + * descriptors in ring->dma_pdma. + */ + if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { +- ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, ++ ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, + &ring->phys_pdma, GFP_KERNEL); + if (!ring->dma_pdma) + goto no_tx_mem; + +- for (i = 0; i < MTK_DMA_SIZE; i++) { ++ for (i = 0; i < ring_size; i++) { + ring->dma_pdma[i].txd2 = TX_DMA_DESP2_DEF; + ring->dma_pdma[i].txd4 = 0; + } + } + +- ring->dma_size = MTK_DMA_SIZE; +- atomic_set(&ring->free_count, MTK_DMA_SIZE - 2); ++ ring->dma_size = ring_size; ++ atomic_set(&ring->free_count, ring_size - 2); + ring->next_free = ring->dma; + ring->last_free = (void *)txd; +- ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz)); ++ ring->last_free_ptr = (u32)(ring->phys + ((ring_size - 1) * sz)); + ring->thresh = MAX_SKB_FRAGS; + + /* make sure that all changes to the dma ring are flushed before we +@@ -2261,14 +2267,14 @@ static int mtk_tx_alloc(struct mtk_eth * + mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr); + mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr); + mtk_w32(eth, +- ring->phys + ((MTK_DMA_SIZE - 1) * sz), ++ ring->phys + ((ring_size - 1) * sz), + soc->reg_map->qdma.crx_ptr); + mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); + mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, + soc->reg_map->qdma.qtx_cfg); + } else { + mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); +- mtk_w32(eth, MTK_DMA_SIZE, MT7628_TX_MAX_CNT0); ++ mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); + mtk_w32(eth, 0, MT7628_TX_CTX_IDX0); + mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx); + } +@@ -2286,7 +2292,7 @@ static void mtk_tx_clean(struct mtk_eth + int i; + + if (ring->buf) { +- for (i = 0; i < MTK_DMA_SIZE; i++) ++ for (i = 0; i < ring->dma_size; i++) + mtk_tx_unmap(eth, &ring->buf[i], NULL, false); + kfree(ring->buf); + ring->buf = NULL; +@@ -2294,14 +2300,14 @@ static void mtk_tx_clean(struct mtk_eth + + if (ring->dma) { + dma_free_coherent(eth->dma_dev, +- MTK_DMA_SIZE * soc->txrx.txd_size, ++ ring->dma_size * soc->txrx.txd_size, + ring->dma, ring->phys); + ring->dma = NULL; + } + + if (ring->dma_pdma) { + dma_free_coherent(eth->dma_dev, +- MTK_DMA_SIZE * soc->txrx.txd_size, ++ ring->dma_size * soc->txrx.txd_size, + ring->dma_pdma, ring->phys_pdma); + ring->dma_pdma = NULL; + } +@@ -2823,7 +2829,7 @@ static void mtk_dma_free(struct mtk_eth + netdev_reset_queue(eth->netdev[i]); + if (eth->scratch_ring) { + dma_free_coherent(eth->dma_dev, +- MTK_DMA_SIZE * soc->txrx.txd_size, ++ MTK_QDMA_RING_SIZE * soc->txrx.txd_size, + eth->scratch_ring, eth->phy_scratch_ring); + eth->scratch_ring = NULL; + eth->phy_scratch_ring = 0; +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -27,6 +27,7 @@ + #define MTK_MAX_RX_LENGTH_2K 2048 + #define MTK_TX_DMA_BUF_LEN 0x3fff + #define MTK_TX_DMA_BUF_LEN_V2 0xffff ++#define MTK_QDMA_RING_SIZE 2048 + #define MTK_DMA_SIZE 512 + #define MTK_MAC_COUNT 2 + #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN) diff --git a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch b/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch new file mode 100644 index 000000000..f4aff30d7 --- /dev/null +++ b/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch @@ -0,0 +1,52 @@ +From: Felix Fietkau +Date: Fri, 4 Nov 2022 19:49:08 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid port_mg assignment on + MT7622 and newer + +On newer chips, this field is unused and contains some bits related to queue +assignment. Initialize it to 0 in those cases. +Fix offload_version on MT7621 and MT7623, which still need the previous value. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4250,7 +4250,7 @@ static const struct mtk_soc_data mt7621_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7621_CLKS_BITMAP, + .required_pctl = false, +- .offload_version = 2, ++ .offload_version = 1, + .hash_offset = 2, + .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { +@@ -4289,7 +4289,7 @@ static const struct mtk_soc_data mt7623_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7623_CLKS_BITMAP, + .required_pctl = true, +- .offload_version = 2, ++ .offload_version = 1, + .hash_offset = 2, + .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -175,6 +175,8 @@ int mtk_foe_entry_prepare(struct mtk_eth + val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) | + FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf); + } else { ++ int port_mg = eth->soc->offload_version > 1 ? 0 : 0x3f; ++ + val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | + FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | + FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | +@@ -182,7 +184,7 @@ int mtk_foe_entry_prepare(struct mtk_eth + entry->ib1 = val; + + val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) | +- FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | ++ FIELD_PREP(MTK_FOE_IB2_PORT_MG, port_mg) | + FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f); + } + diff --git a/target/linux/generic/pending-6.1/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch b/target/linux/generic/pending-6.1/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch new file mode 100644 index 000000000..bed28561f --- /dev/null +++ b/target/linux/generic/pending-6.1/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch @@ -0,0 +1,654 @@ +From: Felix Fietkau +Date: Thu, 27 Oct 2022 20:17:27 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: implement multi-queue + support for per-port queues + +When sending traffic to multiple ports with different link speeds, queued +packets to one port can drown out tx to other ports. +In order to better handle transmission to multiple ports, use the hardware +shaper feature to implement weighted fair queueing between ports. +Weight and maximum rate are automatically adjusted based on the link speed +of the port. +The first 3 queues are unrestricted and reserved for non-DSA direct tx on +GMAC ports. The following queues are automatically assigned by the MTK DSA +tag driver based on the target port number. +The PPE offload code configures the queues for offloaded traffic in the same +way. +This feature is only supported on devices supporting QDMA. All queues still +share the same DMA ring and descriptor pool. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -54,6 +54,7 @@ static const struct mtk_reg_map mtk_reg_ + }, + .qdma = { + .qtx_cfg = 0x1800, ++ .qtx_sch = 0x1804, + .rx_ptr = 0x1900, + .rx_cnt_cfg = 0x1904, + .qcrx_ptr = 0x1908, +@@ -61,6 +62,7 @@ static const struct mtk_reg_map mtk_reg_ + .rst_idx = 0x1a08, + .delay_irq = 0x1a0c, + .fc_th = 0x1a10, ++ .tx_sch_rate = 0x1a14, + .int_grp = 0x1a20, + .hred = 0x1a44, + .ctx_ptr = 0x1b00, +@@ -113,6 +115,7 @@ static const struct mtk_reg_map mt7986_r + }, + .qdma = { + .qtx_cfg = 0x4400, ++ .qtx_sch = 0x4404, + .rx_ptr = 0x4500, + .rx_cnt_cfg = 0x4504, + .qcrx_ptr = 0x4508, +@@ -130,6 +133,7 @@ static const struct mtk_reg_map mt7986_r + .fq_tail = 0x4724, + .fq_count = 0x4728, + .fq_blen = 0x472c, ++ .tx_sch_rate = 0x4798, + }, + .gdm1_cnt = 0x1c00, + .gdma_to_ppe = 0x3333, +@@ -613,6 +617,75 @@ static void mtk_mac_link_down(struct phy + mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); + } + ++static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, ++ int speed) ++{ ++ const struct mtk_soc_data *soc = eth->soc; ++ u32 ofs, val; ++ ++ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) ++ return; ++ ++ val = MTK_QTX_SCH_MIN_RATE_EN | ++ /* minimum: 10 Mbps */ ++ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | ++ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | ++ MTK_QTX_SCH_LEAKY_BUCKET_SIZE; ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; ++ ++ if (IS_ENABLED(CONFIG_SOC_MT7621)) { ++ switch (speed) { ++ case SPEED_10: ++ val |= MTK_QTX_SCH_MAX_RATE_EN | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 2) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); ++ break; ++ case SPEED_100: ++ val |= MTK_QTX_SCH_MAX_RATE_EN | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3); ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); ++ break; ++ case SPEED_1000: ++ val |= MTK_QTX_SCH_MAX_RATE_EN | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 105) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10); ++ break; ++ default: ++ break; ++ } ++ } else { ++ switch (speed) { ++ case SPEED_10: ++ val |= MTK_QTX_SCH_MAX_RATE_EN | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); ++ break; ++ case SPEED_100: ++ val |= MTK_QTX_SCH_MAX_RATE_EN | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5); ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); ++ break; ++ case SPEED_1000: ++ val |= MTK_QTX_SCH_MAX_RATE_EN | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 10) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) | ++ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ ofs = MTK_QTX_OFFSET * idx; ++ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); ++} ++ + static void mtk_mac_link_up(struct phylink_config *config, + struct phy_device *phy, + unsigned int mode, phy_interface_t interface, +@@ -638,6 +711,8 @@ static void mtk_mac_link_up(struct phyli + break; + } + ++ mtk_set_queue_speed(mac->hw, mac->id, speed); ++ + /* Configure duplex */ + if (duplex == DUPLEX_FULL) + mcr |= MAC_MCR_FORCE_DPX; +@@ -1099,7 +1174,8 @@ static void mtk_tx_set_dma_desc_v1(struc + + WRITE_ONCE(desc->txd1, info->addr); + +- data = TX_DMA_SWC | TX_DMA_PLEN0(info->size); ++ data = TX_DMA_SWC | TX_DMA_PLEN0(info->size) | ++ FIELD_PREP(TX_DMA_PQID, info->qid); + if (info->last) + data |= TX_DMA_LS0; + WRITE_ONCE(desc->txd3, data); +@@ -1133,9 +1209,6 @@ static void mtk_tx_set_dma_desc_v2(struc + data |= TX_DMA_LS0; + WRITE_ONCE(desc->txd3, data); + +- if (!info->qid && mac->id) +- info->qid = MTK_QDMA_GMAC2_QID; +- + data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ + data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); + WRITE_ONCE(desc->txd4, data); +@@ -1179,11 +1252,12 @@ static int mtk_tx_map(struct sk_buff *sk + .gso = gso, + .csum = skb->ip_summed == CHECKSUM_PARTIAL, + .vlan = skb_vlan_tag_present(skb), +- .qid = skb->mark & MTK_QDMA_TX_MASK, ++ .qid = skb_get_queue_mapping(skb), + .vlan_tci = skb_vlan_tag_get(skb), + .first = true, + .last = !skb_is_nonlinear(skb), + }; ++ struct netdev_queue *txq; + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + const struct mtk_soc_data *soc = eth->soc; +@@ -1191,8 +1265,10 @@ static int mtk_tx_map(struct sk_buff *sk + struct mtk_tx_dma *itxd_pdma, *txd_pdma; + struct mtk_tx_buf *itx_buf, *tx_buf; + int i, n_desc = 1; ++ int queue = skb_get_queue_mapping(skb); + int k = 0; + ++ txq = netdev_get_tx_queue(dev, queue); + itxd = ring->next_free; + itxd_pdma = qdma_to_pdma(ring, itxd); + if (itxd == ring->last_free) +@@ -1241,7 +1317,7 @@ static int mtk_tx_map(struct sk_buff *sk + memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); + txd_info.size = min_t(unsigned int, frag_size, + soc->txrx.dma_max_len); +- txd_info.qid = skb->mark & MTK_QDMA_TX_MASK; ++ txd_info.qid = queue; + txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && + !(frag_size - txd_info.size); + txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, +@@ -1280,7 +1356,7 @@ static int mtk_tx_map(struct sk_buff *sk + txd_pdma->txd2 |= TX_DMA_LS1; + } + +- netdev_sent_queue(dev, skb->len); ++ netdev_tx_sent_queue(txq, skb->len); + skb_tx_timestamp(skb); + + ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); +@@ -1292,8 +1368,7 @@ static int mtk_tx_map(struct sk_buff *sk + wmb(); + + if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { +- if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || +- !netdev_xmit_more()) ++ if (netif_xmit_stopped(txq) || !netdev_xmit_more()) + mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); + } else { + int next_idx; +@@ -1362,7 +1437,7 @@ static void mtk_wake_queue(struct mtk_et + for (i = 0; i < MTK_MAC_COUNT; i++) { + if (!eth->netdev[i]) + continue; +- netif_wake_queue(eth->netdev[i]); ++ netif_tx_wake_all_queues(eth->netdev[i]); + } + } + +@@ -1386,7 +1461,7 @@ static netdev_tx_t mtk_start_xmit(struct + + tx_num = mtk_cal_txd_req(eth, skb); + if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { +- netif_stop_queue(dev); ++ netif_tx_stop_all_queues(dev); + netif_err(eth, tx_queued, dev, + "Tx Ring full when queue awake!\n"); + spin_unlock(ð->page_lock); +@@ -1412,7 +1487,7 @@ static netdev_tx_t mtk_start_xmit(struct + goto drop; + + if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) +- netif_stop_queue(dev); ++ netif_tx_stop_all_queues(dev); + + spin_unlock(ð->page_lock); + +@@ -1579,10 +1654,12 @@ static int mtk_xdp_submit_frame(struct m + struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf); + const struct mtk_soc_data *soc = eth->soc; + struct mtk_tx_ring *ring = ð->tx_ring; ++ struct mtk_mac *mac = netdev_priv(dev); + struct mtk_tx_dma_desc_info txd_info = { + .size = xdpf->len, + .first = true, + .last = !xdp_frame_has_frags(xdpf), ++ .qid = mac->id, + }; + int err, index = 0, n_desc = 1, nr_frags; + struct mtk_tx_buf *htx_buf, *tx_buf; +@@ -1632,6 +1709,7 @@ static int mtk_xdp_submit_frame(struct m + memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); + txd_info.size = skb_frag_size(&sinfo->frags[index]); + txd_info.last = index + 1 == nr_frags; ++ txd_info.qid = mac->id; + data = skb_frag_address(&sinfo->frags[index]); + + index++; +@@ -1986,8 +2064,46 @@ rx_done: + return done; + } + ++struct mtk_poll_state { ++ struct netdev_queue *txq; ++ unsigned int total; ++ unsigned int done; ++ unsigned int bytes; ++}; ++ ++static void ++mtk_poll_tx_done(struct mtk_eth *eth, struct mtk_poll_state *state, u8 mac, ++ struct sk_buff *skb) ++{ ++ struct netdev_queue *txq; ++ struct net_device *dev; ++ unsigned int bytes = skb->len; ++ ++ state->total++; ++ eth->tx_packets++; ++ eth->tx_bytes += bytes; ++ ++ dev = eth->netdev[mac]; ++ if (!dev) ++ return; ++ ++ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); ++ if (state->txq == txq) { ++ state->done++; ++ state->bytes += bytes; ++ return; ++ } ++ ++ if (state->txq) ++ netdev_tx_completed_queue(state->txq, state->done, state->bytes); ++ ++ state->txq = txq; ++ state->done = 1; ++ state->bytes = bytes; ++} ++ + static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, +- unsigned int *done, unsigned int *bytes) ++ struct mtk_poll_state *state) + { + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + struct mtk_tx_ring *ring = ð->tx_ring; +@@ -2019,12 +2135,9 @@ static int mtk_poll_tx_qdma(struct mtk_e + break; + + if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { +- if (tx_buf->type == MTK_TYPE_SKB) { +- struct sk_buff *skb = tx_buf->data; ++ if (tx_buf->type == MTK_TYPE_SKB) ++ mtk_poll_tx_done(eth, state, mac, tx_buf->data); + +- bytes[mac] += skb->len; +- done[mac]++; +- } + budget--; + } + mtk_tx_unmap(eth, tx_buf, &bq, true); +@@ -2043,7 +2156,7 @@ static int mtk_poll_tx_qdma(struct mtk_e + } + + static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget, +- unsigned int *done, unsigned int *bytes) ++ struct mtk_poll_state *state) + { + struct mtk_tx_ring *ring = ð->tx_ring; + struct mtk_tx_buf *tx_buf; +@@ -2061,12 +2174,8 @@ static int mtk_poll_tx_pdma(struct mtk_e + break; + + if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { +- if (tx_buf->type == MTK_TYPE_SKB) { +- struct sk_buff *skb = tx_buf->data; +- +- bytes[0] += skb->len; +- done[0]++; +- } ++ if (tx_buf->type == MTK_TYPE_SKB) ++ mtk_poll_tx_done(eth, state, 0, tx_buf->data); + budget--; + } + mtk_tx_unmap(eth, tx_buf, &bq, true); +@@ -2088,26 +2197,15 @@ static int mtk_poll_tx(struct mtk_eth *e + { + struct mtk_tx_ring *ring = ð->tx_ring; + struct dim_sample dim_sample = {}; +- unsigned int done[MTK_MAX_DEVS]; +- unsigned int bytes[MTK_MAX_DEVS]; +- int total = 0, i; +- +- memset(done, 0, sizeof(done)); +- memset(bytes, 0, sizeof(bytes)); ++ struct mtk_poll_state state = {}; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) +- budget = mtk_poll_tx_qdma(eth, budget, done, bytes); ++ budget = mtk_poll_tx_qdma(eth, budget, &state); + else +- budget = mtk_poll_tx_pdma(eth, budget, done, bytes); ++ budget = mtk_poll_tx_pdma(eth, budget, &state); + +- for (i = 0; i < MTK_MAC_COUNT; i++) { +- if (!eth->netdev[i] || !done[i]) +- continue; +- netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); +- total += done[i]; +- eth->tx_packets += done[i]; +- eth->tx_bytes += bytes[i]; +- } ++ if (state.txq) ++ netdev_tx_completed_queue(state.txq, state.done, state.bytes); + + dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes, + &dim_sample); +@@ -2117,7 +2215,7 @@ static int mtk_poll_tx(struct mtk_eth *e + (atomic_read(&ring->free_count) > ring->thresh)) + mtk_wake_queue(eth); + +- return total; ++ return state.total; + } + + static void mtk_handle_status_irq(struct mtk_eth *eth) +@@ -2203,6 +2301,7 @@ static int mtk_tx_alloc(struct mtk_eth * + int i, sz = soc->txrx.txd_size; + struct mtk_tx_dma_v2 *txd; + int ring_size; ++ u32 ofs, val; + + if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) + ring_size = MTK_QDMA_RING_SIZE; +@@ -2270,8 +2369,25 @@ static int mtk_tx_alloc(struct mtk_eth * + ring->phys + ((ring_size - 1) * sz), + soc->reg_map->qdma.crx_ptr); + mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); +- mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, +- soc->reg_map->qdma.qtx_cfg); ++ ++ for (i = 0, ofs = 0; i < MTK_QDMA_NUM_QUEUES; i++) { ++ val = (QDMA_RES_THRES << 8) | QDMA_RES_THRES; ++ mtk_w32(eth, val, soc->reg_map->qdma.qtx_cfg + ofs); ++ ++ val = MTK_QTX_SCH_MIN_RATE_EN | ++ /* minimum: 10 Mbps */ ++ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | ++ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | ++ MTK_QTX_SCH_LEAKY_BUCKET_SIZE; ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; ++ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); ++ ofs += MTK_QTX_OFFSET; ++ } ++ val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16); ++ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4); + } else { + mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); + mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); +@@ -2938,7 +3054,7 @@ static int mtk_start_dma(struct mtk_eth + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) + val |= MTK_MUTLI_CNT | MTK_RESV_BUF | + MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | +- MTK_CHK_DDONE_EN; ++ MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; + else + val |= MTK_RX_BT_32DWORDS; + mtk_w32(eth, val, reg_map->qdma.glo_cfg); +@@ -2984,6 +3100,45 @@ static void mtk_gdm_config(struct mtk_et + mtk_w32(eth, 0, MTK_RST_GL); + } + ++static int mtk_device_event(struct notifier_block *n, unsigned long event, void *ptr) ++{ ++ struct mtk_mac *mac = container_of(n, struct mtk_mac, device_notifier); ++ struct mtk_eth *eth = mac->hw; ++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); ++ struct ethtool_link_ksettings s; ++ struct net_device *ldev; ++ struct list_head *iter; ++ struct dsa_port *dp; ++ ++ if (event != NETDEV_CHANGE) ++ return NOTIFY_DONE; ++ ++ netdev_for_each_lower_dev(dev, ldev, iter) { ++ if (netdev_priv(ldev) == mac) ++ goto found; ++ } ++ ++ return NOTIFY_DONE; ++ ++found: ++ if (!dsa_slave_dev_check(dev)) ++ return NOTIFY_DONE; ++ ++ if (__ethtool_get_link_ksettings(dev, &s)) ++ return NOTIFY_DONE; ++ ++ if (s.base.speed == 0 || s.base.speed == ((__u32)-1)) ++ return NOTIFY_DONE; ++ ++ dp = dsa_port_from_netdev(dev); ++ if (dp->index >= MTK_QDMA_NUM_QUEUES) ++ return NOTIFY_DONE; ++ ++ mtk_set_queue_speed(eth, dp->index + 3, s.base.speed); ++ ++ return NOTIFY_DONE; ++} ++ + static int mtk_open(struct net_device *dev) + { + struct mtk_mac *mac = netdev_priv(dev); +@@ -3026,7 +3181,8 @@ static int mtk_open(struct net_device *d + refcount_inc(ð->dma_refcnt); + + phylink_start(mac->phylink); +- netif_start_queue(dev); ++ netif_tx_start_all_queues(dev); ++ + return 0; + } + +@@ -3542,8 +3698,12 @@ static int mtk_unreg_dev(struct mtk_eth + int i; + + for (i = 0; i < MTK_MAC_COUNT; i++) { ++ struct mtk_mac *mac; + if (!eth->netdev[i]) + continue; ++ mac = netdev_priv(eth->netdev[i]); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) ++ unregister_netdevice_notifier(&mac->device_notifier); + unregister_netdev(eth->netdev[i]); + } + +@@ -3759,6 +3919,23 @@ static int mtk_set_rxnfc(struct net_devi + return ret; + } + ++static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev) ++{ ++ struct mtk_mac *mac = netdev_priv(dev); ++ unsigned int queue = 0; ++ ++ if (netdev_uses_dsa(dev)) ++ queue = skb_get_queue_mapping(skb) + 3; ++ else ++ queue = mac->id; ++ ++ if (queue >= dev->num_tx_queues) ++ queue = 0; ++ ++ return queue; ++} ++ + static const struct ethtool_ops mtk_ethtool_ops = { + .get_link_ksettings = mtk_get_link_ksettings, + .set_link_ksettings = mtk_set_link_ksettings, +@@ -3794,6 +3971,7 @@ static const struct net_device_ops mtk_n + .ndo_setup_tc = mtk_eth_setup_tc, + .ndo_bpf = mtk_xdp, + .ndo_xdp_xmit = mtk_xdp_xmit, ++ .ndo_select_queue = mtk_select_queue, + }; + + static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) +@@ -3803,6 +3981,7 @@ static int mtk_add_mac(struct mtk_eth *e + struct phylink *phylink; + struct mtk_mac *mac; + int id, err; ++ int txqs = 1; + + if (!_id) { + dev_err(eth->dev, "missing mac id\n"); +@@ -3820,7 +3999,10 @@ static int mtk_add_mac(struct mtk_eth *e + return -EINVAL; + } + +- eth->netdev[id] = alloc_etherdev(sizeof(*mac)); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) ++ txqs = MTK_QDMA_NUM_QUEUES; ++ ++ eth->netdev[id] = alloc_etherdev_mqs(sizeof(*mac), txqs, 1); + if (!eth->netdev[id]) { + dev_err(eth->dev, "alloc_etherdev failed\n"); + return -ENOMEM; +@@ -3917,6 +4099,11 @@ static int mtk_add_mac(struct mtk_eth *e + else + eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN; + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { ++ mac->device_notifier.notifier_call = mtk_device_event; ++ register_netdevice_notifier(&mac->device_notifier); ++ } ++ + return 0; + + free_netdev: +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -22,6 +22,7 @@ + #include + #include "mtk_ppe.h" + ++#define MTK_QDMA_NUM_QUEUES 16 + #define MTK_QDMA_PAGE_SIZE 2048 + #define MTK_MAX_RX_LENGTH 1536 + #define MTK_MAX_RX_LENGTH_2K 2048 +@@ -203,8 +204,26 @@ + #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) + + /* QDMA TX Queue Configuration Registers */ ++#define MTK_QTX_OFFSET 0x10 + #define QDMA_RES_THRES 4 + ++/* QDMA Tx Queue Scheduler Configuration Registers */ ++#define MTK_QTX_SCH_TX_SEL BIT(31) ++#define MTK_QTX_SCH_TX_SEL_V2 GENMASK(31, 30) ++ ++#define MTK_QTX_SCH_LEAKY_BUCKET_EN BIT(30) ++#define MTK_QTX_SCH_LEAKY_BUCKET_SIZE GENMASK(29, 28) ++#define MTK_QTX_SCH_MIN_RATE_EN BIT(27) ++#define MTK_QTX_SCH_MIN_RATE_MAN GENMASK(26, 20) ++#define MTK_QTX_SCH_MIN_RATE_EXP GENMASK(19, 16) ++#define MTK_QTX_SCH_MAX_RATE_WEIGHT GENMASK(15, 12) ++#define MTK_QTX_SCH_MAX_RATE_EN BIT(11) ++#define MTK_QTX_SCH_MAX_RATE_MAN GENMASK(10, 4) ++#define MTK_QTX_SCH_MAX_RATE_EXP GENMASK(3, 0) ++ ++/* QDMA TX Scheduler Rate Control Register */ ++#define MTK_QDMA_TX_SCH_MAX_WFQ BIT(15) ++ + /* QDMA Global Configuration Register */ + #define MTK_RX_2B_OFFSET BIT(31) + #define MTK_RX_BT_32DWORDS (3 << 11) +@@ -223,6 +242,7 @@ + #define MTK_WCOMP_EN BIT(24) + #define MTK_RESV_BUF (0x40 << 16) + #define MTK_MUTLI_CNT (0x4 << 12) ++#define MTK_LEAKY_BUCKET_EN BIT(11) + + /* QDMA Flow Control Register */ + #define FC_THRES_DROP_MODE BIT(20) +@@ -251,8 +271,6 @@ + #define MTK_STAT_OFFSET 0x40 + + /* QDMA TX NUM */ +-#define MTK_QDMA_TX_NUM 16 +-#define MTK_QDMA_TX_MASK (MTK_QDMA_TX_NUM - 1) + #define QID_BITS_V2(x) (((x) & 0x3f) << 16) + #define MTK_QDMA_GMAC2_QID 8 + +@@ -282,6 +300,7 @@ + #define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) + #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) + #define TX_DMA_SWC BIT(14) ++#define TX_DMA_PQID GENMASK(3, 0) + + /* PDMA on MT7628 */ + #define TX_DMA_DONE BIT(31) +@@ -933,6 +952,7 @@ struct mtk_reg_map { + } pdma; + struct { + u32 qtx_cfg; /* tx queue configuration */ ++ u32 qtx_sch; /* tx queue scheduler configuration */ + u32 rx_ptr; /* rx base pointer */ + u32 rx_cnt_cfg; /* rx max count configuration */ + u32 qcrx_ptr; /* rx cpu pointer */ +@@ -950,6 +970,7 @@ struct mtk_reg_map { + u32 fq_tail; /* fq tail pointer */ + u32 fq_count; /* fq free page count */ + u32 fq_blen; /* fq free page buffer length */ ++ u32 tx_sch_rate; /* tx scheduler rate control registers */ + } qdma; + u32 gdm1_cnt; + u32 gdma_to_ppe; +@@ -1141,6 +1162,7 @@ struct mtk_mac { + __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; + int hwlro_ip_cnt; + unsigned int syscfg0; ++ struct notifier_block device_notifier; + }; + + /* the struct describing the SoC. these are declared in the soc_xyz.c files */ diff --git a/target/linux/generic/pending-6.1/732-05-net-dsa-tag_mtk-assign-per-port-queues.patch b/target/linux/generic/pending-6.1/732-05-net-dsa-tag_mtk-assign-per-port-queues.patch new file mode 100644 index 000000000..7739366ad --- /dev/null +++ b/target/linux/generic/pending-6.1/732-05-net-dsa-tag_mtk-assign-per-port-queues.patch @@ -0,0 +1,20 @@ +From: Felix Fietkau +Date: Fri, 28 Oct 2022 18:16:03 +0200 +Subject: [PATCH] net: dsa: tag_mtk: assign per-port queues + +Keeps traffic sent to the switch within link speed limits + +Signed-off-by: Felix Fietkau +--- + +--- a/net/dsa/tag_mtk.c ++++ b/net/dsa/tag_mtk.c +@@ -33,6 +33,8 @@ static struct sk_buff *mtk_tag_xmit(stru + if (__skb_put_padto(skb, ETH_ZLEN + MTK_HDR_LEN, false)) + return NULL; + ++ skb_set_queue_mapping(skb, dp->index); ++ + /* Build the special tag after the MAC Source Address. If VLAN header + * is present, it's required that VLAN header and special tag is + * being combined. Only in this way we can allow the switch can parse diff --git a/target/linux/generic/pending-6.1/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch b/target/linux/generic/pending-6.1/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch new file mode 100644 index 000000000..d29177eee --- /dev/null +++ b/target/linux/generic/pending-6.1/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch @@ -0,0 +1,93 @@ +From: Felix Fietkau +Date: Thu, 3 Nov 2022 17:49:44 +0100 +Subject: [PATCH] net: ethernet: mediatek: ppe: assign per-port queues + for offloaded traffic + +Keeps traffic sent to the switch within link speed limits + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -399,6 +399,24 @@ int mtk_foe_entry_set_wdma(struct mtk_et + return 0; + } + ++int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ unsigned int queue) ++{ ++ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ *ib2 &= ~MTK_FOE_IB2_QID_V2; ++ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue); ++ *ib2 |= MTK_FOE_IB2_PSE_QOS_V2; ++ } else { ++ *ib2 &= ~MTK_FOE_IB2_QID; ++ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID, queue); ++ *ib2 |= MTK_FOE_IB2_PSE_QOS; ++ } ++ ++ return 0; ++} ++ + static bool + mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, + struct mtk_foe_entry *data) +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -68,7 +68,9 @@ enum { + #define MTK_FOE_IB2_DSCP GENMASK(31, 24) + + /* CONFIG_MEDIATEK_NETSYS_V2 */ ++#define MTK_FOE_IB2_QID_V2 GENMASK(6, 0) + #define MTK_FOE_IB2_PORT_MG_V2 BIT(7) ++#define MTK_FOE_IB2_PSE_QOS_V2 BIT(8) + #define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) + #define MTK_FOE_IB2_MULTICAST_V2 BIT(13) + #define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) +@@ -351,6 +353,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e + int sid); + int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, + int wdma_idx, int txq, int bss, int wcid); ++int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ unsigned int queue); + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); + void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); + int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -188,7 +188,7 @@ mtk_flow_set_output_device(struct mtk_et + int *wed_index) + { + struct mtk_wdma_info info = {}; +- int pse_port, dsa_port; ++ int pse_port, dsa_port, queue; + + if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { + mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, +@@ -212,8 +212,6 @@ mtk_flow_set_output_device(struct mtk_et + } + + dsa_port = mtk_flow_get_dsa_port(&dev); +- if (dsa_port >= 0) +- mtk_foe_entry_set_dsa(eth, foe, dsa_port); + + if (dev == eth->netdev[0]) + pse_port = 1; +@@ -222,6 +220,14 @@ mtk_flow_set_output_device(struct mtk_et + else + return -EOPNOTSUPP; + ++ if (dsa_port >= 0) { ++ mtk_foe_entry_set_dsa(eth, foe, dsa_port); ++ queue = 3 + dsa_port; ++ } else { ++ queue = pse_port - 1; ++ } ++ mtk_foe_entry_set_queue(eth, foe, queue); ++ + out: + mtk_foe_entry_set_pse_port(eth, foe, pse_port); + diff --git a/target/linux/generic/pending-6.1/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-6.1/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch new file mode 100644 index 000000000..289347e02 --- /dev/null +++ b/target/linux/generic/pending-6.1/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch @@ -0,0 +1,28 @@ +From: Felix Fietkau +Date: Thu, 27 Oct 2022 23:39:52 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code + on mt7621 + +Avoid some branches in the hot path on low-end devices with limited CPU power, +and reduce code size + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -898,7 +898,13 @@ enum mkt_eth_capabilities { + #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ + (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) + +-#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) ++#ifdef CONFIG_SOC_MT7621 ++#define MTK_CAP_MASK MTK_NETSYS_V2 ++#else ++#define MTK_CAP_MASK 0 ++#endif ++ ++#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x)) + + #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ + MTK_GMAC2_RGMII | MTK_SHARED_INT | \ diff --git a/target/linux/generic/pending-6.1/732-08-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch b/target/linux/generic/pending-6.1/732-08-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch new file mode 100644 index 000000000..6b7f3d601 --- /dev/null +++ b/target/linux/generic/pending-6.1/732-08-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch @@ -0,0 +1,72 @@ +From: Felix Fietkau +Date: Tue, 8 Nov 2022 15:03:15 +0100 +Subject: [PATCH] net: dsa: add support for DSA rx offloading via + metadata dst + +If a metadata dst is present with the type METADATA_HW_PORT_MUX on a dsa cpu +port netdev, assume that it carries the port number and that there is no DSA +tag present in the skb data. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -971,12 +971,14 @@ bool __skb_flow_dissect(const struct net + #if IS_ENABLED(CONFIG_NET_DSA) + if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) && + proto == htons(ETH_P_XDSA))) { ++ struct metadata_dst *md_dst = skb_metadata_dst(skb); + const struct dsa_device_ops *ops; + int offset = 0; + + ops = skb->dev->dsa_ptr->tag_ops; + /* Only DSA header taggers break flow dissection */ +- if (ops->needed_headroom) { ++ if (ops->needed_headroom && ++ (!md_dst || md_dst->type != METADATA_HW_PORT_MUX)) { + if (ops->flow_dissect) + ops->flow_dissect(skb, &proto, &offset); + else +--- a/net/dsa/dsa.c ++++ b/net/dsa/dsa.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #include "dsa_priv.h" + +@@ -216,6 +217,7 @@ static bool dsa_skb_defer_rx_timestamp(s + static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *unused) + { ++ struct metadata_dst *md_dst = skb_metadata_dst(skb); + struct dsa_port *cpu_dp = dev->dsa_ptr; + struct sk_buff *nskb = NULL; + struct dsa_slave_priv *p; +@@ -229,7 +231,22 @@ static int dsa_switch_rcv(struct sk_buff + if (!skb) + return 0; + +- nskb = cpu_dp->rcv(skb, dev); ++ if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) { ++ unsigned int port = md_dst->u.port_info.port_id; ++ ++ skb_dst_drop(skb); ++ if (!skb_has_extensions(skb)) ++ skb->slow_gro = 0; ++ ++ skb->dev = dsa_master_find_slave(dev, 0, port); ++ if (likely(skb->dev)) { ++ dsa_default_offload_fwd_mark(skb); ++ nskb = skb; ++ } ++ } else { ++ nskb = cpu_dp->rcv(skb, dev); ++ } ++ + if (!nskb) { + kfree_skb(skb); + return 0; diff --git a/target/linux/generic/pending-6.1/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch b/target/linux/generic/pending-6.1/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch new file mode 100644 index 000000000..ef0df5f0f --- /dev/null +++ b/target/linux/generic/pending-6.1/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch @@ -0,0 +1,192 @@ +From: Felix Fietkau +Date: Fri, 28 Oct 2022 11:01:12 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix VLAN rx hardware + acceleration + +- enable VLAN untagging for PDMA rx +- make it possible to disable the feature via ethtool +- pass VLAN tag to the DSA driver +- untag special tag on PDMA only if no non-DSA devices are in use +- disable special tag untagging on 7986 for now, since it's not working yet + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #include "mtk_eth_soc.h" + #include "mtk_wed.h" +@@ -2015,16 +2016,22 @@ static int mtk_poll_rx(struct napi_struc + htons(RX_DMA_VPID(trxd.rxd4)), + RX_DMA_VID(trxd.rxd4)); + } else if (trxd.rxd2 & RX_DMA_VTAG) { +- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ++ __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)), + RX_DMA_VID(trxd.rxd3)); + } ++ } ++ ++ /* When using VLAN untagging in combination with DSA, the ++ * hardware treats the MTK special tag as a VLAN and untags it. ++ */ ++ if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) { ++ unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0); + +- /* If the device is attached to a dsa switch, the special +- * tag inserted in VLAN field by hw switch can * be offloaded +- * by RX HW VLAN offload. Clear vlan info. +- */ +- if (netdev_uses_dsa(netdev)) +- __vlan_hwaccel_clear_tag(skb); ++ if (port < ARRAY_SIZE(eth->dsa_meta) && ++ eth->dsa_meta[port]) ++ skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); ++ ++ __vlan_hwaccel_clear_tag(skb); + } + + skb_record_rx_queue(skb, 0); +@@ -2849,15 +2856,30 @@ static netdev_features_t mtk_fix_feature + + static int mtk_set_features(struct net_device *dev, netdev_features_t features) + { +- int err = 0; ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ netdev_features_t diff = dev->features ^ features; ++ int i; ++ ++ if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO)) ++ mtk_hwlro_netdev_disable(dev); + +- if (!((dev->features ^ features) & NETIF_F_LRO)) ++ /* Set RX VLAN offloading */ ++ if (!(diff & NETIF_F_HW_VLAN_CTAG_RX)) + return 0; + +- if (!(features & NETIF_F_LRO)) +- mtk_hwlro_netdev_disable(dev); ++ mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX), ++ MTK_CDMP_EG_CTRL); + +- return err; ++ /* sync features with other MAC */ ++ for (i = 0; i < MTK_MAC_COUNT; i++) { ++ if (!eth->netdev[i] || eth->netdev[i] == dev) ++ continue; ++ eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX; ++ eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX; ++ } ++ ++ return 0; + } + + /* wait for DMA to finish whatever it is doing before we start using it again */ +@@ -3139,11 +3161,45 @@ found: + return NOTIFY_DONE; + } + ++static bool mtk_uses_dsa(struct net_device *dev) ++{ ++#if IS_ENABLED(CONFIG_NET_DSA) ++ return netdev_uses_dsa(dev) && ++ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK; ++#else ++ return false; ++#endif ++} ++ + static int mtk_open(struct net_device *dev) + { + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; +- int err; ++ int i, err; ++ ++ if (mtk_uses_dsa(dev) && !eth->prog) { ++ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { ++ struct metadata_dst *md_dst = eth->dsa_meta[i]; ++ ++ if (md_dst) ++ continue; ++ ++ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, ++ GFP_KERNEL); ++ if (!md_dst) ++ return -ENOMEM; ++ ++ md_dst->u.port_info.port_id = i; ++ eth->dsa_meta[i] = md_dst; ++ } ++ } else { ++ /* Hardware special tag parsing needs to be disabled if at least ++ * one MAC does not use DSA. ++ */ ++ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); ++ val &= ~MTK_CDMP_STAG_EN; ++ mtk_w32(eth, val, MTK_CDMP_IG_CTRL); ++ } + + err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); + if (err) { +@@ -3473,6 +3529,10 @@ static int mtk_hw_init(struct mtk_eth *e + */ + val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); + mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ val = mtk_r32(eth, MTK_CDMP_IG_CTRL); ++ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); ++ } + + /* Enable RX VLan Offloading */ + mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); +@@ -3690,6 +3750,12 @@ static int mtk_free_dev(struct mtk_eth * + free_netdev(eth->netdev[i]); + } + ++ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { ++ if (!eth->dsa_meta[i]) ++ break; ++ metadata_dst_free(eth->dsa_meta[i]); ++ } ++ + return 0; + } + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -22,6 +22,9 @@ + #include + #include "mtk_ppe.h" + ++#define MTK_MAX_DSA_PORTS 7 ++#define MTK_DSA_PORT_MASK GENMASK(2, 0) ++ + #define MTK_QDMA_NUM_QUEUES 16 + #define MTK_QDMA_PAGE_SIZE 2048 + #define MTK_MAX_RX_LENGTH 1536 +@@ -93,6 +96,9 @@ + #define MTK_CDMQ_IG_CTRL 0x1400 + #define MTK_CDMQ_STAG_EN BIT(0) + ++/* CDMQ Exgress Control Register */ ++#define MTK_CDMQ_EG_CTRL 0x1404 ++ + /* CDMP Ingress Control Register */ + #define MTK_CDMP_IG_CTRL 0x400 + #define MTK_CDMP_STAG_EN BIT(0) +@@ -1142,6 +1148,8 @@ struct mtk_eth { + + int ip_align; + ++ struct metadata_dst *dsa_meta[MTK_MAX_DSA_PORTS]; ++ + struct mtk_ppe *ppe[2]; + struct rhashtable flow_table; + diff --git a/target/linux/generic/pending-6.1/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-6.1/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch new file mode 100644 index 000000000..5f32218bb --- /dev/null +++ b/target/linux/generic/pending-6.1/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch @@ -0,0 +1,78 @@ +From: Felix Fietkau +Date: Thu, 3 Nov 2022 12:38:49 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: work around issue with + sending small fragments + +When frames are sent with very small fragments, the DMA engine appears to +lock up and transmit attempts time out. Fix this by detecting the presence +of small fragments and use skb_gso_segment + skb_linearize to deal with +them + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1442,12 +1442,28 @@ static void mtk_wake_queue(struct mtk_et + } + } + ++static bool mtk_skb_has_small_frag(struct sk_buff *skb) ++{ ++ int min_size = 16; ++ int i; ++ ++ if (skb_headlen(skb) < min_size) ++ return true; ++ ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) ++ if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size) ++ return true; ++ ++ return false; ++} ++ + static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + struct mtk_tx_ring *ring = ð->tx_ring; + struct net_device_stats *stats = &dev->stats; ++ struct sk_buff *segs, *next; + bool gso = false; + int tx_num; + +@@ -1469,6 +1485,17 @@ static netdev_tx_t mtk_start_xmit(struct + return NETDEV_TX_BUSY; + } + ++ if (skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { ++ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); ++ if (IS_ERR(segs)) ++ goto drop; ++ ++ if (segs) { ++ consume_skb(skb); ++ skb = segs; ++ } ++ } ++ + /* TSO: fill MSS info in tcp checksum field */ + if (skb_is_gso(skb)) { + if (skb_cow_head(skb, 0)) { +@@ -1484,8 +1511,13 @@ static netdev_tx_t mtk_start_xmit(struct + } + } + +- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) +- goto drop; ++ skb_list_walk_safe(skb, skb, next) { ++ if ((mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || ++ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { ++ stats->tx_dropped++; ++ dev_kfree_skb_any(skb); ++ } ++ } + + if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) + netif_tx_stop_all_queues(dev); diff --git a/target/linux/generic/pending-6.1/732-11-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-6.1/732-11-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch new file mode 100644 index 000000000..f89ad6adb --- /dev/null +++ b/target/linux/generic/pending-6.1/732-11-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Fri, 28 Oct 2022 12:54:48 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: set NETIF_F_ALL_TSO + +Significantly improves performance by avoiding unnecessary segmentation + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -49,8 +49,7 @@ + NETIF_F_RXCSUM | \ + NETIF_F_HW_VLAN_CTAG_TX | \ + NETIF_F_HW_VLAN_CTAG_RX | \ +- NETIF_F_SG | NETIF_F_TSO | \ +- NETIF_F_TSO6 | \ ++ NETIF_F_SG | NETIF_F_ALL_TSO | \ + NETIF_F_IPV6_CSUM |\ + NETIF_F_HW_TC) + #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM) diff --git a/target/linux/generic/pending-6.1/732-12-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch b/target/linux/generic/pending-6.1/732-12-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch new file mode 100644 index 000000000..b0e80d263 --- /dev/null +++ b/target/linux/generic/pending-6.1/732-12-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch @@ -0,0 +1,37 @@ +From: Felix Fietkau +Date: Thu, 3 Nov 2022 17:46:25 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: drop packets to WDMA if the + ring is full + +Improves handling of DMA ring overflow. +Clarify other WDMA drop related comment. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3585,9 +3585,12 @@ static int mtk_hw_init(struct mtk_eth *e + mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { +- /* PSE should not drop port8 and port9 packets */ ++ /* PSE should not drop port8 and port9 packets from WDMA Tx */ + mtk_w32(eth, 0x00000300, PSE_DROP_CFG); + ++ /* PSE should drop packets to port 8/9 on WDMA Rx ring full */ ++ mtk_w32(eth, 0x00000300, PSE_PPE0_DROP); ++ + /* PSE Free Queue Flow Control */ + mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2); + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -127,6 +127,7 @@ + #define PSE_FQFC_CFG1 0x100 + #define PSE_FQFC_CFG2 0x104 + #define PSE_DROP_CFG 0x108 ++#define PSE_PPE0_DROP 0x110 + + /* PSE Input Queue Reservation Register*/ + #define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2)) diff --git a/target/linux/generic/pending-6.1/732-13-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch b/target/linux/generic/pending-6.1/732-13-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch new file mode 100644 index 000000000..54e48df44 --- /dev/null +++ b/target/linux/generic/pending-6.1/732-13-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch @@ -0,0 +1,52 @@ +From: Felix Fietkau +Date: Thu, 17 Nov 2022 11:58:21 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix flow_offload related refcount + bug + +Since we call flow_block_cb_decref on FLOW_BLOCK_UNBIND, we need to call +flow_block_cb_incref unconditionally, even for a newly allocated cb. +Fixes a use-after-free bug + +Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support") +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -554,6 +554,7 @@ mtk_eth_setup_tc_block(struct net_device + struct mtk_eth *eth = mac->hw; + static LIST_HEAD(block_cb_list); + struct flow_block_cb *block_cb; ++ bool register_block = false; + flow_setup_cb_t *cb; + + if (!eth->soc->offload_version) +@@ -568,16 +569,20 @@ mtk_eth_setup_tc_block(struct net_device + switch (f->command) { + case FLOW_BLOCK_BIND: + block_cb = flow_block_cb_lookup(f->block, cb, dev); +- if (block_cb) { +- flow_block_cb_incref(block_cb); +- return 0; ++ if (!block_cb) { ++ block_cb = flow_block_cb_alloc(cb, dev, dev, NULL); ++ if (IS_ERR(block_cb)) ++ return PTR_ERR(block_cb); ++ ++ register_block = true; + } +- block_cb = flow_block_cb_alloc(cb, dev, dev, NULL); +- if (IS_ERR(block_cb)) +- return PTR_ERR(block_cb); + +- flow_block_cb_add(block_cb, f); +- list_add_tail(&block_cb->driver_list, &block_cb_list); ++ flow_block_cb_incref(block_cb); ++ ++ if (register_block) { ++ flow_block_cb_add(block_cb, f); ++ list_add_tail(&block_cb->driver_list, &block_cb_list); ++ } + return 0; + case FLOW_BLOCK_UNBIND: + block_cb = flow_block_cb_lookup(f->block, cb, dev); diff --git a/target/linux/generic/pending-6.1/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/pending-6.1/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch new file mode 100644 index 000000000..94dd8018f --- /dev/null +++ b/target/linux/generic/pending-6.1/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch @@ -0,0 +1,181 @@ +From: Felix Fietkau +Date: Sun, 20 Nov 2022 23:01:00 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload, + only use DSA untagging + +Through testing I found out that hardware vlan rx offload support seems to +have some hardware issues. At least when using multiple MACs and when receiving +tagged packets on the secondary MAC, the hardware can sometimes start to emit +wrong tags on the first MAC as well. + +In order to avoid such issues, drop the feature configuration and use the +offload feature only for DSA hardware untagging on MT7621/MT7622 devices which +only use one MAC. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2041,29 +2041,16 @@ static int mtk_poll_rx(struct napi_struc + if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) + mtk_ppe_check_skb(eth->ppe[0], skb, hash); + +- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { +- if (trxd.rxd3 & RX_DMA_VTAG_V2) +- __vlan_hwaccel_put_tag(skb, +- htons(RX_DMA_VPID(trxd.rxd4)), +- RX_DMA_VID(trxd.rxd4)); +- } else if (trxd.rxd2 & RX_DMA_VTAG) { +- __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)), +- RX_DMA_VID(trxd.rxd3)); +- } +- } +- + /* When using VLAN untagging in combination with DSA, the + * hardware treats the MTK special tag as a VLAN and untags it. + */ +- if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) { +- unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0); ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && ++ (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { ++ unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); + + if (port < ARRAY_SIZE(eth->dsa_meta) && + eth->dsa_meta[port]) + skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); +- +- __vlan_hwaccel_clear_tag(skb); + } + + skb_record_rx_queue(skb, 0); +@@ -2888,29 +2875,11 @@ static netdev_features_t mtk_fix_feature + + static int mtk_set_features(struct net_device *dev, netdev_features_t features) + { +- struct mtk_mac *mac = netdev_priv(dev); +- struct mtk_eth *eth = mac->hw; + netdev_features_t diff = dev->features ^ features; +- int i; + + if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO)) + mtk_hwlro_netdev_disable(dev); + +- /* Set RX VLAN offloading */ +- if (!(diff & NETIF_F_HW_VLAN_CTAG_RX)) +- return 0; +- +- mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX), +- MTK_CDMP_EG_CTRL); +- +- /* sync features with other MAC */ +- for (i = 0; i < MTK_MAC_COUNT; i++) { +- if (!eth->netdev[i] || eth->netdev[i] == dev) +- continue; +- eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX; +- eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX; +- } +- + return 0; + } + +@@ -3209,30 +3178,6 @@ static int mtk_open(struct net_device *d + struct mtk_eth *eth = mac->hw; + int i, err; + +- if (mtk_uses_dsa(dev) && !eth->prog) { +- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { +- struct metadata_dst *md_dst = eth->dsa_meta[i]; +- +- if (md_dst) +- continue; +- +- md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, +- GFP_KERNEL); +- if (!md_dst) +- return -ENOMEM; +- +- md_dst->u.port_info.port_id = i; +- eth->dsa_meta[i] = md_dst; +- } +- } else { +- /* Hardware special tag parsing needs to be disabled if at least +- * one MAC does not use DSA. +- */ +- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); +- val &= ~MTK_CDMP_STAG_EN; +- mtk_w32(eth, val, MTK_CDMP_IG_CTRL); +- } +- + err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); + if (err) { + netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, +@@ -3271,6 +3216,35 @@ static int mtk_open(struct net_device *d + phylink_start(mac->phylink); + netif_tx_start_all_queues(dev); + ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return 0; ++ ++ if (mtk_uses_dsa(dev) && !eth->prog) { ++ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { ++ struct metadata_dst *md_dst = eth->dsa_meta[i]; ++ ++ if (md_dst) ++ continue; ++ ++ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, ++ GFP_KERNEL); ++ if (!md_dst) ++ return -ENOMEM; ++ ++ md_dst->u.port_info.port_id = i; ++ eth->dsa_meta[i] = md_dst; ++ } ++ } else { ++ /* Hardware special tag parsing needs to be disabled if at least ++ * one MAC does not use DSA. ++ */ ++ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); ++ val &= ~MTK_CDMP_STAG_EN; ++ mtk_w32(eth, val, MTK_CDMP_IG_CTRL); ++ ++ mtk_w32(eth, 0, MTK_CDMP_EG_CTRL); ++ } ++ + return 0; + } + +@@ -3564,10 +3538,9 @@ static int mtk_hw_init(struct mtk_eth *e + if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { + val = mtk_r32(eth, MTK_CDMP_IG_CTRL); + mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); +- } + +- /* Enable RX VLan Offloading */ +- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); ++ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); ++ } + + /* set interrupt delays based on current Net DIM sample */ + mtk_dim_rx(ð->rx_dim.work); +@@ -4188,7 +4161,7 @@ static int mtk_add_mac(struct mtk_eth *e + eth->netdev[id]->hw_features |= NETIF_F_LRO; + + eth->netdev[id]->vlan_features = eth->soc->hw_features & +- ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); ++ ~NETIF_F_HW_VLAN_CTAG_TX; + eth->netdev[id]->features |= eth->soc->hw_features; + eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops; + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -48,7 +48,6 @@ + #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \ + NETIF_F_RXCSUM | \ + NETIF_F_HW_VLAN_CTAG_TX | \ +- NETIF_F_HW_VLAN_CTAG_RX | \ + NETIF_F_SG | NETIF_F_ALL_TSO | \ + NETIF_F_IPV6_CSUM |\ + NETIF_F_HW_TC) diff --git a/target/linux/generic/pending-6.1/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch b/target/linux/generic/pending-6.1/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch new file mode 100644 index 000000000..c48613929 --- /dev/null +++ b/target/linux/generic/pending-6.1/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch @@ -0,0 +1,591 @@ +From: Sujuan Chen +Date: Sat, 5 Nov 2022 23:36:18 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: introduce wed mcu support + +Introduce WED mcu support used to configure WED WO chip. +This is a preliminary patch in order to add RX Wireless +Ethernet Dispatch available on MT7986 SoC. + +Tested-by: Daniel Golle +Co-developed-by: Lorenzo Bianconi +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Sujuan Chen +Signed-off-by: David S. Miller +--- + create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_mcu.c + create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.h + +--- a/drivers/net/ethernet/mediatek/Makefile ++++ b/drivers/net/ethernet/mediatek/Makefile +@@ -5,7 +5,7 @@ + + obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o + mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o +-mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o ++mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o + ifdef CONFIG_DEBUG_FS + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o + endif +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c +@@ -0,0 +1,359 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (C) 2022 MediaTek Inc. ++ * ++ * Author: Lorenzo Bianconi ++ * Sujuan Chen ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "mtk_wed_regs.h" ++#include "mtk_wed_wo.h" ++#include "mtk_wed.h" ++ ++static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg) ++{ ++ return readl(wo->boot.addr + reg); ++} ++ ++static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) ++{ ++ writel(val, wo->boot.addr + reg); ++} ++ ++static struct sk_buff * ++mtk_wed_mcu_msg_alloc(const void *data, int data_len) ++{ ++ int length = sizeof(struct mtk_wed_mcu_hdr) + data_len; ++ struct sk_buff *skb; ++ ++ skb = alloc_skb(length, GFP_KERNEL); ++ if (!skb) ++ return NULL; ++ ++ memset(skb->head, 0, length); ++ skb_reserve(skb, sizeof(struct mtk_wed_mcu_hdr)); ++ if (data && data_len) ++ skb_put_data(skb, data, data_len); ++ ++ return skb; ++} ++ ++static struct sk_buff * ++mtk_wed_mcu_get_response(struct mtk_wed_wo *wo, unsigned long expires) ++{ ++ if (!time_is_after_jiffies(expires)) ++ return NULL; ++ ++ wait_event_timeout(wo->mcu.wait, !skb_queue_empty(&wo->mcu.res_q), ++ expires - jiffies); ++ return skb_dequeue(&wo->mcu.res_q); ++} ++ ++void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb) ++{ ++ skb_queue_tail(&wo->mcu.res_q, skb); ++ wake_up(&wo->mcu.wait); ++} ++ ++void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, ++ struct sk_buff *skb) ++{ ++ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; ++ ++ switch (hdr->cmd) { ++ case MTK_WED_WO_EVT_LOG_DUMP: { ++ const char *msg = (const char *)(skb->data + sizeof(*hdr)); ++ ++ dev_notice(wo->hw->dev, "%s\n", msg); ++ break; ++ } ++ case MTK_WED_WO_EVT_PROFILING: { ++ struct mtk_wed_wo_log_info *info; ++ u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info); ++ int i; ++ ++ info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr)); ++ for (i = 0 ; i < count ; i++) ++ dev_notice(wo->hw->dev, ++ "SN:%u latency: total=%u, rro:%u, mod:%u\n", ++ le32_to_cpu(info[i].sn), ++ le32_to_cpu(info[i].total), ++ le32_to_cpu(info[i].rro), ++ le32_to_cpu(info[i].mod)); ++ break; ++ } ++ case MTK_WED_WO_EVT_RXCNT_INFO: ++ break; ++ default: ++ break; ++ } ++ ++ dev_kfree_skb(skb); ++} ++ ++static int ++mtk_wed_mcu_skb_send_msg(struct mtk_wed_wo *wo, struct sk_buff *skb, ++ int id, int cmd, u16 *wait_seq, bool wait_resp) ++{ ++ struct mtk_wed_mcu_hdr *hdr; ++ ++ /* TODO: make it dynamic based on cmd */ ++ wo->mcu.timeout = 20 * HZ; ++ ++ hdr = (struct mtk_wed_mcu_hdr *)skb_push(skb, sizeof(*hdr)); ++ hdr->cmd = cmd; ++ hdr->length = cpu_to_le16(skb->len); ++ ++ if (wait_resp && wait_seq) { ++ u16 seq = ++wo->mcu.seq; ++ ++ if (!seq) ++ seq = ++wo->mcu.seq; ++ *wait_seq = seq; ++ ++ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_NEED_RSP); ++ hdr->seq = cpu_to_le16(seq); ++ } ++ if (id == MTK_WED_MODULE_ID_WO) ++ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO); ++ ++ dev_kfree_skb(skb); ++ return 0; ++} ++ ++static int ++mtk_wed_mcu_parse_response(struct mtk_wed_wo *wo, struct sk_buff *skb, ++ int cmd, int seq) ++{ ++ struct mtk_wed_mcu_hdr *hdr; ++ ++ if (!skb) { ++ dev_err(wo->hw->dev, "Message %08x (seq %d) timeout\n", ++ cmd, seq); ++ return -ETIMEDOUT; ++ } ++ ++ hdr = (struct mtk_wed_mcu_hdr *)skb->data; ++ if (le16_to_cpu(hdr->seq) != seq) ++ return -EAGAIN; ++ ++ skb_pull(skb, sizeof(*hdr)); ++ switch (cmd) { ++ case MTK_WED_WO_CMD_RXCNT_INFO: ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, ++ const void *data, int len, bool wait_resp) ++{ ++ unsigned long expires; ++ struct sk_buff *skb; ++ u16 seq; ++ int ret; ++ ++ skb = mtk_wed_mcu_msg_alloc(data, len); ++ if (!skb) ++ return -ENOMEM; ++ ++ mutex_lock(&wo->mcu.mutex); ++ ++ ret = mtk_wed_mcu_skb_send_msg(wo, skb, id, cmd, &seq, wait_resp); ++ if (ret || !wait_resp) ++ goto unlock; ++ ++ expires = jiffies + wo->mcu.timeout; ++ do { ++ skb = mtk_wed_mcu_get_response(wo, expires); ++ ret = mtk_wed_mcu_parse_response(wo, skb, cmd, seq); ++ dev_kfree_skb(skb); ++ } while (ret == -EAGAIN); ++ ++unlock: ++ mutex_unlock(&wo->mcu.mutex); ++ ++ return ret; ++} ++ ++static int ++mtk_wed_get_memory_region(struct mtk_wed_wo *wo, ++ struct mtk_wed_wo_memory_region *region) ++{ ++ struct reserved_mem *rmem; ++ struct device_node *np; ++ int index; ++ ++ index = of_property_match_string(wo->hw->node, "memory-region-names", ++ region->name); ++ if (index < 0) ++ return index; ++ ++ np = of_parse_phandle(wo->hw->node, "memory-region", index); ++ if (!np) ++ return -ENODEV; ++ ++ rmem = of_reserved_mem_lookup(np); ++ of_node_put(np); ++ ++ if (!rmem) ++ return -ENODEV; ++ ++ region->phy_addr = rmem->base; ++ region->size = rmem->size; ++ region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size); ++ ++ return !region->addr ? -EINVAL : 0; ++} ++ ++static int ++mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw, ++ struct mtk_wed_wo_memory_region *region) ++{ ++ const u8 *first_region_ptr, *region_ptr, *trailer_ptr, *ptr = fw->data; ++ const struct mtk_wed_fw_trailer *trailer; ++ const struct mtk_wed_fw_region *fw_region; ++ ++ trailer_ptr = fw->data + fw->size - sizeof(*trailer); ++ trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr; ++ region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region); ++ first_region_ptr = region_ptr; ++ ++ while (region_ptr < trailer_ptr) { ++ u32 length; ++ ++ fw_region = (const struct mtk_wed_fw_region *)region_ptr; ++ length = le32_to_cpu(fw_region->len); ++ ++ if (region->phy_addr != le32_to_cpu(fw_region->addr)) ++ goto next; ++ ++ if (region->size < length) ++ goto next; ++ ++ if (first_region_ptr < ptr + length) ++ goto next; ++ ++ if (region->shared && region->consumed) ++ return 0; ++ ++ if (!region->shared || !region->consumed) { ++ memcpy_toio(region->addr, ptr, length); ++ region->consumed = true; ++ return 0; ++ } ++next: ++ region_ptr += sizeof(*fw_region); ++ ptr += length; ++ } ++ ++ return -EINVAL; ++} ++ ++static int ++mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) ++{ ++ static struct mtk_wed_wo_memory_region mem_region[] = { ++ [MTK_WED_WO_REGION_EMI] = { ++ .name = "wo-emi", ++ }, ++ [MTK_WED_WO_REGION_ILM] = { ++ .name = "wo-ilm", ++ }, ++ [MTK_WED_WO_REGION_DATA] = { ++ .name = "wo-data", ++ .shared = true, ++ }, ++ }; ++ const struct mtk_wed_fw_trailer *trailer; ++ const struct firmware *fw; ++ const char *fw_name; ++ u32 val, boot_cr; ++ int ret, i; ++ ++ /* load firmware region metadata */ ++ for (i = 0; i < ARRAY_SIZE(mem_region); i++) { ++ ret = mtk_wed_get_memory_region(wo, &mem_region[i]); ++ if (ret) ++ return ret; ++ } ++ ++ wo->boot.name = "wo-boot"; ++ ret = mtk_wed_get_memory_region(wo, &wo->boot); ++ if (ret) ++ return ret; ++ ++ /* set dummy cr */ ++ wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL, ++ wo->hw->index + 1); ++ ++ /* load firmware */ ++ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; ++ ret = request_firmware(&fw, fw_name, wo->hw->dev); ++ if (ret) ++ return ret; ++ ++ trailer = (void *)(fw->data + fw->size - ++ sizeof(struct mtk_wed_fw_trailer)); ++ dev_info(wo->hw->dev, ++ "MTK WED WO Firmware Version: %.10s, Build Time: %.15s\n", ++ trailer->fw_ver, trailer->build_date); ++ dev_info(wo->hw->dev, "MTK WED WO Chip ID %02x Region %d\n", ++ trailer->chip_id, trailer->num_region); ++ ++ for (i = 0; i < ARRAY_SIZE(mem_region); i++) { ++ ret = mtk_wed_mcu_run_firmware(wo, fw, &mem_region[i]); ++ if (ret) ++ goto out; ++ } ++ ++ /* set the start address */ ++ boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR ++ : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; ++ wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16); ++ /* wo firmware reset */ ++ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00); ++ ++ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR); ++ val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK ++ : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK; ++ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val); ++out: ++ release_firmware(fw); ++ ++ return ret; ++} ++ ++static u32 ++mtk_wed_mcu_read_fw_dl(struct mtk_wed_wo *wo) ++{ ++ return wed_r32(wo->hw->wed_dev, ++ MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL); ++} ++ ++int mtk_wed_mcu_init(struct mtk_wed_wo *wo) ++{ ++ u32 val; ++ int ret; ++ ++ skb_queue_head_init(&wo->mcu.res_q); ++ init_waitqueue_head(&wo->mcu.wait); ++ mutex_init(&wo->mcu.mutex); ++ ++ ret = mtk_wed_mcu_load_firmware(wo); ++ if (ret) ++ return ret; ++ ++ return readx_poll_timeout(mtk_wed_mcu_read_fw_dl, wo, val, !val, ++ 100, MTK_FW_DL_TIMEOUT); ++} ++ ++MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); ++MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -152,6 +152,7 @@ struct mtk_wdma_desc { + + #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10) + ++#define MTK_WED_SCR0 0x3c0 + #define MTK_WED_WPDMA_INT_TRIGGER 0x504 + #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1) + #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4) +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h +@@ -0,0 +1,150 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* Copyright (C) 2022 Lorenzo Bianconi */ ++ ++#ifndef __MTK_WED_WO_H ++#define __MTK_WED_WO_H ++ ++#include ++#include ++ ++struct mtk_wed_hw; ++ ++struct mtk_wed_mcu_hdr { ++ /* DW0 */ ++ u8 version; ++ u8 cmd; ++ __le16 length; ++ ++ /* DW1 */ ++ __le16 seq; ++ __le16 flag; ++ ++ /* DW2 */ ++ __le32 status; ++ ++ /* DW3 */ ++ u8 rsv[20]; ++}; ++ ++struct mtk_wed_wo_log_info { ++ __le32 sn; ++ __le32 total; ++ __le32 rro; ++ __le32 mod; ++}; ++ ++enum mtk_wed_wo_event { ++ MTK_WED_WO_EVT_LOG_DUMP = 0x1, ++ MTK_WED_WO_EVT_PROFILING = 0x2, ++ MTK_WED_WO_EVT_RXCNT_INFO = 0x3, ++}; ++ ++#define MTK_WED_MODULE_ID_WO 1 ++#define MTK_FW_DL_TIMEOUT 4000000 /* us */ ++#define MTK_WOCPU_TIMEOUT 2000000 /* us */ ++ ++enum { ++ MTK_WED_WARP_CMD_FLAG_RSP = BIT(0), ++ MTK_WED_WARP_CMD_FLAG_NEED_RSP = BIT(1), ++ MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2), ++}; ++ ++enum { ++ MTK_WED_WO_REGION_EMI, ++ MTK_WED_WO_REGION_ILM, ++ MTK_WED_WO_REGION_DATA, ++ MTK_WED_WO_REGION_BOOT, ++ __MTK_WED_WO_REGION_MAX, ++}; ++ ++enum mtk_wed_dummy_cr_idx { ++ MTK_WED_DUMMY_CR_FWDL, ++ MTK_WED_DUMMY_CR_WO_STATUS, ++}; ++ ++#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" ++#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" ++ ++#define MTK_WO_MCU_CFG_LS_BASE 0 ++#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) ++#define MTK_WO_MCU_CFG_LS_FW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x004) ++#define MTK_WO_MCU_CFG_LS_CFG_DBG1_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x00c) ++#define MTK_WO_MCU_CFG_LS_CFG_DBG2_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x010) ++#define MTK_WO_MCU_CFG_LS_WF_MCCR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x014) ++#define MTK_WO_MCU_CFG_LS_WF_MCCR_SET_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x018) ++#define MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x01c) ++#define MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x050) ++#define MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x060) ++#define MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x064) ++ ++#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5) ++#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0) ++ ++struct mtk_wed_wo_memory_region { ++ const char *name; ++ void __iomem *addr; ++ phys_addr_t phy_addr; ++ u32 size; ++ bool shared:1; ++ bool consumed:1; ++}; ++ ++struct mtk_wed_fw_region { ++ __le32 decomp_crc; ++ __le32 decomp_len; ++ __le32 decomp_blk_sz; ++ u8 rsv0[4]; ++ __le32 addr; ++ __le32 len; ++ u8 feature_set; ++ u8 rsv1[15]; ++} __packed; ++ ++struct mtk_wed_fw_trailer { ++ u8 chip_id; ++ u8 eco_code; ++ u8 num_region; ++ u8 format_ver; ++ u8 format_flag; ++ u8 rsv[2]; ++ char fw_ver[10]; ++ char build_date[15]; ++ u32 crc; ++}; ++ ++struct mtk_wed_wo { ++ struct mtk_wed_hw *hw; ++ struct mtk_wed_wo_memory_region boot; ++ ++ struct { ++ struct mutex mutex; ++ int timeout; ++ u16 seq; ++ ++ struct sk_buff_head res_q; ++ wait_queue_head_t wait; ++ } mcu; ++}; ++ ++static inline int ++mtk_wed_mcu_check_msg(struct mtk_wed_wo *wo, struct sk_buff *skb) ++{ ++ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; ++ ++ if (hdr->version) ++ return -EINVAL; ++ ++ if (skb->len < sizeof(*hdr) || skb->len != le16_to_cpu(hdr->length)) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb); ++void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, ++ struct sk_buff *skb); ++int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, ++ const void *data, int len, bool wait_resp); ++int mtk_wed_mcu_init(struct mtk_wed_wo *wo); ++ ++#endif /* __MTK_WED_WO_H */ +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -11,6 +11,35 @@ + struct mtk_wed_hw; + struct mtk_wdma_desc; + ++enum mtk_wed_wo_cmd { ++ MTK_WED_WO_CMD_WED_CFG, ++ MTK_WED_WO_CMD_WED_RX_STAT, ++ MTK_WED_WO_CMD_RRO_SER, ++ MTK_WED_WO_CMD_DBG_INFO, ++ MTK_WED_WO_CMD_DEV_INFO, ++ MTK_WED_WO_CMD_BSS_INFO, ++ MTK_WED_WO_CMD_STA_REC, ++ MTK_WED_WO_CMD_DEV_INFO_DUMP, ++ MTK_WED_WO_CMD_BSS_INFO_DUMP, ++ MTK_WED_WO_CMD_STA_REC_DUMP, ++ MTK_WED_WO_CMD_BA_INFO_DUMP, ++ MTK_WED_WO_CMD_FBCMD_Q_DUMP, ++ MTK_WED_WO_CMD_FW_LOG_CTRL, ++ MTK_WED_WO_CMD_LOG_FLUSH, ++ MTK_WED_WO_CMD_CHANGE_STATE, ++ MTK_WED_WO_CMD_CPU_STATS_ENABLE, ++ MTK_WED_WO_CMD_CPU_STATS_DUMP, ++ MTK_WED_WO_CMD_EXCEPTION_INIT, ++ MTK_WED_WO_CMD_PROF_CTRL, ++ MTK_WED_WO_CMD_STA_BA_DUMP, ++ MTK_WED_WO_CMD_BA_CTRL_DUMP, ++ MTK_WED_WO_CMD_RXCNT_CTRL, ++ MTK_WED_WO_CMD_RXCNT_INFO, ++ MTK_WED_WO_CMD_SET_CAP, ++ MTK_WED_WO_CMD_CCIF_RING_DUMP, ++ MTK_WED_WO_CMD_WED_END ++}; ++ + enum mtk_wed_bus_tye { + MTK_WED_BUS_PCIE, + MTK_WED_BUS_AXI, diff --git a/target/linux/generic/pending-6.1/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch b/target/linux/generic/pending-6.1/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch new file mode 100644 index 000000000..fd5f45df2 --- /dev/null +++ b/target/linux/generic/pending-6.1/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch @@ -0,0 +1,737 @@ +From: Lorenzo Bianconi +Date: Sat, 5 Nov 2022 23:36:19 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: introduce wed wo support + +Introduce WO chip support to mtk wed driver. MTK WED WO is used to +implement RX Wireless Ethernet Dispatch and offload traffic received by +wlan nic to the wired interface. + +Tested-by: Daniel Golle +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.c + +--- a/drivers/net/ethernet/mediatek/Makefile ++++ b/drivers/net/ethernet/mediatek/Makefile +@@ -5,7 +5,7 @@ + + obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o + mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o +-mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o ++mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o + ifdef CONFIG_DEBUG_FS + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o + endif +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -16,6 +16,7 @@ + #include "mtk_wed_regs.h" + #include "mtk_wed.h" + #include "mtk_ppe.h" ++#include "mtk_wed_wo.h" + + #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000) + +@@ -355,6 +356,8 @@ mtk_wed_detach(struct mtk_wed_device *de + + mtk_wed_free_buffer(dev); + mtk_wed_free_tx_rings(dev); ++ if (hw->version != 1) ++ mtk_wed_wo_deinit(hw); + + if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { + struct device_node *wlan_node; +@@ -878,9 +881,11 @@ mtk_wed_attach(struct mtk_wed_device *de + } + + mtk_wed_hw_init_early(dev); +- if (hw->hifsys) ++ if (hw->version == 1) + regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, + BIT(hw->index), 0); ++ else ++ ret = mtk_wed_wo_init(hw); + + out: + mutex_unlock(&hw_lock); +--- a/drivers/net/ethernet/mediatek/mtk_wed.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed.h +@@ -10,6 +10,7 @@ + #include + + struct mtk_eth; ++struct mtk_wed_wo; + + struct mtk_wed_hw { + struct device_node *node; +@@ -22,6 +23,7 @@ struct mtk_wed_hw { + struct regmap *mirror; + struct dentry *debugfs_dir; + struct mtk_wed_device *wed_dev; ++ struct mtk_wed_wo *wed_wo; + u32 debugfs_reg; + u32 num_flows; + u8 version; +--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c +@@ -122,8 +122,7 @@ mtk_wed_mcu_skb_send_msg(struct mtk_wed_ + if (id == MTK_WED_MODULE_ID_WO) + hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO); + +- dev_kfree_skb(skb); +- return 0; ++ return mtk_wed_wo_queue_tx_skb(wo, &wo->q_tx, skb); + } + + static int +--- /dev/null ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c +@@ -0,0 +1,508 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (C) 2022 MediaTek Inc. ++ * ++ * Author: Lorenzo Bianconi ++ * Sujuan Chen ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mtk_wed.h" ++#include "mtk_wed_regs.h" ++#include "mtk_wed_wo.h" ++ ++static u32 ++mtk_wed_mmio_r32(struct mtk_wed_wo *wo, u32 reg) ++{ ++ u32 val; ++ ++ if (regmap_read(wo->mmio.regs, reg, &val)) ++ val = ~0; ++ ++ return val; ++} ++ ++static void ++mtk_wed_mmio_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) ++{ ++ regmap_write(wo->mmio.regs, reg, val); ++} ++ ++static u32 ++mtk_wed_wo_get_isr(struct mtk_wed_wo *wo) ++{ ++ u32 val = mtk_wed_mmio_r32(wo, MTK_WED_WO_CCIF_RCHNUM); ++ ++ return val & MTK_WED_WO_CCIF_RCHNUM_MASK; ++} ++ ++static void ++mtk_wed_wo_set_isr(struct mtk_wed_wo *wo, u32 mask) ++{ ++ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_IRQ0_MASK, mask); ++} ++ ++static void ++mtk_wed_wo_set_ack(struct mtk_wed_wo *wo, u32 mask) ++{ ++ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_ACK, mask); ++} ++ ++static void ++mtk_wed_wo_set_isr_mask(struct mtk_wed_wo *wo, u32 mask, u32 val, bool set) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&wo->mmio.lock, flags); ++ wo->mmio.irq_mask &= ~mask; ++ wo->mmio.irq_mask |= val; ++ if (set) ++ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask); ++ spin_unlock_irqrestore(&wo->mmio.lock, flags); ++} ++ ++static void ++mtk_wed_wo_irq_enable(struct mtk_wed_wo *wo, u32 mask) ++{ ++ mtk_wed_wo_set_isr_mask(wo, 0, mask, false); ++ tasklet_schedule(&wo->mmio.irq_tasklet); ++} ++ ++static void ++mtk_wed_wo_irq_disable(struct mtk_wed_wo *wo, u32 mask) ++{ ++ mtk_wed_wo_set_isr_mask(wo, mask, 0, true); ++} ++ ++static void ++mtk_wed_wo_kickout(struct mtk_wed_wo *wo) ++{ ++ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_BUSY, 1 << MTK_WED_WO_TXCH_NUM); ++ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_TCHNUM, MTK_WED_WO_TXCH_NUM); ++} ++ ++static void ++mtk_wed_wo_queue_kick(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, ++ u32 val) ++{ ++ wmb(); ++ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, val); ++} ++ ++static void * ++mtk_wed_wo_dequeue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, u32 *len, ++ bool flush) ++{ ++ int buf_len = SKB_WITH_OVERHEAD(q->buf_size); ++ int index = (q->tail + 1) % q->n_desc; ++ struct mtk_wed_wo_queue_entry *entry; ++ struct mtk_wed_wo_queue_desc *desc; ++ void *buf; ++ ++ if (!q->queued) ++ return NULL; ++ ++ if (flush) ++ q->desc[index].ctrl |= cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE); ++ else if (!(q->desc[index].ctrl & cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE))) ++ return NULL; ++ ++ q->tail = index; ++ q->queued--; ++ ++ desc = &q->desc[index]; ++ entry = &q->entry[index]; ++ buf = entry->buf; ++ if (len) ++ *len = FIELD_GET(MTK_WED_WO_CTL_SD_LEN0, ++ le32_to_cpu(READ_ONCE(desc->ctrl))); ++ if (buf) ++ dma_unmap_single(wo->hw->dev, entry->addr, buf_len, ++ DMA_FROM_DEVICE); ++ entry->buf = NULL; ++ ++ return buf; ++} ++ ++static int ++mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, ++ gfp_t gfp, bool rx) ++{ ++ enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; ++ int n_buf = 0; ++ ++ spin_lock_bh(&q->lock); ++ while (q->queued < q->n_desc) { ++ void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp); ++ struct mtk_wed_wo_queue_entry *entry; ++ dma_addr_t addr; ++ ++ if (!buf) ++ break; ++ ++ addr = dma_map_single(wo->hw->dev, buf, q->buf_size, dir); ++ if (unlikely(dma_mapping_error(wo->hw->dev, addr))) { ++ skb_free_frag(buf); ++ break; ++ } ++ ++ q->head = (q->head + 1) % q->n_desc; ++ entry = &q->entry[q->head]; ++ entry->addr = addr; ++ entry->len = q->buf_size; ++ q->entry[q->head].buf = buf; ++ ++ if (rx) { ++ struct mtk_wed_wo_queue_desc *desc = &q->desc[q->head]; ++ u32 ctrl = MTK_WED_WO_CTL_LAST_SEC0 | ++ FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0, ++ entry->len); ++ ++ WRITE_ONCE(desc->buf0, cpu_to_le32(addr)); ++ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); ++ } ++ q->queued++; ++ n_buf++; ++ } ++ spin_unlock_bh(&q->lock); ++ ++ return n_buf; ++} ++ ++static void ++mtk_wed_wo_rx_complete(struct mtk_wed_wo *wo) ++{ ++ mtk_wed_wo_set_ack(wo, MTK_WED_WO_RXCH_INT_MASK); ++ mtk_wed_wo_irq_enable(wo, MTK_WED_WO_RXCH_INT_MASK); ++} ++ ++static void ++mtk_wed_wo_rx_run_queue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) ++{ ++ for (;;) { ++ struct mtk_wed_mcu_hdr *hdr; ++ struct sk_buff *skb; ++ void *data; ++ u32 len; ++ ++ data = mtk_wed_wo_dequeue(wo, q, &len, false); ++ if (!data) ++ break; ++ ++ skb = build_skb(data, q->buf_size); ++ if (!skb) { ++ skb_free_frag(data); ++ continue; ++ } ++ ++ __skb_put(skb, len); ++ if (mtk_wed_mcu_check_msg(wo, skb)) { ++ dev_kfree_skb(skb); ++ continue; ++ } ++ ++ hdr = (struct mtk_wed_mcu_hdr *)skb->data; ++ if (hdr->flag & cpu_to_le16(MTK_WED_WARP_CMD_FLAG_RSP)) ++ mtk_wed_mcu_rx_event(wo, skb); ++ else ++ mtk_wed_mcu_rx_unsolicited_event(wo, skb); ++ } ++ ++ if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) { ++ u32 index = (q->head - 1) % q->n_desc; ++ ++ mtk_wed_wo_queue_kick(wo, q, index); ++ } ++} ++ ++static irqreturn_t ++mtk_wed_wo_irq_handler(int irq, void *data) ++{ ++ struct mtk_wed_wo *wo = data; ++ ++ mtk_wed_wo_set_isr(wo, 0); ++ tasklet_schedule(&wo->mmio.irq_tasklet); ++ ++ return IRQ_HANDLED; ++} ++ ++static void mtk_wed_wo_irq_tasklet(struct tasklet_struct *t) ++{ ++ struct mtk_wed_wo *wo = from_tasklet(wo, t, mmio.irq_tasklet); ++ u32 intr, mask; ++ ++ /* disable interrupts */ ++ mtk_wed_wo_set_isr(wo, 0); ++ ++ intr = mtk_wed_wo_get_isr(wo); ++ intr &= wo->mmio.irq_mask; ++ mask = intr & (MTK_WED_WO_RXCH_INT_MASK | MTK_WED_WO_EXCEPTION_INT_MASK); ++ mtk_wed_wo_irq_disable(wo, mask); ++ ++ if (intr & MTK_WED_WO_RXCH_INT_MASK) { ++ mtk_wed_wo_rx_run_queue(wo, &wo->q_rx); ++ mtk_wed_wo_rx_complete(wo); ++ } ++} ++ ++/* mtk wed wo hw queues */ ++ ++static int ++mtk_wed_wo_queue_alloc(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, ++ int n_desc, int buf_size, int index, ++ struct mtk_wed_wo_queue_regs *regs) ++{ ++ spin_lock_init(&q->lock); ++ q->regs = *regs; ++ q->n_desc = n_desc; ++ q->buf_size = buf_size; ++ ++ q->desc = dmam_alloc_coherent(wo->hw->dev, n_desc * sizeof(*q->desc), ++ &q->desc_dma, GFP_KERNEL); ++ if (!q->desc) ++ return -ENOMEM; ++ ++ q->entry = devm_kzalloc(wo->hw->dev, n_desc * sizeof(*q->entry), ++ GFP_KERNEL); ++ if (!q->entry) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static void ++mtk_wed_wo_queue_free(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) ++{ ++ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0); ++ dma_free_coherent(wo->hw->dev, q->n_desc * sizeof(*q->desc), q->desc, ++ q->desc_dma); ++} ++ ++static void ++mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) ++{ ++ struct page *page; ++ int i; ++ ++ spin_lock_bh(&q->lock); ++ for (i = 0; i < q->n_desc; i++) { ++ struct mtk_wed_wo_queue_entry *entry = &q->entry[i]; ++ ++ dma_unmap_single(wo->hw->dev, entry->addr, entry->len, ++ DMA_TO_DEVICE); ++ skb_free_frag(entry->buf); ++ entry->buf = NULL; ++ } ++ spin_unlock_bh(&q->lock); ++ ++ if (!q->cache.va) ++ return; ++ ++ page = virt_to_page(q->cache.va); ++ __page_frag_cache_drain(page, q->cache.pagecnt_bias); ++ memset(&q->cache, 0, sizeof(q->cache)); ++} ++ ++static void ++mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) ++{ ++ struct page *page; ++ ++ spin_lock_bh(&q->lock); ++ for (;;) { ++ void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true); ++ ++ if (!buf) ++ break; ++ ++ skb_free_frag(buf); ++ } ++ spin_unlock_bh(&q->lock); ++ ++ if (!q->cache.va) ++ return; ++ ++ page = virt_to_page(q->cache.va); ++ __page_frag_cache_drain(page, q->cache.pagecnt_bias); ++ memset(&q->cache, 0, sizeof(q->cache)); ++} ++ ++static void ++mtk_wed_wo_queue_reset(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) ++{ ++ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0); ++ mtk_wed_mmio_w32(wo, q->regs.desc_base, q->desc_dma); ++ mtk_wed_mmio_w32(wo, q->regs.ring_size, q->n_desc); ++} ++ ++int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, ++ struct sk_buff *skb) ++{ ++ struct mtk_wed_wo_queue_entry *entry; ++ struct mtk_wed_wo_queue_desc *desc; ++ int ret = 0, index; ++ u32 ctrl; ++ ++ spin_lock_bh(&q->lock); ++ ++ q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx); ++ index = (q->head + 1) % q->n_desc; ++ if (q->tail == index) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ entry = &q->entry[index]; ++ if (skb->len > entry->len) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ desc = &q->desc[index]; ++ q->head = index; ++ ++ dma_sync_single_for_cpu(wo->hw->dev, entry->addr, skb->len, ++ DMA_TO_DEVICE); ++ memcpy(entry->buf, skb->data, skb->len); ++ dma_sync_single_for_device(wo->hw->dev, entry->addr, skb->len, ++ DMA_TO_DEVICE); ++ ++ ctrl = FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0, skb->len) | ++ MTK_WED_WO_CTL_LAST_SEC0 | MTK_WED_WO_CTL_DMA_DONE; ++ WRITE_ONCE(desc->buf0, cpu_to_le32(entry->addr)); ++ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); ++ ++ mtk_wed_wo_queue_kick(wo, q, q->head); ++ mtk_wed_wo_kickout(wo); ++out: ++ spin_unlock_bh(&q->lock); ++ ++ dev_kfree_skb(skb); ++ ++ return ret; ++} ++ ++static int ++mtk_wed_wo_exception_init(struct mtk_wed_wo *wo) ++{ ++ return 0; ++} ++ ++static int ++mtk_wed_wo_hardware_init(struct mtk_wed_wo *wo) ++{ ++ struct mtk_wed_wo_queue_regs regs; ++ struct device_node *np; ++ int ret; ++ ++ np = of_parse_phandle(wo->hw->node, "mediatek,wo-ccif", 0); ++ if (!np) ++ return -ENODEV; ++ ++ wo->mmio.regs = syscon_regmap_lookup_by_phandle(np, NULL); ++ if (IS_ERR_OR_NULL(wo->mmio.regs)) ++ return PTR_ERR(wo->mmio.regs); ++ ++ wo->mmio.irq = irq_of_parse_and_map(np, 0); ++ wo->mmio.irq_mask = MTK_WED_WO_ALL_INT_MASK; ++ spin_lock_init(&wo->mmio.lock); ++ tasklet_setup(&wo->mmio.irq_tasklet, mtk_wed_wo_irq_tasklet); ++ ++ ret = devm_request_irq(wo->hw->dev, wo->mmio.irq, ++ mtk_wed_wo_irq_handler, IRQF_TRIGGER_HIGH, ++ KBUILD_MODNAME, wo); ++ if (ret) ++ goto error; ++ ++ regs.desc_base = MTK_WED_WO_CCIF_DUMMY1; ++ regs.ring_size = MTK_WED_WO_CCIF_DUMMY2; ++ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW4; ++ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY3; ++ ++ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_tx, MTK_WED_WO_RING_SIZE, ++ MTK_WED_WO_CMD_LEN, MTK_WED_WO_TXCH_NUM, ++ ®s); ++ if (ret) ++ goto error; ++ ++ mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false); ++ mtk_wed_wo_queue_reset(wo, &wo->q_tx); ++ ++ regs.desc_base = MTK_WED_WO_CCIF_DUMMY5; ++ regs.ring_size = MTK_WED_WO_CCIF_DUMMY6; ++ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW8; ++ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY7; ++ ++ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_rx, MTK_WED_WO_RING_SIZE, ++ MTK_WED_WO_CMD_LEN, MTK_WED_WO_RXCH_NUM, ++ ®s); ++ if (ret) ++ goto error; ++ ++ mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true); ++ mtk_wed_wo_queue_reset(wo, &wo->q_rx); ++ ++ /* rx queue irqmask */ ++ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask); ++ ++ return 0; ++ ++error: ++ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo); ++ ++ return ret; ++} ++ ++static void ++mtk_wed_wo_hw_deinit(struct mtk_wed_wo *wo) ++{ ++ /* disable interrupts */ ++ mtk_wed_wo_set_isr(wo, 0); ++ ++ tasklet_disable(&wo->mmio.irq_tasklet); ++ ++ disable_irq(wo->mmio.irq); ++ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo); ++ ++ mtk_wed_wo_queue_tx_clean(wo, &wo->q_tx); ++ mtk_wed_wo_queue_rx_clean(wo, &wo->q_rx); ++ mtk_wed_wo_queue_free(wo, &wo->q_tx); ++ mtk_wed_wo_queue_free(wo, &wo->q_rx); ++} ++ ++int mtk_wed_wo_init(struct mtk_wed_hw *hw) ++{ ++ struct mtk_wed_wo *wo; ++ int ret; ++ ++ wo = devm_kzalloc(hw->dev, sizeof(*wo), GFP_KERNEL); ++ if (!wo) ++ return -ENOMEM; ++ ++ hw->wed_wo = wo; ++ wo->hw = hw; ++ ++ ret = mtk_wed_wo_hardware_init(wo); ++ if (ret) ++ return ret; ++ ++ ret = mtk_wed_mcu_init(wo); ++ if (ret) ++ return ret; ++ ++ return mtk_wed_wo_exception_init(wo); ++} ++ ++void mtk_wed_wo_deinit(struct mtk_wed_hw *hw) ++{ ++ struct mtk_wed_wo *wo = hw->wed_wo; ++ ++ mtk_wed_wo_hw_deinit(wo); ++} +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h +@@ -80,6 +80,54 @@ enum mtk_wed_dummy_cr_idx { + #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5) + #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0) + ++#define MTK_WED_WO_RING_SIZE 256 ++#define MTK_WED_WO_CMD_LEN 1504 ++ ++#define MTK_WED_WO_TXCH_NUM 0 ++#define MTK_WED_WO_RXCH_NUM 1 ++#define MTK_WED_WO_RXCH_WO_EXCEPTION 7 ++ ++#define MTK_WED_WO_TXCH_INT_MASK BIT(0) ++#define MTK_WED_WO_RXCH_INT_MASK BIT(1) ++#define MTK_WED_WO_EXCEPTION_INT_MASK BIT(7) ++#define MTK_WED_WO_ALL_INT_MASK (MTK_WED_WO_RXCH_INT_MASK | \ ++ MTK_WED_WO_EXCEPTION_INT_MASK) ++ ++#define MTK_WED_WO_CCIF_BUSY 0x004 ++#define MTK_WED_WO_CCIF_START 0x008 ++#define MTK_WED_WO_CCIF_TCHNUM 0x00c ++#define MTK_WED_WO_CCIF_RCHNUM 0x010 ++#define MTK_WED_WO_CCIF_RCHNUM_MASK GENMASK(7, 0) ++ ++#define MTK_WED_WO_CCIF_ACK 0x014 ++#define MTK_WED_WO_CCIF_IRQ0_MASK 0x018 ++#define MTK_WED_WO_CCIF_IRQ1_MASK 0x01c ++#define MTK_WED_WO_CCIF_DUMMY1 0x020 ++#define MTK_WED_WO_CCIF_DUMMY2 0x024 ++#define MTK_WED_WO_CCIF_DUMMY3 0x028 ++#define MTK_WED_WO_CCIF_DUMMY4 0x02c ++#define MTK_WED_WO_CCIF_SHADOW1 0x030 ++#define MTK_WED_WO_CCIF_SHADOW2 0x034 ++#define MTK_WED_WO_CCIF_SHADOW3 0x038 ++#define MTK_WED_WO_CCIF_SHADOW4 0x03c ++#define MTK_WED_WO_CCIF_DUMMY5 0x050 ++#define MTK_WED_WO_CCIF_DUMMY6 0x054 ++#define MTK_WED_WO_CCIF_DUMMY7 0x058 ++#define MTK_WED_WO_CCIF_DUMMY8 0x05c ++#define MTK_WED_WO_CCIF_SHADOW5 0x060 ++#define MTK_WED_WO_CCIF_SHADOW6 0x064 ++#define MTK_WED_WO_CCIF_SHADOW7 0x068 ++#define MTK_WED_WO_CCIF_SHADOW8 0x06c ++ ++#define MTK_WED_WO_CTL_SD_LEN1 GENMASK(13, 0) ++#define MTK_WED_WO_CTL_LAST_SEC1 BIT(14) ++#define MTK_WED_WO_CTL_BURST BIT(15) ++#define MTK_WED_WO_CTL_SD_LEN0_SHIFT 16 ++#define MTK_WED_WO_CTL_SD_LEN0 GENMASK(29, 16) ++#define MTK_WED_WO_CTL_LAST_SEC0 BIT(30) ++#define MTK_WED_WO_CTL_DMA_DONE BIT(31) ++#define MTK_WED_WO_INFO_WINFO GENMASK(15, 0) ++ + struct mtk_wed_wo_memory_region { + const char *name; + void __iomem *addr; +@@ -112,10 +160,53 @@ struct mtk_wed_fw_trailer { + u32 crc; + }; + ++struct mtk_wed_wo_queue_regs { ++ u32 desc_base; ++ u32 ring_size; ++ u32 cpu_idx; ++ u32 dma_idx; ++}; ++ ++struct mtk_wed_wo_queue_desc { ++ __le32 buf0; ++ __le32 ctrl; ++ __le32 buf1; ++ __le32 info; ++ __le32 reserved[4]; ++} __packed __aligned(32); ++ ++struct mtk_wed_wo_queue_entry { ++ dma_addr_t addr; ++ void *buf; ++ u32 len; ++}; ++ ++struct mtk_wed_wo_queue { ++ struct mtk_wed_wo_queue_regs regs; ++ ++ struct page_frag_cache cache; ++ spinlock_t lock; ++ ++ struct mtk_wed_wo_queue_desc *desc; ++ dma_addr_t desc_dma; ++ ++ struct mtk_wed_wo_queue_entry *entry; ++ ++ u16 head; ++ u16 tail; ++ int n_desc; ++ int queued; ++ int buf_size; ++ ++}; ++ + struct mtk_wed_wo { + struct mtk_wed_hw *hw; + struct mtk_wed_wo_memory_region boot; + ++ struct mtk_wed_wo_queue q_tx; ++ struct mtk_wed_wo_queue q_rx; ++ + struct { + struct mutex mutex; + int timeout; +@@ -124,6 +215,15 @@ struct mtk_wed_wo { + struct sk_buff_head res_q; + wait_queue_head_t wait; + } mcu; ++ ++ struct { ++ struct regmap *regs; ++ ++ spinlock_t lock; ++ struct tasklet_struct irq_tasklet; ++ int irq; ++ u32 irq_mask; ++ } mmio; + }; + + static inline int +@@ -146,5 +246,9 @@ void mtk_wed_mcu_rx_unsolicited_event(st + int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, + const void *data, int len, bool wait_resp); + int mtk_wed_mcu_init(struct mtk_wed_wo *wo); ++int mtk_wed_wo_init(struct mtk_wed_hw *hw); ++void mtk_wed_wo_deinit(struct mtk_wed_hw *hw); ++int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *dev, struct mtk_wed_wo_queue *q, ++ struct sk_buff *skb); + + #endif /* __MTK_WED_WO_H */ diff --git a/target/linux/generic/pending-6.1/733-03-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch b/target/linux/generic/pending-6.1/733-03-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch new file mode 100644 index 000000000..a002a5f85 --- /dev/null +++ b/target/linux/generic/pending-6.1/733-03-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch @@ -0,0 +1,79 @@ +From: Lorenzo Bianconi +Date: Sat, 5 Nov 2022 23:36:20 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: rename tx_wdma array in rx_wdma + +Rename tx_wdma queue array in rx_wdma since this is rx side of wdma soc. +Moreover rename mtk_wed_wdma_ring_setup routine in +mtk_wed_wdma_rx_ring_setup() + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -253,8 +253,8 @@ mtk_wed_free_tx_rings(struct mtk_wed_dev + + for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) + mtk_wed_free_ring(dev, &dev->tx_ring[i]); +- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) +- mtk_wed_free_ring(dev, &dev->tx_wdma[i]); ++ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) ++ mtk_wed_free_ring(dev, &dev->rx_wdma[i]); + } + + static void +@@ -688,10 +688,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device + } + + static int +-mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size) ++mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) + { + u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; +- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx]; ++ struct mtk_wed_ring *wdma = &dev->rx_wdma[idx]; + + if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) + return -ENOMEM; +@@ -805,9 +805,9 @@ mtk_wed_start(struct mtk_wed_device *dev + { + int i; + +- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) +- if (!dev->tx_wdma[i].desc) +- mtk_wed_wdma_ring_setup(dev, i, 16); ++ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) ++ if (!dev->rx_wdma[i].desc) ++ mtk_wed_wdma_rx_ring_setup(dev, i, 16); + + mtk_wed_hw_init(dev); + mtk_wed_configure_irq(dev, irq_mask); +@@ -916,7 +916,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev + sizeof(*ring->desc))) + return -ENOMEM; + +- if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) ++ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) + return -ENOMEM; + + ring->reg_base = MTK_WED_RING_TX(idx); +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -7,6 +7,7 @@ + #include + + #define MTK_WED_TX_QUEUES 2 ++#define MTK_WED_RX_QUEUES 2 + + struct mtk_wed_hw; + struct mtk_wdma_desc; +@@ -66,7 +67,7 @@ struct mtk_wed_device { + + struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; + struct mtk_wed_ring txfree_ring; +- struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; ++ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; + + struct { + int size; diff --git a/target/linux/generic/pending-6.1/733-04-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch b/target/linux/generic/pending-6.1/733-04-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch new file mode 100644 index 000000000..eca29739b --- /dev/null +++ b/target/linux/generic/pending-6.1/733-04-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch @@ -0,0 +1,1521 @@ +From: Lorenzo Bianconi +Date: Sat, 5 Nov 2022 23:36:21 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add configure wed wo support + +Enable RX Wireless Ethernet Dispatch available on MT7986 Soc. + +Tested-by: Daniel Golle +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -23,6 +24,7 @@ + #define MTK_WED_PKT_SIZE 1900 + #define MTK_WED_BUF_SIZE 2048 + #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048) ++#define MTK_WED_RX_RING_SIZE 1536 + + #define MTK_WED_TX_RING_SIZE 2048 + #define MTK_WED_WDMA_RING_SIZE 1024 +@@ -31,6 +33,10 @@ + #define MTK_WED_PER_GROUP_PKT 128 + + #define MTK_WED_FBUF_SIZE 128 ++#define MTK_WED_MIOD_CNT 16 ++#define MTK_WED_FB_CMD_CNT 1024 ++#define MTK_WED_RRO_QUE_CNT 8192 ++#define MTK_WED_MIOD_ENTRY_CNT 128 + + static struct mtk_wed_hw *hw_list[2]; + static DEFINE_MUTEX(hw_lock); +@@ -65,12 +71,76 @@ wdma_set(struct mtk_wed_device *dev, u32 + wdma_m32(dev, reg, 0, mask); + } + ++static void ++wdma_clr(struct mtk_wed_device *dev, u32 reg, u32 mask) ++{ ++ wdma_m32(dev, reg, mask, 0); ++} ++ ++static u32 ++wifi_r32(struct mtk_wed_device *dev, u32 reg) ++{ ++ return readl(dev->wlan.base + reg); ++} ++ ++static void ++wifi_w32(struct mtk_wed_device *dev, u32 reg, u32 val) ++{ ++ writel(val, dev->wlan.base + reg); ++} ++ + static u32 + mtk_wed_read_reset(struct mtk_wed_device *dev) + { + return wed_r32(dev, MTK_WED_RESET); + } + ++static u32 ++mtk_wdma_read_reset(struct mtk_wed_device *dev) ++{ ++ return wdma_r32(dev, MTK_WDMA_GLO_CFG); ++} ++ ++static void ++mtk_wdma_rx_reset(struct mtk_wed_device *dev) ++{ ++ u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY; ++ int i; ++ ++ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN); ++ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, ++ !(status & mask), 0, 1000)) ++ dev_err(dev->hw->dev, "rx reset failed\n"); ++ ++ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) { ++ if (dev->rx_wdma[i].desc) ++ continue; ++ ++ wdma_w32(dev, ++ MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); ++ } ++} ++ ++static void ++mtk_wdma_tx_reset(struct mtk_wed_device *dev) ++{ ++ u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY; ++ int i; ++ ++ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); ++ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, ++ !(status & mask), 0, 1000)) ++ dev_err(dev->hw->dev, "tx reset failed\n"); ++ ++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) { ++ if (dev->tx_wdma[i].desc) ++ continue; ++ ++ wdma_w32(dev, ++ MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); ++ } ++} ++ + static void + mtk_wed_reset(struct mtk_wed_device *dev, u32 mask) + { +@@ -82,6 +152,54 @@ mtk_wed_reset(struct mtk_wed_device *dev + WARN_ON_ONCE(1); + } + ++static u32 ++mtk_wed_wo_read_status(struct mtk_wed_device *dev) ++{ ++ return wed_r32(dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_WO_STATUS); ++} ++ ++static void ++mtk_wed_wo_reset(struct mtk_wed_device *dev) ++{ ++ struct mtk_wed_wo *wo = dev->hw->wed_wo; ++ u8 state = MTK_WED_WO_STATE_DISABLE; ++ void __iomem *reg; ++ u32 val; ++ ++ mtk_wdma_tx_reset(dev); ++ mtk_wed_reset(dev, MTK_WED_RESET_WED); ++ ++ mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, ++ MTK_WED_WO_CMD_CHANGE_STATE, &state, ++ sizeof(state), false); ++ ++ if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val, ++ val == MTK_WED_WOIF_DISABLE_DONE, ++ 100, MTK_WOCPU_TIMEOUT)) ++ dev_err(dev->hw->dev, "failed to disable wed-wo\n"); ++ ++ reg = ioremap(MTK_WED_WO_CPU_MCUSYS_RESET_ADDR, 4); ++ ++ val = readl(reg); ++ switch (dev->hw->index) { ++ case 0: ++ val |= MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK; ++ writel(val, reg); ++ val &= ~MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK; ++ writel(val, reg); ++ break; ++ case 1: ++ val |= MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK; ++ writel(val, reg); ++ val &= ~MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK; ++ writel(val, reg); ++ break; ++ default: ++ break; ++ } ++ iounmap(reg); ++} ++ + static struct mtk_wed_hw * + mtk_wed_assign(struct mtk_wed_device *dev) + { +@@ -116,7 +234,7 @@ out: + } + + static int +-mtk_wed_buffer_alloc(struct mtk_wed_device *dev) ++mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) + { + struct mtk_wdma_desc *desc; + dma_addr_t desc_phys; +@@ -133,16 +251,16 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi + if (!page_list) + return -ENOMEM; + +- dev->buf_ring.size = ring_size; +- dev->buf_ring.pages = page_list; ++ dev->tx_buf_ring.size = ring_size; ++ dev->tx_buf_ring.pages = page_list; + + desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc), + &desc_phys, GFP_KERNEL); + if (!desc) + return -ENOMEM; + +- dev->buf_ring.desc = desc; +- dev->buf_ring.desc_phys = desc_phys; ++ dev->tx_buf_ring.desc = desc; ++ dev->tx_buf_ring.desc_phys = desc_phys; + + for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) { + dma_addr_t page_phys, buf_phys; +@@ -203,10 +321,10 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi + } + + static void +-mtk_wed_free_buffer(struct mtk_wed_device *dev) ++mtk_wed_free_tx_buffer(struct mtk_wed_device *dev) + { +- struct mtk_wdma_desc *desc = dev->buf_ring.desc; +- void **page_list = dev->buf_ring.pages; ++ struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc; ++ void **page_list = dev->tx_buf_ring.pages; + int page_idx; + int i; + +@@ -216,7 +334,8 @@ mtk_wed_free_buffer(struct mtk_wed_devic + if (!desc) + goto free_pagelist; + +- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) { ++ for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size; ++ i += MTK_WED_BUF_PER_PAGE) { + void *page = page_list[page_idx++]; + dma_addr_t buf_addr; + +@@ -229,13 +348,59 @@ mtk_wed_free_buffer(struct mtk_wed_devic + __free_page(page); + } + +- dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc), +- desc, dev->buf_ring.desc_phys); ++ dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc), ++ desc, dev->tx_buf_ring.desc_phys); + + free_pagelist: + kfree(page_list); + } + ++static int ++mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev) ++{ ++ struct mtk_rxbm_desc *desc; ++ dma_addr_t desc_phys; ++ ++ dev->rx_buf_ring.size = dev->wlan.rx_nbuf; ++ desc = dma_alloc_coherent(dev->hw->dev, ++ dev->wlan.rx_nbuf * sizeof(*desc), ++ &desc_phys, GFP_KERNEL); ++ if (!desc) ++ return -ENOMEM; ++ ++ dev->rx_buf_ring.desc = desc; ++ dev->rx_buf_ring.desc_phys = desc_phys; ++ dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt); ++ ++ return 0; ++} ++ ++static void ++mtk_wed_free_rx_buffer(struct mtk_wed_device *dev) ++{ ++ struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc; ++ ++ if (!desc) ++ return; ++ ++ dev->wlan.release_rx_buf(dev); ++ dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc), ++ desc, dev->rx_buf_ring.desc_phys); ++} ++ ++static void ++mtk_wed_rx_buffer_hw_init(struct mtk_wed_device *dev) ++{ ++ wed_w32(dev, MTK_WED_RX_BM_RX_DMAD, ++ FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0, dev->wlan.rx_size)); ++ wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys); ++ wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL | ++ FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt)); ++ wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH, ++ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff)); ++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); ++} ++ + static void + mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring) + { +@@ -247,6 +412,13 @@ mtk_wed_free_ring(struct mtk_wed_device + } + + static void ++mtk_wed_free_rx_rings(struct mtk_wed_device *dev) ++{ ++ mtk_wed_free_rx_buffer(dev); ++ mtk_wed_free_ring(dev, &dev->rro.ring); ++} ++ ++static void + mtk_wed_free_tx_rings(struct mtk_wed_device *dev) + { + int i; +@@ -291,6 +463,38 @@ mtk_wed_set_512_support(struct mtk_wed_d + } + } + ++#define MTK_WFMDA_RX_DMA_EN BIT(2) ++static void ++mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx) ++{ ++ u32 val; ++ int i; ++ ++ if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED)) ++ return; /* queue is not configured by mt76 */ ++ ++ for (i = 0; i < 3; i++) { ++ u32 cur_idx; ++ ++ cur_idx = wed_r32(dev, ++ MTK_WED_WPDMA_RING_RX_DATA(idx) + ++ MTK_WED_RING_OFS_CPU_IDX); ++ if (cur_idx == MTK_WED_RX_RING_SIZE - 1) ++ break; ++ ++ usleep_range(100000, 200000); ++ } ++ ++ if (i == 3) { ++ dev_err(dev->hw->dev, "rx dma enable failed\n"); ++ return; ++ } ++ ++ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) | ++ MTK_WFMDA_RX_DMA_EN; ++ wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val); ++} ++ + static void + mtk_wed_dma_disable(struct mtk_wed_device *dev) + { +@@ -304,20 +508,25 @@ mtk_wed_dma_disable(struct mtk_wed_devic + MTK_WED_GLO_CFG_TX_DMA_EN | + MTK_WED_GLO_CFG_RX_DMA_EN); + +- wdma_m32(dev, MTK_WDMA_GLO_CFG, ++ wdma_clr(dev, MTK_WDMA_GLO_CFG, + MTK_WDMA_GLO_CFG_TX_DMA_EN | + MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0); ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); + + if (dev->hw->version == 1) { + regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); +- wdma_m32(dev, MTK_WDMA_GLO_CFG, +- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); ++ wdma_clr(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); + } else { + wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, + MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | + MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); + ++ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, ++ MTK_WED_WPDMA_RX_D_RX_DRV_EN); ++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, ++ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); ++ + mtk_wed_set_512_support(dev, false); + } + } +@@ -338,6 +547,13 @@ mtk_wed_stop(struct mtk_wed_device *dev) + wdma_w32(dev, MTK_WDMA_INT_MASK, 0); + wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); + wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); ++ ++ if (dev->hw->version == 1) ++ return; ++ ++ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); ++ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0); ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); + } + + static void +@@ -353,11 +569,21 @@ mtk_wed_detach(struct mtk_wed_device *de + wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); + + mtk_wed_reset(dev, MTK_WED_RESET_WED); ++ if (mtk_wed_get_rx_capa(dev)) { ++ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); ++ } + +- mtk_wed_free_buffer(dev); ++ mtk_wed_free_tx_buffer(dev); + mtk_wed_free_tx_rings(dev); +- if (hw->version != 1) ++ ++ if (mtk_wed_get_rx_capa(dev)) { ++ mtk_wed_wo_reset(dev); ++ mtk_wed_free_rx_rings(dev); + mtk_wed_wo_deinit(hw); ++ mtk_wdma_rx_reset(dev); ++ } + + if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { + struct device_node *wlan_node; +@@ -434,10 +660,12 @@ mtk_wed_set_wpdma(struct mtk_wed_device + } else { + mtk_wed_bus_init(dev); + +- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); +- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); +- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); +- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); ++ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); ++ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); + } + } + +@@ -487,6 +715,132 @@ mtk_wed_hw_init_early(struct mtk_wed_dev + } + } + ++static int ++mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, ++ int size) ++{ ++ ring->desc = dma_alloc_coherent(dev->hw->dev, ++ size * sizeof(*ring->desc), ++ &ring->desc_phys, GFP_KERNEL); ++ if (!ring->desc) ++ return -ENOMEM; ++ ++ ring->desc_size = sizeof(*ring->desc); ++ ring->size = size; ++ memset(ring->desc, 0, size); ++ ++ return 0; ++} ++ ++#define MTK_WED_MIOD_COUNT (MTK_WED_MIOD_ENTRY_CNT * MTK_WED_MIOD_CNT) ++static int ++mtk_wed_rro_alloc(struct mtk_wed_device *dev) ++{ ++ struct reserved_mem *rmem; ++ struct device_node *np; ++ int index; ++ ++ index = of_property_match_string(dev->hw->node, "memory-region-names", ++ "wo-dlm"); ++ if (index < 0) ++ return index; ++ ++ np = of_parse_phandle(dev->hw->node, "memory-region", index); ++ if (!np) ++ return -ENODEV; ++ ++ rmem = of_reserved_mem_lookup(np); ++ of_node_put(np); ++ ++ if (!rmem) ++ return -ENODEV; ++ ++ dev->rro.miod_phys = rmem->base; ++ dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys; ++ ++ return mtk_wed_rro_ring_alloc(dev, &dev->rro.ring, ++ MTK_WED_RRO_QUE_CNT); ++} ++ ++static int ++mtk_wed_rro_cfg(struct mtk_wed_device *dev) ++{ ++ struct mtk_wed_wo *wo = dev->hw->wed_wo; ++ struct { ++ struct { ++ __le32 base; ++ __le32 cnt; ++ __le32 unit; ++ } ring[2]; ++ __le32 wed; ++ u8 version; ++ } req = { ++ .ring[0] = { ++ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE), ++ .cnt = cpu_to_le32(MTK_WED_MIOD_CNT), ++ .unit = cpu_to_le32(MTK_WED_MIOD_ENTRY_CNT), ++ }, ++ .ring[1] = { ++ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE + ++ MTK_WED_MIOD_COUNT), ++ .cnt = cpu_to_le32(MTK_WED_FB_CMD_CNT), ++ .unit = cpu_to_le32(4), ++ }, ++ }; ++ ++ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, ++ MTK_WED_WO_CMD_WED_CFG, ++ &req, sizeof(req), true); ++} ++ ++static void ++mtk_wed_rro_hw_init(struct mtk_wed_device *dev) ++{ ++ wed_w32(dev, MTK_WED_RROQM_MIOD_CFG, ++ FIELD_PREP(MTK_WED_RROQM_MIOD_MID_DW, 0x70 >> 2) | ++ FIELD_PREP(MTK_WED_RROQM_MIOD_MOD_DW, 0x10 >> 2) | ++ FIELD_PREP(MTK_WED_RROQM_MIOD_ENTRY_DW, ++ MTK_WED_MIOD_ENTRY_CNT >> 2)); ++ ++ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL0, dev->rro.miod_phys); ++ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL1, ++ FIELD_PREP(MTK_WED_RROQM_MIOD_CNT, MTK_WED_MIOD_CNT)); ++ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL0, dev->rro.fdbk_phys); ++ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL1, ++ FIELD_PREP(MTK_WED_RROQM_FDBK_CNT, MTK_WED_FB_CMD_CNT)); ++ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL2, 0); ++ wed_w32(dev, MTK_WED_RROQ_BASE_L, dev->rro.ring.desc_phys); ++ ++ wed_set(dev, MTK_WED_RROQM_RST_IDX, ++ MTK_WED_RROQM_RST_IDX_MIOD | ++ MTK_WED_RROQM_RST_IDX_FDBK); ++ ++ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); ++ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL2, MTK_WED_MIOD_CNT - 1); ++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN); ++} ++ ++static void ++mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev) ++{ ++ wed_w32(dev, MTK_WED_RESET, MTK_WED_RESET_RX_ROUTE_QM); ++ ++ for (;;) { ++ usleep_range(100, 200); ++ if (!(wed_r32(dev, MTK_WED_RESET) & MTK_WED_RESET_RX_ROUTE_QM)) ++ break; ++ } ++ ++ /* configure RX_ROUTE_QM */ ++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); ++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT); ++ wed_set(dev, MTK_WED_RTQM_GLO_CFG, ++ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index)); ++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); ++ /* enable RX_ROUTE_QM */ ++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); ++} ++ + static void + mtk_wed_hw_init(struct mtk_wed_device *dev) + { +@@ -498,11 +852,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d + wed_w32(dev, MTK_WED_TX_BM_CTRL, + MTK_WED_TX_BM_CTRL_PAUSE | + FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, +- dev->buf_ring.size / 128) | ++ dev->tx_buf_ring.size / 128) | + FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, + MTK_WED_TX_RING_SIZE / 256)); + +- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys); ++ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys); + + wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); + +@@ -529,9 +883,9 @@ mtk_wed_hw_init(struct mtk_wed_device *d + wed_w32(dev, MTK_WED_TX_TKID_CTRL, + MTK_WED_TX_TKID_CTRL_PAUSE | + FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM, +- dev->buf_ring.size / 128) | ++ dev->tx_buf_ring.size / 128) | + FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, +- dev->buf_ring.size / 128)); ++ dev->tx_buf_ring.size / 128)); + wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, + FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | + MTK_WED_TX_TKID_DYN_THR_HI); +@@ -539,18 +893,28 @@ mtk_wed_hw_init(struct mtk_wed_device *d + + mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); + +- if (dev->hw->version == 1) ++ if (dev->hw->version == 1) { + wed_set(dev, MTK_WED_CTRL, + MTK_WED_CTRL_WED_TX_BM_EN | + MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); +- else ++ } else { + wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); ++ /* rx hw init */ ++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, ++ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | ++ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); ++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); ++ ++ mtk_wed_rx_buffer_hw_init(dev); ++ mtk_wed_rro_hw_init(dev); ++ mtk_wed_route_qm_hw_init(dev); ++ } + + wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); + } + + static void +-mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size) ++mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx) + { + void *head = (void *)ring->desc; + int i; +@@ -560,7 +924,10 @@ mtk_wed_ring_reset(struct mtk_wed_ring * + + desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size); + desc->buf0 = 0; +- desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); ++ if (tx) ++ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); ++ else ++ desc->ctrl = cpu_to_le32(MTK_WFDMA_DESC_CTRL_TO_HOST); + desc->buf1 = 0; + desc->info = 0; + } +@@ -616,7 +983,8 @@ mtk_wed_reset_dma(struct mtk_wed_device + if (!dev->tx_ring[i].desc) + continue; + +- mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE); ++ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE, ++ true); + } + + if (mtk_wed_poll_busy(dev)) +@@ -634,6 +1002,9 @@ mtk_wed_reset_dma(struct mtk_wed_device + wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); + wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); + ++ if (mtk_wed_get_rx_capa(dev)) ++ mtk_wdma_rx_reset(dev); ++ + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); + mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV); +@@ -668,12 +1039,11 @@ mtk_wed_reset_dma(struct mtk_wed_device + MTK_WED_WPDMA_RESET_IDX_RX); + wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0); + } +- + } + + static int + mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, +- int size, u32 desc_size) ++ int size, u32 desc_size, bool tx) + { + ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size, + &ring->desc_phys, GFP_KERNEL); +@@ -682,7 +1052,7 @@ mtk_wed_ring_alloc(struct mtk_wed_device + + ring->desc_size = desc_size; + ring->size = size; +- mtk_wed_ring_reset(ring, size); ++ mtk_wed_ring_reset(ring, size, tx); + + return 0; + } +@@ -691,9 +1061,14 @@ static int + mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) + { + u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; +- struct mtk_wed_ring *wdma = &dev->rx_wdma[idx]; ++ struct mtk_wed_ring *wdma; + +- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) ++ if (idx >= ARRAY_SIZE(dev->rx_wdma)) ++ return -EINVAL; ++ ++ wdma = &dev->rx_wdma[idx]; ++ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, ++ true)) + return -ENOMEM; + + wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, +@@ -710,6 +1085,60 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we + return 0; + } + ++static int ++mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size) ++{ ++ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; ++ struct mtk_wed_ring *wdma; ++ ++ if (idx >= ARRAY_SIZE(dev->tx_wdma)) ++ return -EINVAL; ++ ++ wdma = &dev->tx_wdma[idx]; ++ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, ++ true)) ++ return -ENOMEM; ++ ++ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, ++ wdma->desc_phys); ++ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT, ++ size); ++ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0); ++ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0); ++ ++ if (!idx) { ++ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE, ++ wdma->desc_phys); ++ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_COUNT, ++ size); ++ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_CPU_IDX, ++ 0); ++ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_DMA_IDX, ++ 0); ++ } ++ ++ return 0; ++} ++ ++static void ++mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb, ++ u32 reason, u32 hash) ++{ ++ struct mtk_eth *eth = dev->hw->eth; ++ struct ethhdr *eh; ++ ++ if (!skb) ++ return; ++ ++ if (reason != MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) ++ return; ++ ++ skb_set_mac_header(skb, 0); ++ eh = eth_hdr(skb); ++ skb->protocol = eh->h_proto; ++ mtk_ppe_check_skb(eth->ppe[dev->hw->index], skb, hash); ++} ++ + static void + mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask) + { +@@ -732,6 +1161,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev + + wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); + } else { ++ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE, ++ GENMASK(1, 0)); + /* initail tx interrupt trigger */ + wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, + MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | +@@ -750,6 +1181,16 @@ mtk_wed_configure_irq(struct mtk_wed_dev + FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, + dev->wlan.txfree_tbit)); + ++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX, ++ MTK_WED_WPDMA_INT_CTRL_RX0_EN | ++ MTK_WED_WPDMA_INT_CTRL_RX0_CLR | ++ MTK_WED_WPDMA_INT_CTRL_RX1_EN | ++ MTK_WED_WPDMA_INT_CTRL_RX1_CLR | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG, ++ dev->wlan.rx_tbit[0]) | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG, ++ dev->wlan.rx_tbit[1])); ++ + wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); + wed_set(dev, MTK_WED_WDMA_INT_CTRL, + FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL, +@@ -787,9 +1228,15 @@ mtk_wed_dma_enable(struct mtk_wed_device + wdma_set(dev, MTK_WDMA_GLO_CFG, + MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); + } else { ++ int i; ++ + wed_set(dev, MTK_WED_WPDMA_CTRL, + MTK_WED_WPDMA_CTRL_SDL1_FIXED); + ++ wed_set(dev, MTK_WED_WDMA_GLO_CFG, ++ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | ++ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); ++ + wed_set(dev, MTK_WED_WPDMA_GLO_CFG, + MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | + MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); +@@ -797,6 +1244,15 @@ mtk_wed_dma_enable(struct mtk_wed_device + wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, + MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | + MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); ++ ++ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, ++ MTK_WED_WPDMA_RX_D_RX_DRV_EN | ++ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | ++ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, ++ 0x2)); ++ ++ for (i = 0; i < MTK_WED_RX_QUEUES; i++) ++ mtk_wed_check_wfdma_rx_fill(dev, i); + } + } + +@@ -822,7 +1278,19 @@ mtk_wed_start(struct mtk_wed_device *dev + val |= BIT(0) | (BIT(1) * !!dev->hw->index); + regmap_write(dev->hw->mirror, dev->hw->index * 4, val); + } else { +- mtk_wed_set_512_support(dev, true); ++ /* driver set mid ready and only once */ ++ wed_w32(dev, MTK_WED_EXT_INT_MASK1, ++ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); ++ wed_w32(dev, MTK_WED_EXT_INT_MASK2, ++ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); ++ ++ wed_r32(dev, MTK_WED_EXT_INT_MASK1); ++ wed_r32(dev, MTK_WED_EXT_INT_MASK2); ++ ++ if (mtk_wed_rro_cfg(dev)) ++ return; ++ ++ mtk_wed_set_512_support(dev, dev->wlan.wcid_512); + } + + mtk_wed_dma_enable(dev); +@@ -856,7 +1324,7 @@ mtk_wed_attach(struct mtk_wed_device *de + if (!hw) { + module_put(THIS_MODULE); + ret = -ENODEV; +- goto out; ++ goto unlock; + } + + device = dev->wlan.bus_type == MTK_WED_BUS_PCIE +@@ -869,15 +1337,24 @@ mtk_wed_attach(struct mtk_wed_device *de + dev->dev = hw->dev; + dev->irq = hw->irq; + dev->wdma_idx = hw->index; ++ dev->version = hw->version; + + if (hw->eth->dma_dev == hw->eth->dev && + of_dma_is_coherent(hw->eth->dev->of_node)) + mtk_eth_set_dma_device(hw->eth, hw->dev); + +- ret = mtk_wed_buffer_alloc(dev); +- if (ret) { +- mtk_wed_detach(dev); ++ ret = mtk_wed_tx_buffer_alloc(dev); ++ if (ret) + goto out; ++ ++ if (mtk_wed_get_rx_capa(dev)) { ++ ret = mtk_wed_rx_buffer_alloc(dev); ++ if (ret) ++ goto out; ++ ++ ret = mtk_wed_rro_alloc(dev); ++ if (ret) ++ goto out; + } + + mtk_wed_hw_init_early(dev); +@@ -886,8 +1363,10 @@ mtk_wed_attach(struct mtk_wed_device *de + BIT(hw->index), 0); + else + ret = mtk_wed_wo_init(hw); +- + out: ++ if (ret) ++ mtk_wed_detach(dev); ++unlock: + mutex_unlock(&hw_lock); + + return ret; +@@ -910,10 +1389,11 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev + * WDMA RX. + */ + +- BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); ++ if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring))) ++ return -EINVAL; + + if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, +- sizeof(*ring->desc))) ++ sizeof(*ring->desc), true)) + return -ENOMEM; + + if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) +@@ -960,6 +1440,37 @@ mtk_wed_txfree_ring_setup(struct mtk_wed + return 0; + } + ++static int ++mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) ++{ ++ struct mtk_wed_ring *ring = &dev->rx_ring[idx]; ++ ++ if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring))) ++ return -EINVAL; ++ ++ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, ++ sizeof(*ring->desc), false)) ++ return -ENOMEM; ++ ++ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) ++ return -ENOMEM; ++ ++ ring->reg_base = MTK_WED_RING_RX_DATA(idx); ++ ring->wpdma = regs; ++ ring->flags |= MTK_WED_RING_CONFIGURED; ++ ++ /* WPDMA -> WED */ ++ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys); ++ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_RX_RING_SIZE); ++ ++ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_BASE, ++ ring->desc_phys); ++ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_COUNT, ++ MTK_WED_RX_RING_SIZE); ++ ++ return 0; ++} ++ + static u32 + mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) + { +@@ -1056,7 +1567,9 @@ void mtk_wed_add_hw(struct device_node * + static const struct mtk_wed_ops wed_ops = { + .attach = mtk_wed_attach, + .tx_ring_setup = mtk_wed_tx_ring_setup, ++ .rx_ring_setup = mtk_wed_rx_ring_setup, + .txfree_ring_setup = mtk_wed_txfree_ring_setup, ++ .msg_update = mtk_wed_mcu_msg_update, + .start = mtk_wed_start, + .stop = mtk_wed_stop, + .reset_dma = mtk_wed_reset_dma, +@@ -1065,6 +1578,7 @@ void mtk_wed_add_hw(struct device_node * + .irq_get = mtk_wed_irq_get, + .irq_set_mask = mtk_wed_irq_set_mask, + .detach = mtk_wed_detach, ++ .ppe_check = mtk_wed_ppe_check, + }; + struct device_node *eth_np = eth->dev->of_node; + struct platform_device *pdev; +--- a/drivers/net/ethernet/mediatek/mtk_wed.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed.h +@@ -87,6 +87,24 @@ wpdma_tx_w32(struct mtk_wed_device *dev, + } + + static inline u32 ++wpdma_rx_r32(struct mtk_wed_device *dev, int ring, u32 reg) ++{ ++ if (!dev->rx_ring[ring].wpdma) ++ return 0; ++ ++ return readl(dev->rx_ring[ring].wpdma + reg); ++} ++ ++static inline void ++wpdma_rx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val) ++{ ++ if (!dev->rx_ring[ring].wpdma) ++ return; ++ ++ writel(val, dev->rx_ring[ring].wpdma + reg); ++} ++ ++static inline u32 + wpdma_txfree_r32(struct mtk_wed_device *dev, u32 reg) + { + if (!dev->txfree_ring.wpdma) +@@ -128,6 +146,7 @@ static inline int mtk_wed_flow_add(int i + static inline void mtk_wed_flow_remove(int index) + { + } ++ + #endif + + #ifdef CONFIG_DEBUG_FS +--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "mtk_wed_regs.h" + #include "mtk_wed_wo.h" +@@ -60,24 +61,37 @@ void mtk_wed_mcu_rx_event(struct mtk_wed + wake_up(&wo->mcu.wait); + } + ++static void ++mtk_wed_update_rx_stats(struct mtk_wed_device *wed, struct sk_buff *skb) ++{ ++ u32 count = get_unaligned_le32(skb->data); ++ struct mtk_wed_wo_rx_stats *stats; ++ int i; ++ ++ if (count * sizeof(*stats) > skb->len - sizeof(u32)) ++ return; ++ ++ stats = (struct mtk_wed_wo_rx_stats *)(skb->data + sizeof(u32)); ++ for (i = 0 ; i < count ; i++) ++ wed->wlan.update_wo_rx_stats(wed, &stats[i]); ++} ++ + void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, + struct sk_buff *skb) + { + struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; + +- switch (hdr->cmd) { +- case MTK_WED_WO_EVT_LOG_DUMP: { +- const char *msg = (const char *)(skb->data + sizeof(*hdr)); ++ skb_pull(skb, sizeof(*hdr)); + +- dev_notice(wo->hw->dev, "%s\n", msg); ++ switch (hdr->cmd) { ++ case MTK_WED_WO_EVT_LOG_DUMP: ++ dev_notice(wo->hw->dev, "%s\n", skb->data); + break; +- } + case MTK_WED_WO_EVT_PROFILING: { +- struct mtk_wed_wo_log_info *info; +- u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info); ++ struct mtk_wed_wo_log_info *info = (void *)skb->data; ++ u32 count = skb->len / sizeof(*info); + int i; + +- info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr)); + for (i = 0 ; i < count ; i++) + dev_notice(wo->hw->dev, + "SN:%u latency: total=%u, rro:%u, mod:%u\n", +@@ -88,6 +102,7 @@ void mtk_wed_mcu_rx_unsolicited_event(st + break; + } + case MTK_WED_WO_EVT_RXCNT_INFO: ++ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb); + break; + default: + break; +@@ -144,6 +159,8 @@ mtk_wed_mcu_parse_response(struct mtk_we + skb_pull(skb, sizeof(*hdr)); + switch (cmd) { + case MTK_WED_WO_CMD_RXCNT_INFO: ++ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb); ++ break; + default: + break; + } +@@ -182,6 +199,18 @@ unlock: + return ret; + } + ++int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, ++ int len) ++{ ++ struct mtk_wed_wo *wo = dev->hw->wed_wo; ++ ++ if (dev->hw->version == 1) ++ return 0; ++ ++ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len, ++ true); ++} ++ + static int + mtk_wed_get_memory_region(struct mtk_wed_wo *wo, + struct mtk_wed_wo_memory_region *region) +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -4,6 +4,7 @@ + #ifndef __MTK_WED_REGS_H + #define __MTK_WED_REGS_H + ++#define MTK_WFDMA_DESC_CTRL_TO_HOST BIT(8) + #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0) + #define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0) + #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15) +@@ -28,6 +29,8 @@ struct mtk_wdma_desc { + #define MTK_WED_RESET_WED_TX_DMA BIT(12) + #define MTK_WED_RESET_WDMA_RX_DRV BIT(17) + #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) ++#define MTK_WED_RESET_RX_RRO_QM BIT(20) ++#define MTK_WED_RESET_RX_ROUTE_QM BIT(21) + #define MTK_WED_RESET_WED BIT(31) + + #define MTK_WED_CTRL 0x00c +@@ -39,8 +42,12 @@ struct mtk_wdma_desc { + #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9) + #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10) + #define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11) +-#define MTK_WED_CTRL_RESERVE_EN BIT(12) +-#define MTK_WED_CTRL_RESERVE_BUSY BIT(13) ++#define MTK_WED_CTRL_WED_RX_BM_EN BIT(12) ++#define MTK_WED_CTRL_WED_RX_BM_BUSY BIT(13) ++#define MTK_WED_CTRL_RX_RRO_QM_EN BIT(14) ++#define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15) ++#define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16) ++#define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17) + #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) + #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) + #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) +@@ -62,6 +69,9 @@ struct mtk_wdma_desc { + #define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22) + #define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23) + #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24) ++#define MTK_WED_EXT_INT_STATUS_RX_DRV_GET_BM_DMAD_SKIP BIT(25) ++#define MTK_WED_EXT_INT_STATUS_WPDMA_RX_D_DRV_ERR BIT(26) ++#define MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY BIT(27) + #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \ + MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \ + MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \ +@@ -71,6 +81,8 @@ struct mtk_wdma_desc { + MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR) + + #define MTK_WED_EXT_INT_MASK 0x028 ++#define MTK_WED_EXT_INT_MASK1 0x02c ++#define MTK_WED_EXT_INT_MASK2 0x030 + + #define MTK_WED_STATUS 0x060 + #define MTK_WED_STATUS_TX GENMASK(15, 8) +@@ -151,6 +163,7 @@ struct mtk_wdma_desc { + #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10) + + #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10) ++#define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10) + + #define MTK_WED_SCR0 0x3c0 + #define MTK_WED_WPDMA_INT_TRIGGER 0x504 +@@ -213,6 +226,12 @@ struct mtk_wdma_desc { + #define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10) + + #define MTK_WED_WPDMA_INT_CTRL_RX 0x534 ++#define MTK_WED_WPDMA_INT_CTRL_RX0_EN BIT(0) ++#define MTK_WED_WPDMA_INT_CTRL_RX0_CLR BIT(1) ++#define MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG GENMASK(6, 2) ++#define MTK_WED_WPDMA_INT_CTRL_RX1_EN BIT(8) ++#define MTK_WED_WPDMA_INT_CTRL_RX1_CLR BIT(9) ++#define MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG GENMASK(14, 10) + + #define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538 + #define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0) +@@ -242,11 +261,34 @@ struct mtk_wdma_desc { + + #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10) + #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10) ++#define MTK_WED_WPDMA_RING_RX_DATA(_n) (0x730 + (_n) * 0x10) ++ ++#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c ++#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0) ++#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7) ++#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24) ++ ++#define MTK_WED_WPDMA_RX_D_RST_IDX 0x760 ++#define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16) ++#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24) ++ ++#define MTK_WED_WPDMA_RX_GLO_CFG 0x76c ++#define MTK_WED_WPDMA_RX_RING 0x770 ++ ++#define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4) ++#define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4) ++#define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c ++ ++#define MTK_WED_WDMA_RING_TX 0x800 ++ ++#define MTK_WED_WDMA_TX_MIB 0x810 ++ + #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10) + #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4) + + #define MTK_WED_WDMA_GLO_CFG 0xa04 + #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0) ++#define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1) + #define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2) + #define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3) + #define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4) +@@ -291,6 +333,20 @@ struct mtk_wdma_desc { + #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4) + #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4) + ++#define MTK_WED_RX_BM_RX_DMAD 0xd80 ++#define MTK_WED_RX_BM_RX_DMAD_SDL0 GENMASK(13, 0) ++ ++#define MTK_WED_RX_BM_BASE 0xd84 ++#define MTK_WED_RX_BM_INIT_PTR 0xd88 ++#define MTK_WED_RX_BM_SW_TAIL GENMASK(15, 0) ++#define MTK_WED_RX_BM_INIT_SW_TAIL BIT(16) ++ ++#define MTK_WED_RX_PTR 0xd8c ++ ++#define MTK_WED_RX_BM_DYN_ALLOC_TH 0xdb4 ++#define MTK_WED_RX_BM_DYN_ALLOC_TH_H GENMASK(31, 16) ++#define MTK_WED_RX_BM_DYN_ALLOC_TH_L GENMASK(15, 0) ++ + #define MTK_WED_RING_OFS_BASE 0x00 + #define MTK_WED_RING_OFS_COUNT 0x04 + #define MTK_WED_RING_OFS_CPU_IDX 0x08 +@@ -301,7 +357,9 @@ struct mtk_wdma_desc { + + #define MTK_WDMA_GLO_CFG 0x204 + #define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0) ++#define MTK_WDMA_GLO_CFG_TX_DMA_BUSY BIT(1) + #define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2) ++#define MTK_WDMA_GLO_CFG_RX_DMA_BUSY BIT(3) + #define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26) + #define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27) + #define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28) +@@ -330,4 +388,70 @@ struct mtk_wdma_desc { + /* DMA channel mapping */ + #define HIFSYS_DMA_AG_MAP 0x008 + ++#define MTK_WED_RTQM_GLO_CFG 0xb00 ++#define MTK_WED_RTQM_BUSY BIT(1) ++#define MTK_WED_RTQM_Q_RST BIT(2) ++#define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5) ++#define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20) ++ ++#define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4) ++#define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4) ++#define MTK_WED_RTQM_Q2N_MIB 0xb80 ++#define MTK_WED_RTQM_Q2H_MIB(_n) (0xb84 + (_n) * 0x4) ++ ++#define MTK_WED_RTQM_Q2B_MIB 0xb8c ++#define MTK_WED_RTQM_PFDBK_MIB 0xb90 ++ ++#define MTK_WED_RROQM_GLO_CFG 0xc04 ++#define MTK_WED_RROQM_RST_IDX 0xc08 ++#define MTK_WED_RROQM_RST_IDX_MIOD BIT(0) ++#define MTK_WED_RROQM_RST_IDX_FDBK BIT(4) ++ ++#define MTK_WED_RROQM_MIOD_CTRL0 0xc40 ++#define MTK_WED_RROQM_MIOD_CTRL1 0xc44 ++#define MTK_WED_RROQM_MIOD_CNT GENMASK(11, 0) ++ ++#define MTK_WED_RROQM_MIOD_CTRL2 0xc48 ++#define MTK_WED_RROQM_MIOD_CTRL3 0xc4c ++ ++#define MTK_WED_RROQM_FDBK_CTRL0 0xc50 ++#define MTK_WED_RROQM_FDBK_CTRL1 0xc54 ++#define MTK_WED_RROQM_FDBK_CNT GENMASK(11, 0) ++ ++#define MTK_WED_RROQM_FDBK_CTRL2 0xc58 ++ ++#define MTK_WED_RROQ_BASE_L 0xc80 ++#define MTK_WED_RROQ_BASE_H 0xc84 ++ ++#define MTK_WED_RROQM_MIOD_CFG 0xc8c ++#define MTK_WED_RROQM_MIOD_MID_DW GENMASK(5, 0) ++#define MTK_WED_RROQM_MIOD_MOD_DW GENMASK(13, 8) ++#define MTK_WED_RROQM_MIOD_ENTRY_DW GENMASK(22, 16) ++ ++#define MTK_WED_RROQM_MID_MIB 0xcc0 ++#define MTK_WED_RROQM_MOD_MIB 0xcc4 ++#define MTK_WED_RROQM_MOD_COHERENT_MIB 0xcc8 ++#define MTK_WED_RROQM_FDBK_MIB 0xcd0 ++#define MTK_WED_RROQM_FDBK_COHERENT_MIB 0xcd4 ++#define MTK_WED_RROQM_FDBK_IND_MIB 0xce0 ++#define MTK_WED_RROQM_FDBK_ENQ_MIB 0xce4 ++#define MTK_WED_RROQM_FDBK_ANC_MIB 0xce8 ++#define MTK_WED_RROQM_FDBK_ANC2H_MIB 0xcec ++ ++#define MTK_WED_RX_BM_RX_DMAD 0xd80 ++#define MTK_WED_RX_BM_BASE 0xd84 ++#define MTK_WED_RX_BM_INIT_PTR 0xd88 ++#define MTK_WED_RX_BM_PTR 0xd8c ++#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16) ++#define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0) ++ ++#define MTK_WED_RX_BM_BLEN 0xd90 ++#define MTK_WED_RX_BM_STS 0xd94 ++#define MTK_WED_RX_BM_INTF2 0xd98 ++#define MTK_WED_RX_BM_INTF 0xd9c ++#define MTK_WED_RX_BM_ERR_STS 0xda8 ++ ++#define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000 ++#define MTK_WED_PCIE_INT_MASK 0x0 ++ + #endif +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h +@@ -49,6 +49,10 @@ enum { + MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2), + }; + ++#define MTK_WED_WO_CPU_MCUSYS_RESET_ADDR 0x15194050 ++#define MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK 0x20 ++#define MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK 0x1 ++ + enum { + MTK_WED_WO_REGION_EMI, + MTK_WED_WO_REGION_ILM, +@@ -57,6 +61,28 @@ enum { + __MTK_WED_WO_REGION_MAX, + }; + ++enum mtk_wed_wo_state { ++ MTK_WED_WO_STATE_UNDEFINED, ++ MTK_WED_WO_STATE_INIT, ++ MTK_WED_WO_STATE_ENABLE, ++ MTK_WED_WO_STATE_DISABLE, ++ MTK_WED_WO_STATE_HALT, ++ MTK_WED_WO_STATE_GATING, ++ MTK_WED_WO_STATE_SER_RESET, ++ MTK_WED_WO_STATE_WF_RESET, ++}; ++ ++enum mtk_wed_wo_done_state { ++ MTK_WED_WOIF_UNDEFINED, ++ MTK_WED_WOIF_DISABLE_DONE, ++ MTK_WED_WOIF_TRIGGER_ENABLE, ++ MTK_WED_WOIF_ENABLE_DONE, ++ MTK_WED_WOIF_TRIGGER_GATING, ++ MTK_WED_WOIF_GATING_DONE, ++ MTK_WED_WOIF_TRIGGER_HALT, ++ MTK_WED_WOIF_HALT_DONE, ++}; ++ + enum mtk_wed_dummy_cr_idx { + MTK_WED_DUMMY_CR_FWDL, + MTK_WED_DUMMY_CR_WO_STATUS, +@@ -245,6 +271,8 @@ void mtk_wed_mcu_rx_unsolicited_event(st + struct sk_buff *skb); + int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, + const void *data, int len, bool wait_resp); ++int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, ++ int len); + int mtk_wed_mcu_init(struct mtk_wed_wo *wo); + int mtk_wed_wo_init(struct mtk_wed_hw *hw); + void mtk_wed_wo_deinit(struct mtk_wed_hw *hw); +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -5,10 +5,13 @@ + #include + #include + #include ++#include + + #define MTK_WED_TX_QUEUES 2 + #define MTK_WED_RX_QUEUES 2 + ++#define WED_WO_STA_REC 0x6 ++ + struct mtk_wed_hw; + struct mtk_wdma_desc; + +@@ -41,21 +44,37 @@ enum mtk_wed_wo_cmd { + MTK_WED_WO_CMD_WED_END + }; + ++struct mtk_rxbm_desc { ++ __le32 buf0; ++ __le32 token; ++} __packed __aligned(4); ++ + enum mtk_wed_bus_tye { + MTK_WED_BUS_PCIE, + MTK_WED_BUS_AXI, + }; + ++#define MTK_WED_RING_CONFIGURED BIT(0) + struct mtk_wed_ring { + struct mtk_wdma_desc *desc; + dma_addr_t desc_phys; + u32 desc_size; + int size; ++ u32 flags; + + u32 reg_base; + void __iomem *wpdma; + }; + ++struct mtk_wed_wo_rx_stats { ++ __le16 wlan_idx; ++ __le16 tid; ++ __le32 rx_pkt_cnt; ++ __le32 rx_byte_cnt; ++ __le32 rx_err_cnt; ++ __le32 rx_drop_cnt; ++}; ++ + struct mtk_wed_device { + #ifdef CONFIG_NET_MEDIATEK_SOC_WED + const struct mtk_wed_ops *ops; +@@ -64,9 +83,12 @@ struct mtk_wed_device { + bool init_done, running; + int wdma_idx; + int irq; ++ u8 version; + + struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; ++ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES]; + struct mtk_wed_ring txfree_ring; ++ struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; + struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; + + struct { +@@ -74,7 +96,20 @@ struct mtk_wed_device { + void **pages; + struct mtk_wdma_desc *desc; + dma_addr_t desc_phys; +- } buf_ring; ++ } tx_buf_ring; ++ ++ struct { ++ int size; ++ struct page_frag_cache rx_page; ++ struct mtk_rxbm_desc *desc; ++ dma_addr_t desc_phys; ++ } rx_buf_ring; ++ ++ struct { ++ struct mtk_wed_ring ring; ++ dma_addr_t miod_phys; ++ dma_addr_t fdbk_phys; ++ } rro; + + /* filled by driver: */ + struct { +@@ -83,22 +118,36 @@ struct mtk_wed_device { + struct pci_dev *pci_dev; + }; + enum mtk_wed_bus_tye bus_type; ++ void __iomem *base; ++ u32 phy_base; + + u32 wpdma_phys; + u32 wpdma_int; + u32 wpdma_mask; + u32 wpdma_tx; + u32 wpdma_txfree; ++ u32 wpdma_rx_glo; ++ u32 wpdma_rx; ++ ++ bool wcid_512; + + u16 token_start; + unsigned int nbuf; ++ unsigned int rx_nbuf; ++ unsigned int rx_npkt; ++ unsigned int rx_size; + + u8 tx_tbit[MTK_WED_TX_QUEUES]; ++ u8 rx_tbit[MTK_WED_RX_QUEUES]; + u8 txfree_tbit; + + u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); + int (*offload_enable)(struct mtk_wed_device *wed); + void (*offload_disable)(struct mtk_wed_device *wed); ++ u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size); ++ void (*release_rx_buf)(struct mtk_wed_device *wed); ++ void (*update_wo_rx_stats)(struct mtk_wed_device *wed, ++ struct mtk_wed_wo_rx_stats *stats); + } wlan; + #endif + }; +@@ -107,9 +156,15 @@ struct mtk_wed_ops { + int (*attach)(struct mtk_wed_device *dev); + int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, + void __iomem *regs); ++ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, ++ void __iomem *regs); + int (*txfree_ring_setup)(struct mtk_wed_device *dev, + void __iomem *regs); ++ int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, ++ void *data, int len); + void (*detach)(struct mtk_wed_device *dev); ++ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb, ++ u32 reason, u32 hash); + + void (*stop)(struct mtk_wed_device *dev); + void (*start)(struct mtk_wed_device *dev, u32 irq_mask); +@@ -144,6 +199,16 @@ mtk_wed_device_attach(struct mtk_wed_dev + return ret; + } + ++static inline bool ++mtk_wed_get_rx_capa(struct mtk_wed_device *dev) ++{ ++#ifdef CONFIG_NET_MEDIATEK_SOC_WED ++ return dev->version != 1; ++#else ++ return false; ++#endif ++} ++ + #ifdef CONFIG_NET_MEDIATEK_SOC_WED + #define mtk_wed_device_active(_dev) !!(_dev)->ops + #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) +@@ -160,6 +225,12 @@ mtk_wed_device_attach(struct mtk_wed_dev + (_dev)->ops->irq_get(_dev, _mask) + #define mtk_wed_device_irq_set_mask(_dev, _mask) \ + (_dev)->ops->irq_set_mask(_dev, _mask) ++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \ ++ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs) ++#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ ++ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) ++#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ ++ (_dev)->ops->msg_update(_dev, _id, _msg, _len) + #else + static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) + { +@@ -173,6 +244,9 @@ static inline bool mtk_wed_device_active + #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) + #define mtk_wed_device_irq_get(_dev, _mask) 0 + #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) ++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV ++#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) ++#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV + #endif + + #endif diff --git a/target/linux/generic/pending-6.1/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch b/target/linux/generic/pending-6.1/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch new file mode 100644 index 000000000..bb1066dec --- /dev/null +++ b/target/linux/generic/pending-6.1/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch @@ -0,0 +1,149 @@ +From: Lorenzo Bianconi +Date: Sat, 5 Nov 2022 23:36:22 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add rx mib counters + +Introduce WED RX MIB counters support available on MT7986a SoC. + +Tested-by: Daniel Golle +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c +@@ -2,6 +2,7 @@ + /* Copyright (C) 2021 Felix Fietkau */ + + #include ++#include + #include "mtk_wed.h" + #include "mtk_wed_regs.h" + +@@ -18,6 +19,8 @@ enum { + DUMP_TYPE_WDMA, + DUMP_TYPE_WPDMA_TX, + DUMP_TYPE_WPDMA_TXFREE, ++ DUMP_TYPE_WPDMA_RX, ++ DUMP_TYPE_WED_RRO, + }; + + #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING } +@@ -36,6 +39,9 @@ enum { + + #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n) + #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE) ++#define DUMP_WPDMA_RX_RING(_n) DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n) ++#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO) ++#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO) + + static void + print_reg_val(struct seq_file *s, const char *name, u32 val) +@@ -57,6 +63,7 @@ dump_wed_regs(struct seq_file *s, struct + cur > regs ? "\n" : "", + cur->name); + continue; ++ case DUMP_TYPE_WED_RRO: + case DUMP_TYPE_WED: + val = wed_r32(dev, cur->offset); + break; +@@ -69,6 +76,9 @@ dump_wed_regs(struct seq_file *s, struct + case DUMP_TYPE_WPDMA_TXFREE: + val = wpdma_txfree_r32(dev, cur->offset); + break; ++ case DUMP_TYPE_WPDMA_RX: ++ val = wpdma_rx_r32(dev, cur->base, cur->offset); ++ break; + } + print_reg_val(s, cur->name, val); + } +@@ -132,6 +142,80 @@ wed_txinfo_show(struct seq_file *s, void + } + DEFINE_SHOW_ATTRIBUTE(wed_txinfo); + ++static int ++wed_rxinfo_show(struct seq_file *s, void *data) ++{ ++ static const struct reg_dump regs[] = { ++ DUMP_STR("WPDMA RX"), ++ DUMP_WPDMA_RX_RING(0), ++ DUMP_WPDMA_RX_RING(1), ++ ++ DUMP_STR("WPDMA RX"), ++ DUMP_WED(WED_WPDMA_RX_D_MIB(0)), ++ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)), ++ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)), ++ DUMP_WED(WED_WPDMA_RX_D_MIB(1)), ++ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)), ++ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)), ++ DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB), ++ ++ DUMP_STR("WED RX"), ++ DUMP_WED_RING(WED_RING_RX_DATA(0)), ++ DUMP_WED_RING(WED_RING_RX_DATA(1)), ++ ++ DUMP_STR("WED RRO"), ++ DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0), ++ DUMP_WED(WED_RROQM_MID_MIB), ++ DUMP_WED(WED_RROQM_MOD_MIB), ++ DUMP_WED(WED_RROQM_MOD_COHERENT_MIB), ++ DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0), ++ DUMP_WED(WED_RROQM_FDBK_IND_MIB), ++ DUMP_WED(WED_RROQM_FDBK_ENQ_MIB), ++ DUMP_WED(WED_RROQM_FDBK_ANC_MIB), ++ DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB), ++ ++ DUMP_STR("WED Route QM"), ++ DUMP_WED(WED_RTQM_R2H_MIB(0)), ++ DUMP_WED(WED_RTQM_R2Q_MIB(0)), ++ DUMP_WED(WED_RTQM_Q2H_MIB(0)), ++ DUMP_WED(WED_RTQM_R2H_MIB(1)), ++ DUMP_WED(WED_RTQM_R2Q_MIB(1)), ++ DUMP_WED(WED_RTQM_Q2H_MIB(1)), ++ DUMP_WED(WED_RTQM_Q2N_MIB), ++ DUMP_WED(WED_RTQM_Q2B_MIB), ++ DUMP_WED(WED_RTQM_PFDBK_MIB), ++ ++ DUMP_STR("WED WDMA TX"), ++ DUMP_WED(WED_WDMA_TX_MIB), ++ DUMP_WED_RING(WED_WDMA_RING_TX), ++ ++ DUMP_STR("WDMA TX"), ++ DUMP_WDMA(WDMA_GLO_CFG), ++ DUMP_WDMA_RING(WDMA_RING_TX(0)), ++ DUMP_WDMA_RING(WDMA_RING_TX(1)), ++ ++ DUMP_STR("WED RX BM"), ++ DUMP_WED(WED_RX_BM_BASE), ++ DUMP_WED(WED_RX_BM_RX_DMAD), ++ DUMP_WED(WED_RX_BM_PTR), ++ DUMP_WED(WED_RX_BM_TKID_MIB), ++ DUMP_WED(WED_RX_BM_BLEN), ++ DUMP_WED(WED_RX_BM_STS), ++ DUMP_WED(WED_RX_BM_INTF2), ++ DUMP_WED(WED_RX_BM_INTF), ++ DUMP_WED(WED_RX_BM_ERR_STS), ++ }; ++ struct mtk_wed_hw *hw = s->private; ++ struct mtk_wed_device *dev = hw->wed_dev; ++ ++ if (!dev) ++ return 0; ++ ++ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); ++ ++ return 0; ++} ++DEFINE_SHOW_ATTRIBUTE(wed_rxinfo); + + static int + mtk_wed_reg_set(void *data, u64 val) +@@ -175,4 +259,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w + debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); + debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); + debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); ++ if (hw->version != 1) ++ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, ++ &wed_rxinfo_fops); + } diff --git a/target/linux/generic/pending-6.0/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch similarity index 94% rename from target/linux/generic/pending-6.0/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch rename to target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch index 005fbe933..37b2b8c15 100644 --- a/target/linux/generic/pending-6.0/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch +++ b/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch @@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -6937,6 +6937,7 @@ static int mv88e6xxx_register_switch(str +@@ -6958,6 +6958,7 @@ static int mv88e6xxx_register_switch(str ds->ops = &mv88e6xxx_switch_ops; ds->ageing_time_min = chip->info->age_time_coeff; ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; diff --git a/target/linux/generic/pending-6.0/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch b/target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch similarity index 100% rename from target/linux/generic/pending-6.0/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch rename to target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch diff --git a/target/linux/generic/pending-6.0/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch b/target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch similarity index 100% rename from target/linux/generic/pending-6.0/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch rename to target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch diff --git a/target/linux/generic/pending-6.0/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch b/target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch similarity index 98% rename from target/linux/generic/pending-6.0/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch rename to target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch index a2235a24e..a13d405e6 100644 --- a/target/linux/generic/pending-6.0/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch +++ b/target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch @@ -70,7 +70,7 @@ v1 -> v2: --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig -@@ -1720,4 +1720,19 @@ config GPIO_SIM +@@ -1711,4 +1711,19 @@ config GPIO_SIM endmenu @@ -92,7 +92,7 @@ v1 -> v2: endif --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile -@@ -44,6 +44,7 @@ obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd +@@ -43,6 +43,7 @@ obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o diff --git a/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch b/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch new file mode 100644 index 000000000..2b3e4bbf7 --- /dev/null +++ b/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch @@ -0,0 +1,108 @@ +From fd59b838dd90452f61a17dc9e5ff175205003068 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 15 Sep 2022 18:49:43 +0200 +Subject: [PATCH] OPP: Provide old opp to config_clks on _set_opp + +With the target opp, also pass the old opp to config_clks function. +This can be useful when a driver needs to take decision on what fequency +to set based on what is the current frequency without using a +clk_get_freq call. +Update the only user of custom config_clks (tegra30 devfreq driver) to +this new implementation. + +Signed-off-by: Christian Marangi +--- + drivers/devfreq/tegra30-devfreq.c | 5 +++-- + drivers/opp/core.c | 11 ++++++----- + include/linux/pm_opp.h | 11 ++++++----- + 3 files changed, 15 insertions(+), 12 deletions(-) + +--- a/drivers/devfreq/tegra30-devfreq.c ++++ b/drivers/devfreq/tegra30-devfreq.c +@@ -823,8 +823,9 @@ static int devm_tegra_devfreq_init_hw(st + + static int tegra_devfreq_config_clks_nop(struct device *dev, + struct opp_table *opp_table, +- struct dev_pm_opp *opp, void *data, +- bool scaling_down) ++ struct dev_pm_opp *old_opp, ++ struct dev_pm_opp *opp, ++ void *data, bool scaling_down) + { + /* We want to skip clk configuration via dev_pm_opp_set_opp() */ + return 0; +--- a/drivers/opp/core.c ++++ b/drivers/opp/core.c +@@ -816,7 +816,8 @@ static int _set_opp_voltage(struct devic + + static int + _opp_config_clk_single(struct device *dev, struct opp_table *opp_table, +- struct dev_pm_opp *opp, void *data, bool scaling_down) ++ struct dev_pm_opp *old_opp, struct dev_pm_opp *opp, ++ void *data, bool scaling_down) + { + unsigned long *target = data; + unsigned long freq; +@@ -848,8 +849,8 @@ _opp_config_clk_single(struct device *de + * the order in which they are present in the array while scaling up. + */ + int dev_pm_opp_config_clks_simple(struct device *dev, +- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, +- bool scaling_down) ++ struct opp_table *opp_table, struct dev_pm_opp *old_opp, ++ struct dev_pm_opp *opp, void *data, bool scaling_down) + { + int ret, i; + +@@ -1121,7 +1122,7 @@ static int _set_opp(struct device *dev, + } + + if (opp_table->config_clks) { +- ret = opp_table->config_clks(dev, opp_table, opp, clk_data, scaling_down); ++ ret = opp_table->config_clks(dev, opp_table, old_opp, opp, clk_data, scaling_down); + if (ret) + return ret; + } +@@ -1196,7 +1197,7 @@ int dev_pm_opp_set_rate(struct device *d + * equivalent to a clk_set_rate() + */ + if (!_get_opp_count(opp_table)) { +- ret = opp_table->config_clks(dev, opp_table, NULL, ++ ret = opp_table->config_clks(dev, opp_table, NULL, NULL, + &target_freq, false); + goto put_opp_table; + } +--- a/include/linux/pm_opp.h ++++ b/include/linux/pm_opp.h +@@ -61,7 +61,8 @@ typedef int (*config_regulators_t)(struc + struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, + struct regulator **regulators, unsigned int count); + +-typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table, ++typedef int (*config_clks_t)(struct device *dev, ++ struct opp_table *opp_table, struct dev_pm_opp *old_opp, + struct dev_pm_opp *opp, void *data, bool scaling_down); + + /** +@@ -160,8 +161,8 @@ int dev_pm_opp_set_config(struct device + int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); + void dev_pm_opp_clear_config(int token); + int dev_pm_opp_config_clks_simple(struct device *dev, +- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, +- bool scaling_down); ++ struct opp_table *opp_table, struct dev_pm_opp *old_opp, ++ struct dev_pm_opp *opp, void *data, bool scaling_down); + + struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp); + int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); +@@ -346,8 +347,8 @@ static inline int devm_pm_opp_set_config + static inline void dev_pm_opp_clear_config(int token) {} + + static inline int dev_pm_opp_config_clks_simple(struct device *dev, +- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, +- bool scaling_down) ++ struct opp_table *opp_table, struct dev_pm_opp *old_opp, ++ struct dev_pm_opp *opp, void *data, bool scaling_down) + { + return -EOPNOTSUPP; + } diff --git a/target/linux/generic/pending-6.0/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch similarity index 100% rename from target/linux/generic/pending-6.0/810-pci_disable_common_quirks.patch rename to target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch diff --git a/target/linux/generic/pending-6.0/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch similarity index 98% rename from target/linux/generic/pending-6.0/811-pci_disable_usb_common_quirks.patch rename to target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch index 42a839783..98ea4c06d 100644 --- a/target/linux/generic/pending-6.0/811-pci_disable_usb_common_quirks.patch +++ b/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch @@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau #endif /* __LINUX_USB_PCI_QUIRKS_H */ --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h -@@ -484,7 +484,14 @@ extern int usb_hcd_pci_probe(struct pci_ +@@ -483,7 +483,14 @@ extern int usb_hcd_pci_probe(struct pci_ extern void usb_hcd_pci_remove(struct pci_dev *dev); extern void usb_hcd_pci_shutdown(struct pci_dev *dev); diff --git a/target/linux/generic/pending-6.0/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch similarity index 100% rename from target/linux/generic/pending-6.0/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch rename to target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch diff --git a/target/linux/generic/pending-6.0/834-ledtrig-libata.patch b/target/linux/generic/pending-6.1/834-ledtrig-libata.patch similarity index 92% rename from target/linux/generic/pending-6.0/834-ledtrig-libata.patch rename to target/linux/generic/pending-6.1/834-ledtrig-libata.patch index 84415e40d..4a1693185 100644 --- a/target/linux/generic/pending-6.0/834-ledtrig-libata.patch +++ b/target/linux/generic/pending-6.1/834-ledtrig-libata.patch @@ -64,8 +64,8 @@ Signed-off-by: Daniel Golle + /** * ata_build_rw_tf - Build ATA taskfile for given read/write request - * @tf: Target ATA taskfile -@@ -4621,6 +4634,9 @@ void __ata_qc_complete(struct ata_queued + * @qc: Metadata associated with the taskfile to build +@@ -4619,6 +4632,9 @@ void __ata_qc_complete(struct ata_queued link->active_tag = ATA_TAG_POISON; ap->nr_active_links--; } @@ -75,7 +75,7 @@ Signed-off-by: Daniel Golle /* clear exclusive status */ if (unlikely(qc->flags & ATA_QCFLAG_CLEAR_EXCL && -@@ -5327,6 +5343,9 @@ struct ata_port *ata_port_alloc(struct a +@@ -5325,6 +5341,9 @@ struct ata_port *ata_port_alloc(struct a ap->stats.unhandled_irq = 1; ap->stats.idle_irq = 1; #endif @@ -85,7 +85,7 @@ Signed-off-by: Daniel Golle ata_sff_port_init(ap); return ap; -@@ -5362,6 +5381,12 @@ static void ata_host_release(struct kref +@@ -5360,6 +5379,12 @@ static void ata_host_release(struct kref kfree(ap->pmp_link); kfree(ap->slave_link); @@ -98,7 +98,7 @@ Signed-off-by: Daniel Golle kfree(ap); host->ports[i] = NULL; } -@@ -5764,7 +5789,23 @@ int ata_host_register(struct ata_host *h +@@ -5762,7 +5787,23 @@ int ata_host_register(struct ata_host *h host->ports[i]->print_id = atomic_inc_return(&ata_print_id); host->ports[i]->local_port_no = i + 1; } diff --git a/target/linux/generic/pending-6.0/840-hwrng-bcm2835-set-quality-to-1000.patch b/target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch similarity index 100% rename from target/linux/generic/pending-6.0/840-hwrng-bcm2835-set-quality-to-1000.patch rename to target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch diff --git a/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch b/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch new file mode 100644 index 000000000..fc61ee202 --- /dev/null +++ b/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch @@ -0,0 +1,102 @@ +From 663b9f99bb35dbc0c7b685f71ee3668a60d31320 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Beh=C3=BAn?= +Date: Mon, 10 Jan 2022 02:02:00 +0100 +Subject: [PATCH] PCI: aardvark: Make main irq_chip structure a static driver + structure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Marc Zyngier says [1] that we should use struct irq_chip as a global +static struct in the driver. Even though the structure currently +contains a dynamic member (parent_device), Marc says [2] that he plans +to kill it and make the structure completely static. + +We have already converted others irq_chip structures in this driver in +this way, but we omitted this one because the .name member is +dynamically created from device's name, and the name is displayed in +sysfs, so changing it would break sysfs ABI. + +The rationale for changing the name (to "advk-INT") in spite of sysfs +ABI, and thus allowing to convert to a static structure, is that after +the other changes we made in this series, the IRQ chip is basically +something different: it no logner generates ERR and PME interrupts (they +are generated by emulated bridge's rp_irq_chip). + +[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz@kernel.org/ +[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz@kernel.org/ + +Signed-off-by: Marek Behún +--- + drivers/pci/controller/pci-aardvark.c | 25 +++++++------------------ + 1 file changed, 7 insertions(+), 18 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -277,7 +277,6 @@ struct advk_pcie { + u8 wins_count; + struct irq_domain *rp_irq_domain; + struct irq_domain *irq_domain; +- struct irq_chip irq_chip; + raw_spinlock_t irq_lock; + struct irq_domain *msi_domain; + struct irq_domain *msi_inner_domain; +@@ -1426,14 +1425,19 @@ static void advk_pcie_irq_unmask(struct + raw_spin_unlock_irqrestore(&pcie->irq_lock, flags); + } + ++static struct irq_chip advk_irq_chip = { ++ .name = "advk-INT", ++ .irq_mask = advk_pcie_irq_mask, ++ .irq_unmask = advk_pcie_irq_unmask, ++}; ++ + static int advk_pcie_irq_map(struct irq_domain *h, + unsigned int virq, irq_hw_number_t hwirq) + { + struct advk_pcie *pcie = h->host_data; + + irq_set_status_flags(virq, IRQ_LEVEL); +- irq_set_chip_and_handler(virq, &pcie->irq_chip, +- handle_level_irq); ++ irq_set_chip_and_handler(virq, &advk_irq_chip, handle_level_irq); + irq_set_chip_data(virq, pcie); + + return 0; +@@ -1492,7 +1496,6 @@ static int advk_pcie_init_irq_domain(str + struct device *dev = &pcie->pdev->dev; + struct device_node *node = dev->of_node; + struct device_node *pcie_intc_node; +- struct irq_chip *irq_chip; + int ret = 0; + + raw_spin_lock_init(&pcie->irq_lock); +@@ -1503,28 +1506,14 @@ static int advk_pcie_init_irq_domain(str + return -ENODEV; + } + +- irq_chip = &pcie->irq_chip; +- +- irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", +- dev_name(dev)); +- if (!irq_chip->name) { +- ret = -ENOMEM; +- goto out_put_node; +- } +- +- irq_chip->irq_mask = advk_pcie_irq_mask; +- irq_chip->irq_unmask = advk_pcie_irq_unmask; +- + pcie->irq_domain = + irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, + &advk_pcie_irq_domain_ops, pcie); + if (!pcie->irq_domain) { + dev_err(dev, "Failed to get a INTx IRQ domain\n"); + ret = -ENOMEM; +- goto out_put_node; + } + +-out_put_node: + of_node_put(pcie_intc_node); + return ret; + } diff --git a/target/linux/generic/pending-6.0/920-mangle_bootargs.patch b/target/linux/generic/pending-6.1/920-mangle_bootargs.patch similarity index 91% rename from target/linux/generic/pending-6.0/920-mangle_bootargs.patch rename to target/linux/generic/pending-6.1/920-mangle_bootargs.patch index e87b48f4f..60ceff00d 100644 --- a/target/linux/generic/pending-6.0/920-mangle_bootargs.patch +++ b/target/linux/generic/pending-6.1/920-mangle_bootargs.patch @@ -13,7 +13,7 @@ Signed-off-by: Imre Kaloz --- a/init/Kconfig +++ b/init/Kconfig -@@ -1809,6 +1809,15 @@ config EMBEDDED +@@ -1826,6 +1826,15 @@ config EMBEDDED an embedded system so certain expert options are available for configuration. @@ -31,7 +31,7 @@ Signed-off-by: Imre Kaloz help --- a/init/main.c +++ b/init/main.c -@@ -607,6 +607,29 @@ static inline void setup_nr_cpu_ids(void +@@ -609,6 +609,29 @@ static inline void setup_nr_cpu_ids(void static inline void smp_prepare_cpus(unsigned int maxcpus) { } #endif @@ -61,7 +61,7 @@ Signed-off-by: Imre Kaloz /* * We need to store the untouched command line for future reference. * We also need to store the touched command line since the parameter -@@ -950,6 +973,7 @@ asmlinkage __visible void __init __no_sa +@@ -957,6 +980,7 @@ asmlinkage __visible void __init __no_sa pr_notice("%s", linux_banner); early_security_init(); setup_arch(&command_line); diff --git a/target/linux/generic/pending-6.1/930-qcom-qmi-helpers.patch b/target/linux/generic/pending-6.1/930-qcom-qmi-helpers.patch new file mode 100644 index 000000000..2f4277420 --- /dev/null +++ b/target/linux/generic/pending-6.1/930-qcom-qmi-helpers.patch @@ -0,0 +1,11 @@ +--- a/drivers/soc/qcom/Kconfig ++++ b/drivers/soc/qcom/Kconfig +@@ -92,7 +92,7 @@ config QCOM_PDR_HELPERS + select QCOM_QMI_HELPERS + + config QCOM_QMI_HELPERS +- tristate ++ tristate "Qualcomm QMI Helpers" + depends on NET + + config QCOM_RMTFS_MEM diff --git a/target/linux/rockchip/armv8/config-6.1 b/target/linux/rockchip/armv8/config-6.1 new file mode 100644 index 000000000..d1b2050cf --- /dev/null +++ b/target/linux/rockchip/armv8/config-6.1 @@ -0,0 +1,736 @@ +CONFIG_64BIT=y +CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_FORCE_MAX_ORDER=11 +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=33 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_STACKWALK=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_ARC_EMAC_CORE=y +CONFIG_ARM64=y +CONFIG_ARM64_CNP=y +CONFIG_ARM64_EPAN=y +CONFIG_ARM64_ERRATUM_1742098=y +CONFIG_ARM64_ERRATUM_819472=y +CONFIG_ARM64_ERRATUM_824069=y +CONFIG_ARM64_ERRATUM_826319=y +CONFIG_ARM64_ERRATUM_827319=y +CONFIG_ARM64_ERRATUM_832075=y +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_ERRATUM_858921=y +CONFIG_ARM64_HW_AFDBM=y +CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y +CONFIG_ARM64_MODULE_PLTS=y +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_PAN=y +CONFIG_ARM64_PA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +CONFIG_ARM64_PTR_AUTH=y +CONFIG_ARM64_PTR_AUTH_KERNEL=y +CONFIG_ARM64_RAS_EXTN=y +CONFIG_ARM64_SVE=y +# CONFIG_ARM64_SW_TTBR0_PAN is not set +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_ARM64_VA_BITS=48 +# CONFIG_ARM64_VA_BITS_39 is not set +CONFIG_ARM64_VA_BITS_48=y +CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y +# CONFIG_ARMV8_DEPRECATED is not set +CONFIG_ARM_AMBA=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_ARM_GIC_V3_ITS_PCI=y +CONFIG_ARM_MHU=y +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y +CONFIG_ARM_PSCI_FW=y +CONFIG_ARM_RK3328_DMC_DEVFREQ=y +# CONFIG_ARM_RK3399_DMC_DEVFREQ is not set +# CONFIG_ARM_SCMI_CPUFREQ is not set +CONFIG_ARM_SCMI_HAVE_SHMEM=y +CONFIG_ARM_SCMI_HAVE_TRANSPORT=y +CONFIG_ARM_SCMI_POWER_CONTROL=y +CONFIG_ARM_SCMI_POWER_DOMAIN=y +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y +CONFIG_ARM_SCMI_TRANSPORT_SMC=y +# CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE is not set +CONFIG_ARM_SCPI_CPUFREQ=y +CONFIG_ARM_SCPI_POWER_DOMAIN=y +CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_ARM_SMMU=y +CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y +# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set +CONFIG_ARM_SMMU_V3=y +# CONFIG_ARM_SMMU_V3_SVA is not set +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GPIO=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_BSG_COMMON=y +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NVME=y +CONFIG_BLK_DEV_PCIESSD_MTIP32XX=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BRCMSTB_GISB_ARB=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CHARGER_GPIO=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLK_PX30=y +CONFIG_CLK_RK3308=y +CONFIG_CLK_RK3328=y +CONFIG_CLK_RK3368=y +CONFIG_CLK_RK3399=y +CONFIG_CLK_RK3568=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMA=y +CONFIG_CMA_ALIGNMENT=8 +CONFIG_CMA_AREAS=7 +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +CONFIG_CMA_SIZE_MBYTES=5 +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_RK808=y +CONFIG_COMMON_CLK_ROCKCHIP=y +CONFIG_COMMON_CLK_SCMI=y +CONFIG_COMMON_CLK_SCPI=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +CONFIG_COMPAT=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_CONFIGFS_FS=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y +CONFIG_CONTIG_ALLOC=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_ISOLATION=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_THERMAL=y +CONFIG_CRASH_CORE=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CRC64=y +CONFIG_CRC64_ROCKSOFT=y +CONFIG_CRC_T10DIF=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CHACHA20_NEON=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC64_ROCKSOFT=y +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_ECC=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y +CONFIG_CRYPTO_LIB_DES=y +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_POLYVAL=y +CONFIG_CRYPTO_POLYVAL_ARM64_CE=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA256_ARM64=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SHA3_ARM64=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA512_ARM64=y +CONFIG_CRYPTO_SHA512_ARM64_CE=y +CONFIG_CRYPTO_SM3=y +CONFIG_CRYPTO_SM3_ARM64_CE=y +CONFIG_CRYPTO_SM4=y +CONFIG_CRYPTO_SM4_ARM64_CE=y +CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y +CONFIG_CRYPTO_XTS=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y +# CONFIG_DEVFREQ_GOV_PASSIVE is not set +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +# CONFIG_DEVFREQ_THERMAL is not set +CONFIG_DEVMEM=y +# CONFIG_DEVPORT is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_DEVTMPFS_SAFE is not set +CONFIG_DMADEVICES=y +CONFIG_DMA_CMA=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_DNOTIFY=y +CONFIG_DTC=y +CONFIG_DT_IDLE_GENPD=y +CONFIG_DT_IDLE_STATES=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_DWMAC_DWC_QOS_ETH=y +CONFIG_DWMAC_GENERIC=y +CONFIG_DWMAC_ROCKCHIP=y +CONFIG_DW_WATCHDOG=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EEPROM_AT24=y +CONFIG_EMAC_ROCKCHIP=y +CONFIG_ENERGY_MODEL=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXTCON=y +CONFIG_F2FS_FS=y +CONFIG_FANOTIFY=y +CONFIG_FHANDLE=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FORTIFY_SOURCE is not set +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=2048 +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FWNODE_MDIO=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC12_NO_ARRAY_BOUNDS=y +CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IOREMAP=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_DWAPB=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_ROCKCHIP=y +# CONFIG_HARDENED_USERCOPY is not set +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HID=y +CONFIG_HID_GENERIC=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_PCIE is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y +# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set +CONFIG_HWMON=y +CONFIG_HWSPINLOCK=y +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_ROCKCHIP=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_RK3X=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_INDIRECT_PIO=y +CONFIG_INET_TABLE_PERTURB_ORDER=16 +CONFIG_INPUT=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_MATRIXKMAP=y +# CONFIG_INPUT_MISC is not set +CONFIG_IOMMU_API=y +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y +CONFIG_IOMMU_DMA=y +CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_IO_PGTABLE=y +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +CONFIG_IOMMU_IO_PGTABLE_LPAE=y +# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set +CONFIG_IOMMU_SUPPORT=y +# CONFIG_IO_STRICT_DEVMEM is not set +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JLSEMI_JL2XX1_PHY=y +CONFIG_JUMP_LABEL=y +CONFIG_KALLSYMS=y +CONFIG_KEXEC_CORE=y +CONFIG_KEXEC_FILE=y +CONFIG_KSM=y +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_LIBCRC32C=y +CONFIG_LIBFDT=y +CONFIG_LOCALVERSION_AUTO=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LOG_BUF_SHIFT=19 +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAILBOX=y +# CONFIG_MAILBOX_TEST is not set +CONFIG_MDIO_BUS=y +CONFIG_MDIO_BUS_MUX=y +CONFIG_MDIO_BUS_MUX_GPIO=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEMFD_CREATE=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_MFD_CORE=y +# CONFIG_MFD_KHADAS_MCU is not set +CONFIG_MFD_RK808=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_CQHCI=y +CONFIG_MMC_DW=y +# CONFIG_MMC_DW_BLUEFIELD is not set +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_HI3798CV200 is not set +# CONFIG_MMC_DW_K3 is not set +# CONFIG_MMC_DW_PCI is not set +CONFIG_MMC_DW_PLTFM=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_SDHCI_OF_DWCMSHC=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MOTORCOMM_PHY=y +CONFIG_MQ_IOSCHED_DEADLINE=y +# CONFIG_MTD_CFI is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_SELFTESTS=y +CONFIG_NLS=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NVMEM=y +# CONFIG_NVMEM_ROCKCHIP_EFUSE is not set +# CONFIG_NVMEM_ROCKCHIP_OTP is not set +CONFIG_NVMEM_SYSFS=y +CONFIG_NVME_CORE=y +# CONFIG_NVME_HWMON is not set +# CONFIG_NVME_MULTIPATH is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IOMMU=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_RESOLVE=y +CONFIG_OLD_SIGSUSPEND3=y +# CONFIG_OVERLAY_FS_XINO_AUTO is not set +CONFIG_PADATA=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAHOLE_VERSION=0 +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_PARTITION_PERCPU=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEASPM=y +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_PERFORMANCE is not set +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +CONFIG_PCIE_PME=y +CONFIG_PCIE_ROCKCHIP=y +CONFIG_PCIE_ROCKCHIP_DW_HOST=y +CONFIG_PCIE_ROCKCHIP_HOST=y +CONFIG_PCI_DEBUG=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PCI_STUB=y +CONFIG_PCS_XPCS=y +CONFIG_PGTABLE_LEVELS=4 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PHY_ROCKCHIP_DP=y +# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set +CONFIG_PHY_ROCKCHIP_EMMC=y +# CONFIG_PHY_ROCKCHIP_INNO_HDMI is not set +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y +CONFIG_PHY_ROCKCHIP_PCIE=y +CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y +CONFIG_PHY_ROCKCHIP_TYPEC=y +CONFIG_PHY_ROCKCHIP_USB=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_RK805 is not set +CONFIG_PINCTRL_ROCKCHIP=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PL330_DMA=y +CONFIG_PLATFORM_MHU=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_DEVFREQ=y +CONFIG_PM_DEVFREQ_EVENT=y +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_OPP=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PREEMPT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_BUILD=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_VMCORE=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_PWM=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_PWM_SYSFS=y +# CONFIG_QCOM_QMI_HELPERS is not set +# CONFIG_QFMT_V2 is not set +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_RAID_ATTRS=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_RANDOMIZE_MODULE_REGION_FULL=y +CONFIG_RANDSTRUCT_NONE=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +# CONFIG_RAVE_SP_CORE is not set +CONFIG_RCU_TRACE=y +CONFIG_REALTEK_PHY=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_IRQ=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_ARM_SCMI is not set +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK808=y +CONFIG_RELOCATABLE=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_SCMI=y +CONFIG_RFS_ACCEL=y +CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_ROCKCHIP_IOMMU=y +CONFIG_ROCKCHIP_MBOX=y +CONFIG_ROCKCHIP_PHY=y +CONFIG_ROCKCHIP_PM_DOMAINS=y +CONFIG_ROCKCHIP_THERMAL=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +CONFIG_RPS=y +CONFIG_RSEQ=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_RK808=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_NVMEM=y +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SCHED_MC=y +CONFIG_SCSI=y +CONFIG_SCSI_COMMON=y +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_PROC_FS is not set +CONFIG_SCSI_SAS_ATTRS=y +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SENSORS_ARM_SCMI is not set +CONFIG_SENSORS_ARM_SCPI=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_8250_DWLIB=y +CONFIG_SERIAL_8250_EXAR=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIO=y +CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SG_POOL=y +# CONFIG_SHORTCUT_FE is not set +CONFIG_SLUB_DEBUG=y +CONFIG_SMP=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_DYNAMIC=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_ROCKCHIP=y +CONFIG_SPI_SPIDEV=y +# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set +CONFIG_SQUASHFS_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FILE_CACHE=y +# CONFIG_SQUASHFS_FILE_DIRECT is not set +CONFIG_SRAM=y +CONFIG_SRCU=y +CONFIG_STACKDEPOT=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_PER_TASK=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_STACKTRACE=y +# CONFIG_STAGING is not set +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +CONFIG_STRICT_DEVMEM=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_SWAP is not set +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYNC_FILE=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_SYSVIPC_COMPAT=y +# CONFIG_TEXTSEARCH is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_EMULATION=y +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_THREAD_INFO_IN_TASK=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TRACE_CLOCK=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y +# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set +CONFIG_TRANS_TABLE=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_TYPEC=y +# CONFIG_TYPEC_ANX7411 is not set +CONFIG_TYPEC_FUSB302=y +# CONFIG_TYPEC_HD3SS3220 is not set +# CONFIG_TYPEC_MUX_FSA4480 is not set +# CONFIG_TYPEC_MUX_PI3USB30532 is not set +# CONFIG_TYPEC_RT1719 is not set +# CONFIG_TYPEC_STUSB160X is not set +# CONFIG_TYPEC_TCPCI is not set +CONFIG_TYPEC_TCPM=y +# CONFIG_TYPEC_TPS6598X is not set +# CONFIG_TYPEC_WUSB3801 is not set +# CONFIG_UACCE is not set +# CONFIG_UCLAMP_TASK is not set +# CONFIG_UEVENT_HELPER is not set +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_UNMAP_KERNEL_AT_EL0=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_HOST=y +CONFIG_USB_DWC3_OF_SIMPLE=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_HID=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_PHY=y +CONFIG_USB_ROLE_SWITCH=y +CONFIG_USB_STORAGE=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_BUS=y +CONFIG_USB_ULPI_VIEWPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y +# CONFIG_VIRTIO_MENU is not set +CONFIG_VMAP_STACK=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XARRAY_MULTI=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA32=y diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3566-lubancat1.dts b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3566-lubancat1.dts similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3566-lubancat1.dts rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3566-lubancat1.dts diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3566-lubancat1n.dts b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3566-lubancat1n.dts similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3566-lubancat1n.dts rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3566-lubancat1n.dts diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dts b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dts similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dts rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dts diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dtsi b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dtsi similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dtsi rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-lubancat2.dtsi diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dts b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dts similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dts rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dts diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dtsi b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dtsi similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dtsi rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-lubancat2n.dtsi diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-opc-h68k.dts b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-opc-h68k.dts similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-opc-h68k.dts rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-opc-h68k.dts diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts b/target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts similarity index 100% rename from target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts rename to target/linux/rockchip/files-6.1/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3399-guangmiao-g4c.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3399-guangmiao-g4c.dts deleted file mode 100644 index c6220b3c8..000000000 --- a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3399-guangmiao-g4c.dts +++ /dev/null @@ -1,666 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) - -/dts-v1/; -#include -#include "rk3399.dtsi" -#include "rk3399-opp.dtsi" - -/ { - model = "SHAREVDI GuangMiao G4C"; - compatible = "sharevdi,guangmiao-g4c", "rockchip,rk3399"; - - /delete-node/ display-subsystem; - - aliases { - led-boot = &status_led; - led-failsafe = &status_led; - led-running = &status_led; - led-upgrade = &status_led; - }; - - chosen { - stdout-path = "serial2:1500000n8"; - }; - - clkin_gmac: external-gmac-clock { - compatible = "fixed-clock"; - clock-frequency = <125000000>; - clock-output-names = "clkin_gmac"; - #clock-cells = <0>; - }; - - vcc_sys: vcc-sys { - compatible = "regulator-fixed"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-name = "vcc_sys"; - }; - - vcc3v3_sys: vcc3v3-sys { - compatible = "regulator-fixed"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-name = "vcc3v3_sys"; - vin-supply = <&vcc_sys>; - }; - - vcc_0v9: vcc-0v9 { - compatible = "regulator-fixed"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <900000>; - regulator-name = "vcc_0v9"; - vin-supply = <&vcc3v3_sys>; - }; - - vcc5v0_host0: vcc5v0-host0 { - compatible = "regulator-fixed"; - regulator-always-on; - regulator-boot-on; - regulator-name = "vcc5v0_host0"; - vin-supply = <&vcc_sys>; - }; - - vdd_log: vdd-log { - compatible = "pwm-regulator"; - pwms = <&pwm2 0 25000 1>; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1400000>; - regulator-name = "vdd_log"; - vin-supply = <&vcc_sys>; - }; - - gpio-keys { - compatible = "gpio-keys"; - autorepeat; - pinctrl-names = "default"; - pinctrl-0 = <&reset_button_pin>; - - reset { - debounce-interval = <100>; - gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; - label = "reset"; - linux,code = ; - wakeup-source; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&lan_led_pin>, <&status_led_pin>, <&wan_led_pin>; - - lan_led: led-lan { - gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; - label = "green:lan"; - }; - - status_led: led-status { - gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; - label = "green:status"; - }; - - wan_led: led-wan { - gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; - label = "green:wan"; - }; - }; -}; - -&cpu_b0 { - cpu-supply = <&vdd_cpu_b>; -}; - -&cpu_b1 { - cpu-supply = <&vdd_cpu_b>; -}; - -&cpu_l0 { - cpu-supply = <&vdd_cpu_l>; -}; - -&cpu_l1 { - cpu-supply = <&vdd_cpu_l>; -}; - -&cpu_l2 { - cpu-supply = <&vdd_cpu_l>; -}; - -&cpu_l3 { - cpu-supply = <&vdd_cpu_l>; -}; - -&emmc_phy { - status = "okay"; -}; - -&gmac { - assigned-clock-parents = <&clkin_gmac>; - assigned-clocks = <&cru SCLK_RMII_SRC>; - clock_in_out = "input"; - pinctrl-names = "default"; - pinctrl-0 = <&rgmii_pins>, <&phy_intb>, <&phy_pmeb>, <&phy_rstb>; - phy-handle = <&rtl8211e>; - phy-mode = "rgmii"; - phy-supply = <&vcc3v3_s3>; - tx_delay = <0x28>; - rx_delay = <0x11>; - status = "okay"; - - mdio { - compatible = "snps,dwmac-mdio"; - #address-cells = <1>; - #size-cells = <0>; - - rtl8211e: ethernet-phy@1 { - reg = <1>; - interrupt-parent = <&gpio3>; - interrupts = ; - reset-assert-us = <10000>; - reset-deassert-us = <30000>; - reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; - }; - }; -}; - -&gpu { - mali-supply = <&vdd_gpu>; - status = "okay"; -}; - -&i2c0 { - clock-frequency = <400000>; - i2c-scl-rising-time-ns = <160>; - i2c-scl-falling-time-ns = <30>; - status = "okay"; - - vdd_cpu_b: regulator@40 { - compatible = "silergy,syr827"; - reg = <0x40>; - fcs,suspend-voltage-selector = <1>; - pinctrl-names = "default"; - pinctrl-0 = <&cpu_b_sleep>; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <712500>; - regulator-max-microvolt = <1500000>; - regulator-name = "vdd_cpu_b"; - regulator-ramp-delay = <1000>; - vin-supply = <&vcc_sys>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdd_gpu: regulator@41 { - compatible = "silergy,syr828"; - reg = <0x41>; - fcs,suspend-voltage-selector = <1>; - pinctrl-names = "default"; - pinctrl-0 = <&gpu_sleep>; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <712500>; - regulator-max-microvolt = <1500000>; - regulator-name = "vdd_gpu"; - regulator-ramp-delay = <1000>; - vin-supply = <&vcc_sys>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - rk808: pmic@1b { - compatible = "rockchip,rk808"; - reg = <0x1b>; - clock-output-names = "rtc_clko_soc", "rtc_clko_wifi"; - #clock-cells = <1>; - interrupt-parent = <&gpio1>; - interrupts = <21 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&pmic_int_l>; - rockchip,system-power-controller; - wakeup-source; - - vcc1-supply = <&vcc_sys>; - vcc2-supply = <&vcc_sys>; - vcc3-supply = <&vcc_sys>; - vcc4-supply = <&vcc_sys>; - vcc6-supply = <&vcc_sys>; - vcc7-supply = <&vcc_sys>; - vcc8-supply = <&vcc_3v0>; - vcc9-supply = <&vcc_sys>; - vcc10-supply = <&vcc_sys>; - vcc11-supply = <&vcc_sys>; - vcc12-supply = <&vcc_sys>; - vddio-supply = <&vcc_3v0>; - - regulators { - vdd_center: DCDC_REG1 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <1350000>; - regulator-name = "vdd_center"; - regulator-ramp-delay = <6001>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdd_cpu_l: DCDC_REG2 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <1350000>; - regulator-name = "vdd_cpu_l"; - regulator-ramp-delay = <6001>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc_ddr: DCDC_REG3 { - regulator-always-on; - regulator-boot-on; - regulator-name = "vcc_ddr"; - - regulator-state-mem { - regulator-on-in-suspend; - }; - }; - - vcc_1v8: DCDC_REG4 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "vcc_1v8"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - vcc_vldo1: LDO_REG1 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "vcc_vldo1"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc_vldo2: LDO_REG2 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "vcc_vldo2"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcca_1v8: LDO_REG3 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "vcca_1v8"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - vcc_sdio: LDO_REG4 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-name = "vcc_sdio"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; - }; - }; - - vcc3v0_sd: LDO_REG5 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-name = "vcc3v0_sd"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3000000>; - }; - }; - - vcc_1v5: LDO_REG6 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1500000>; - regulator-max-microvolt = <1500000>; - regulator-name = "vcc_1v5"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1500000>; - }; - }; - - vcca1v8_codec: LDO_REG7 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "vcca1v8_codec"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc_3v0: LDO_REG8 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-name = "vcc_3v0"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3000000>; - }; - }; - - vcc3v3_s3: SWITCH_REG1 { - regulator-always-on; - regulator-boot-on; - regulator-name = "vcc3v3_s3"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc3v3_s0: SWITCH_REG2 { - regulator-always-on; - regulator-boot-on; - regulator-name = "vcc3v3_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - }; - }; -}; - -&i2c3 { - i2c-scl-rising-time-ns = <450>; - i2c-scl-falling-time-ns = <15>; - status = "okay"; -}; - -&io_domains { - bt656-supply = <&vcc_1v8>; - audio-supply = <&vcca1v8_codec>; - sdmmc-supply = <&vcc_sdio>; - gpio1830-supply = <&vcc_3v0>; - status = "okay"; -}; - -&pcie_phy { - assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>; - assigned-clock-rates = <100000000>; - assigned-clocks = <&cru SCLK_PCIEPHY_REF>; - status = "okay"; -}; - -&pcie0 { - ep-gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>; - max-link-speed = <1>; - num-lanes = <1>; - pinctrl-names = "default"; - pinctrl-0 = <&pcie_clkreqnb_cpm>; - vpcie0v9-supply = <&vcc_0v9>; - vpcie1v8-supply = <&vcca_1v8>; - vpcie3v3-supply = <&vcc3v3_sys>; - status = "okay"; - - pcie@0 { - reg = <0x00000000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - - pcie-eth@0,0 { - compatible = "realtek,r8168"; - reg = <0x000000 0 0 0 0>; - - realtek,led-data = <0x87>; - }; - }; -}; - -&pinctrl { - gpio-leds { - lan_led_pin: lan-led-pin { - rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - status_led_pin: status-led-pin { - rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - wan_led_pin: wan-led-pin { - rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - gmac { - phy_intb: phy-intb { - rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; - }; - - phy_pmeb: phy-pmeb { - rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; - }; - - phy_rstb: phy-rstb { - rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - pmic { - cpu_b_sleep: cpu-b-sleep { - rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; - }; - - gpu_sleep: gpu-sleep { - rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; - }; - - pmic_int_l: pmic-int-l { - rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - rockchip-key { - reset_button_pin: reset-button-pin { - rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - sdio { - bt_reg_on_h: bt-reg-on-h { - /* external pullup to VCC1V8_PMUPLL */ - rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - sdmmc { - sdmmc0_det_l: sdmmc0-det-l { - rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; -}; - -&pmu_io_domains { - pmu1830-supply = <&vcc_3v0>; - status = "okay"; -}; - -&pwm0 { - status = "okay"; -}; - -&pwm1 { - status = "okay"; -}; - -&pwm2 { - pinctrl-names = "active"; - pinctrl-0 = <&pwm2_pin_pull_down>; - status = "okay"; -}; - -&saradc { - vref-supply = <&vcc_1v8>; - status = "okay"; -}; - -&sdhci { - bus-width = <8>; - mmc-hs200-1_8v; - non-removable; - status = "okay"; -}; - -&sdmmc { - bus-width = <4>; - cap-mmc-highspeed; - cap-sd-highspeed; - cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; - disable-wp; - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc0_det_l>; - vqmmc-supply = <&vcc_sdio>; - status = "okay"; -}; - -&tcphy0 { - status = "okay"; -}; - -&tcphy1 { - status = "okay"; -}; - -&tsadc { - rockchip,hw-tshut-mode = <1>; - rockchip,hw-tshut-polarity = <1>; - status = "okay"; -}; - -&u2phy0 { - status = "okay"; -}; - -&u2phy0_host { - phy-supply = <&vcc5v0_host0>; - status = "okay"; -}; - -&u2phy0_otg { - status = "okay"; -}; - -&u2phy1 { - status = "okay"; -}; - -&u2phy1_host { - phy-supply = <&vcc5v0_host0>; - status = "okay"; -}; - -&u2phy1_otg { - status = "okay"; -}; - -&uart2 { - status = "okay"; -}; - -&usbdrd3_0 { - status = "okay"; -}; - -&usbdrd3_1 { - status = "okay"; -}; - -&usbdrd_dwc3_0 { - dr_mode = "host"; - status = "okay"; -}; - -&usbdrd_dwc3_1 { - dr_mode = "host"; - status = "okay"; -}; - -&usb_host0_ehci { - status = "okay"; -}; - -&usb_host0_ohci { - status = "okay"; -}; - -&usb_host1_ehci { - status = "okay"; -}; - -&usb_host1_ohci { - status = "okay"; -}; - -&vopb { - status = "okay"; -}; - -&vopb_mmu { - status = "okay"; -}; - -&vopl { - status = "okay"; -}; - -&vopl_mmu { - status = "okay"; -}; diff --git a/target/linux/rockchip/image/Makefile b/target/linux/rockchip/image/Makefile index 8e4474a2b..52d77c965 100644 --- a/target/linux/rockchip/image/Makefile +++ b/target/linux/rockchip/image/Makefile @@ -89,10 +89,6 @@ define Device/Default DEVICE_DTS = rockchip/$$(SOC)-$(lastword $(subst _, ,$(1))) endef -ifdef CONFIG_LINUX_6_0 - DTS_CPPFLAGS += -DDTS_NO_LEGACY -endif - include $(SUBTARGET).mk $(eval $(call BuildImage)) diff --git a/target/linux/rockchip/patches-5.4/009-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch b/target/linux/rockchip/patches-5.4/009-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch index 720840b3b..c508d7131 100644 --- a/target/linux/rockchip/patches-5.4/009-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch +++ b/target/linux/rockchip/patches-5.4/009-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch @@ -31,12 +31,11 @@ Signed-off-by: Heiko Stuebner --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -25,6 +25,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-le +@@ -25,6 +25,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-le dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopc-t4.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-neo4.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4s.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-guangmiao-g4c.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-orangepi.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb diff --git a/target/linux/rockchip/patches-6.1/005-arm64-dts-rockchip-add-EEPROM-node-for-NanoPi-R4S.patch b/target/linux/rockchip/patches-6.1/005-arm64-dts-rockchip-add-EEPROM-node-for-NanoPi-R4S.patch new file mode 100644 index 000000000..792028b29 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/005-arm64-dts-rockchip-add-EEPROM-node-for-NanoPi-R4S.patch @@ -0,0 +1,31 @@ +From af20b3384e8723077cc6484160b0cf4e9be321de Mon Sep 17 00:00:00 2001 +From: Tianling Shen +Date: Mon, 7 Jun 2021 15:45:37 +0800 +Subject: [PATCH] arm64: dts: rockchip: add EEPROM node for NanoPi R4S + +NanoPi R4S has a EEPROM attached to the 2nd I2C bus (U92), which +stores the MAC address. + +Signed-off-by: Tianling Shen +--- + arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +@@ -68,6 +68,15 @@ + status = "disabled"; + }; + ++&i2c2 { ++ eeprom@51 { ++ compatible = "microchip,24c02", "atmel,24c02"; ++ reg = <0x51>; ++ pagesize = <16>; ++ read-only; /* This holds our MAC */ ++ }; ++}; ++ + &i2c4 { + status = "disabled"; + }; diff --git a/target/linux/rockchip/patches-6.1/011-v6.2-net-phy-Add-driver-for-Motorcomm-yt8521.patch b/target/linux/rockchip/patches-6.1/011-v6.2-net-phy-Add-driver-for-Motorcomm-yt8521.patch new file mode 100644 index 000000000..dc27374f7 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/011-v6.2-net-phy-Add-driver-for-Motorcomm-yt8521.patch @@ -0,0 +1,1724 @@ +From 70479a40954cf353e87a486997a3477108c75aa9 Mon Sep 17 00:00:00 2001 +From: Frank +Date: Fri, 28 Oct 2022 17:26:21 +0800 +Subject: [PATCH] net: phy: Add driver for Motorcomm yt8521 gigabit ethernet + phy + +Add a driver for the motorcomm yt8521 gigabit ethernet phy. We have verified + the driver on StarFive VisionFive development board, which is developed by + Shanghai StarFive Technology Co., Ltd.. On the board, yt8521 gigabit ethernet + phy works in utp mode, RGMII interface, supports 1000M/100M/10M speeds, and + wol(magic package). + +Signed-off-by: Frank +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + MAINTAINERS | 1 + + drivers/net/phy/Kconfig | 2 +- + drivers/net/phy/motorcomm.c | 1635 ++++++++++++++++++++++++++++++++++- + 3 files changed, 1635 insertions(+), 3 deletions(-) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -13949,6 +13949,7 @@ F: include/uapi/linux/meye.h + + MOTORCOMM PHY DRIVER + M: Peter Geis ++M: Frank + L: netdev@vger.kernel.org + S: Maintained + F: drivers/net/phy/motorcomm.c +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -334,7 +334,7 @@ config MOTORCOMM_PHY + tristate "Motorcomm PHYs" + help + Enables support for Motorcomm network PHYs. +- Currently supports the YT8511 gigabit PHY. ++ Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs. + + config NATIONAL_PHY + tristate "National Semiconductor PHYs" +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -1,15 +1,106 @@ + // SPDX-License-Identifier: GPL-2.0+ + /* +- * Driver for Motorcomm PHYs ++ * Motorcomm 8511/8521 PHY driver. + * + * Author: Peter Geis ++ * Author: Frank + */ + ++#include + #include + #include + #include + + #define PHY_ID_YT8511 0x0000010a ++#define PHY_ID_YT8521 0x0000011A ++ ++/* YT8521 Register Overview ++ * UTP Register space | FIBER Register space ++ * ------------------------------------------------------------ ++ * | UTP MII | FIBER MII | ++ * | UTP MMD | | ++ * | UTP Extended | FIBER Extended | ++ * ------------------------------------------------------------ ++ * | Common Extended | ++ * ------------------------------------------------------------ ++ */ ++ ++/* 0x10 ~ 0x15 , 0x1E and 0x1F are common MII registers of yt phy */ ++ ++/* Specific Function Control Register */ ++#define YTPHY_SPECIFIC_FUNCTION_CONTROL_REG 0x10 ++ ++/* 2b00 Manual MDI configuration ++ * 2b01 Manual MDIX configuration ++ * 2b10 Reserved ++ * 2b11 Enable automatic crossover for all modes *default* ++ */ ++#define YTPHY_SFCR_MDI_CROSSOVER_MODE_MASK (BIT(6) | BIT(5)) ++#define YTPHY_SFCR_CROSSOVER_EN BIT(3) ++#define YTPHY_SFCR_SQE_TEST_EN BIT(2) ++#define YTPHY_SFCR_POLARITY_REVERSAL_EN BIT(1) ++#define YTPHY_SFCR_JABBER_DIS BIT(0) ++ ++/* Specific Status Register */ ++#define YTPHY_SPECIFIC_STATUS_REG 0x11 ++#define YTPHY_SSR_SPEED_MODE_OFFSET 14 ++ ++#define YTPHY_SSR_SPEED_MODE_MASK (BIT(15) | BIT(14)) ++#define YTPHY_SSR_SPEED_10M 0x0 ++#define YTPHY_SSR_SPEED_100M 0x1 ++#define YTPHY_SSR_SPEED_1000M 0x2 ++#define YTPHY_SSR_DUPLEX_OFFSET 13 ++#define YTPHY_SSR_DUPLEX BIT(13) ++#define YTPHY_SSR_PAGE_RECEIVED BIT(12) ++#define YTPHY_SSR_SPEED_DUPLEX_RESOLVED BIT(11) ++#define YTPHY_SSR_LINK BIT(10) ++#define YTPHY_SSR_MDIX_CROSSOVER BIT(6) ++#define YTPHY_SSR_DOWNGRADE BIT(5) ++#define YTPHY_SSR_TRANSMIT_PAUSE BIT(3) ++#define YTPHY_SSR_RECEIVE_PAUSE BIT(2) ++#define YTPHY_SSR_POLARITY BIT(1) ++#define YTPHY_SSR_JABBER BIT(0) ++ ++/* Interrupt enable Register */ ++#define YTPHY_INTERRUPT_ENABLE_REG 0x12 ++#define YTPHY_IER_WOL BIT(6) ++ ++/* Interrupt Status Register */ ++#define YTPHY_INTERRUPT_STATUS_REG 0x13 ++#define YTPHY_ISR_AUTONEG_ERR BIT(15) ++#define YTPHY_ISR_SPEED_CHANGED BIT(14) ++#define YTPHY_ISR_DUPLEX_CHANGED BIT(13) ++#define YTPHY_ISR_PAGE_RECEIVED BIT(12) ++#define YTPHY_ISR_LINK_FAILED BIT(11) ++#define YTPHY_ISR_LINK_SUCCESSED BIT(10) ++#define YTPHY_ISR_WOL BIT(6) ++#define YTPHY_ISR_WIRESPEED_DOWNGRADE BIT(5) ++#define YTPHY_ISR_SERDES_LINK_FAILED BIT(3) ++#define YTPHY_ISR_SERDES_LINK_SUCCESSED BIT(2) ++#define YTPHY_ISR_POLARITY_CHANGED BIT(1) ++#define YTPHY_ISR_JABBER_HAPPENED BIT(0) ++ ++/* Speed Auto Downgrade Control Register */ ++#define YTPHY_SPEED_AUTO_DOWNGRADE_CONTROL_REG 0x14 ++#define YTPHY_SADCR_SPEED_DOWNGRADE_EN BIT(5) ++ ++/* If these bits are set to 3, the PHY attempts five times ( 3(set value) + ++ * additional 2) before downgrading, default 0x3 ++ */ ++#define YTPHY_SADCR_SPEED_RETRY_LIMIT (0x3 << 2) ++ ++/* Rx Error Counter Register */ ++#define YTPHY_RX_ERROR_COUNTER_REG 0x15 ++ ++/* Extended Register's Address Offset Register */ ++#define YTPHY_PAGE_SELECT 0x1E ++ ++/* Extended Register's Data Register */ ++#define YTPHY_PAGE_DATA 0x1F ++ ++/* FIBER Auto-Negotiation link partner ability */ ++#define YTPHY_FLPA_PAUSE (0x3 << 7) ++#define YTPHY_FLPA_ASYM_PAUSE (0x2 << 7) + + #define YT8511_PAGE_SELECT 0x1e + #define YT8511_PAGE 0x1f +@@ -38,6 +129,352 @@ + #define YT8511_DELAY_FE_TX_EN (0xf << 12) + #define YT8511_DELAY_FE_TX_DIS (0x2 << 12) + ++/* Extended register is different from MMD Register and MII Register. ++ * We can use ytphy_read_ext/ytphy_write_ext/ytphy_modify_ext function to ++ * operate extended register. ++ * Extended Register start ++ */ ++ ++/* Phy gmii clock gating Register */ ++#define YT8521_CLOCK_GATING_REG 0xC ++#define YT8521_CGR_RX_CLK_EN BIT(12) ++ ++#define YT8521_EXTREG_SLEEP_CONTROL1_REG 0x27 ++#define YT8521_ESC1R_SLEEP_SW BIT(15) ++#define YT8521_ESC1R_PLLON_SLP BIT(14) ++ ++/* Phy fiber Link timer cfg2 Register */ ++#define YT8521_LINK_TIMER_CFG2_REG 0xA5 ++#define YT8521_LTCR_EN_AUTOSEN BIT(15) ++ ++/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers ++ * of yt8521 phy. There is no need to switch reg space when operating these ++ * registers. ++ */ ++ ++#define YT8521_REG_SPACE_SELECT_REG 0xA000 ++#define YT8521_RSSR_SPACE_MASK BIT(1) ++#define YT8521_RSSR_FIBER_SPACE (0x1 << 1) ++#define YT8521_RSSR_UTP_SPACE (0x0 << 1) ++#define YT8521_RSSR_TO_BE_ARBITRATED (0xFF) ++ ++#define YT8521_CHIP_CONFIG_REG 0xA001 ++#define YT8521_CCR_SW_RST BIT(15) ++ ++#define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0)) ++#define YT8521_CCR_MODE_UTP_TO_RGMII 0 ++#define YT8521_CCR_MODE_FIBER_TO_RGMII 1 ++#define YT8521_CCR_MODE_UTP_FIBER_TO_RGMII 2 ++#define YT8521_CCR_MODE_UTP_TO_SGMII 3 ++#define YT8521_CCR_MODE_SGPHY_TO_RGMAC 4 ++#define YT8521_CCR_MODE_SGMAC_TO_RGPHY 5 ++#define YT8521_CCR_MODE_UTP_TO_FIBER_AUTO 6 ++#define YT8521_CCR_MODE_UTP_TO_FIBER_FORCE 7 ++ ++/* 3 phy polling modes,poll mode combines utp and fiber mode*/ ++#define YT8521_MODE_FIBER 0x1 ++#define YT8521_MODE_UTP 0x2 ++#define YT8521_MODE_POLL 0x3 ++ ++#define YT8521_RGMII_CONFIG1_REG 0xA003 ++ ++/* TX Gig-E Delay is bits 3:0, default 0x1 ++ * TX Fast-E Delay is bits 7:4, default 0xf ++ * RX Delay is bits 13:10, default 0x0 ++ * Delay = 150ps * N ++ * On = 2250ps, off = 0ps ++ */ ++#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10) ++#define YT8521_RC1R_RX_DELAY_EN (0xF << 10) ++#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10) ++#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4) ++#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4) ++#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4) ++#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0) ++#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0) ++#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0) ++ ++#define YTPHY_MISC_CONFIG_REG 0xA006 ++#define YTPHY_MCR_FIBER_SPEED_MASK BIT(0) ++#define YTPHY_MCR_FIBER_1000BX (0x1 << 0) ++#define YTPHY_MCR_FIBER_100FX (0x0 << 0) ++ ++/* WOL MAC ADDR: MACADDR2(highest), MACADDR1(middle), MACADDR0(lowest) */ ++#define YTPHY_WOL_MACADDR2_REG 0xA007 ++#define YTPHY_WOL_MACADDR1_REG 0xA008 ++#define YTPHY_WOL_MACADDR0_REG 0xA009 ++ ++#define YTPHY_WOL_CONFIG_REG 0xA00A ++#define YTPHY_WCR_INTR_SEL BIT(6) ++#define YTPHY_WCR_ENABLE BIT(3) ++ ++/* 2b00 84ms ++ * 2b01 168ms *default* ++ * 2b10 336ms ++ * 2b11 672ms ++ */ ++#define YTPHY_WCR_PULSE_WIDTH_MASK (BIT(2) | BIT(1)) ++#define YTPHY_WCR_PULSE_WIDTH_672MS (BIT(2) | BIT(1)) ++ ++/* 1b0 Interrupt and WOL events is level triggered and active LOW *default* ++ * 1b1 Interrupt and WOL events is pulse triggered and active LOW ++ */ ++#define YTPHY_WCR_TYPE_PULSE BIT(0) ++ ++/* Extended Register end */ ++ ++struct yt8521_priv { ++ /* combo_advertising is used for case of YT8521 in combo mode, ++ * this means that yt8521 may work in utp or fiber mode which depends ++ * on which media is connected (YT8521_RSSR_TO_BE_ARBITRATED). ++ */ ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(combo_advertising); ++ ++ /* YT8521_MODE_FIBER / YT8521_MODE_UTP / YT8521_MODE_POLL*/ ++ u8 polling_mode; ++ u8 strap_mode; /* 8 working modes */ ++ /* current reg page of yt8521 phy: ++ * YT8521_RSSR_UTP_SPACE ++ * YT8521_RSSR_FIBER_SPACE ++ * YT8521_RSSR_TO_BE_ARBITRATED ++ */ ++ u8 reg_page; ++}; ++ ++/** ++ * ytphy_read_ext() - read a PHY's extended register ++ * @phydev: a pointer to a &struct phy_device ++ * @regnum: register number to read ++ * ++ * NOTE:The caller must have taken the MDIO bus lock. ++ * ++ * returns the value of regnum reg or negative error code ++ */ ++static int ytphy_read_ext(struct phy_device *phydev, u16 regnum) ++{ ++ int ret; ++ ++ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); ++ if (ret < 0) ++ return ret; ++ ++ return __phy_read(phydev, YTPHY_PAGE_DATA); ++} ++ ++/** ++ * ytphy_read_ext_with_lock() - read a PHY's extended register ++ * @phydev: a pointer to a &struct phy_device ++ * @regnum: register number to read ++ * ++ * returns the value of regnum reg or negative error code ++ */ ++static int ytphy_read_ext_with_lock(struct phy_device *phydev, u16 regnum) ++{ ++ int ret; ++ ++ phy_lock_mdio_bus(phydev); ++ ret = ytphy_read_ext(phydev, regnum); ++ phy_unlock_mdio_bus(phydev); ++ ++ return ret; ++} ++ ++/** ++ * ytphy_write_ext() - write a PHY's extended register ++ * @phydev: a pointer to a &struct phy_device ++ * @regnum: register number to write ++ * @val: value to write to @regnum ++ * ++ * NOTE:The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative error code ++ */ ++static int ytphy_write_ext(struct phy_device *phydev, u16 regnum, u16 val) ++{ ++ int ret; ++ ++ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); ++ if (ret < 0) ++ return ret; ++ ++ return __phy_write(phydev, YTPHY_PAGE_DATA, val); ++} ++ ++/** ++ * ytphy_write_ext_with_lock() - write a PHY's extended register ++ * @phydev: a pointer to a &struct phy_device ++ * @regnum: register number to write ++ * @val: value to write to @regnum ++ * ++ * returns 0 or negative error code ++ */ ++static int ytphy_write_ext_with_lock(struct phy_device *phydev, u16 regnum, ++ u16 val) ++{ ++ int ret; ++ ++ phy_lock_mdio_bus(phydev); ++ ret = ytphy_write_ext(phydev, regnum, val); ++ phy_unlock_mdio_bus(phydev); ++ ++ return ret; ++} ++ ++/** ++ * ytphy_modify_ext() - bits modify a PHY's extended register ++ * @phydev: a pointer to a &struct phy_device ++ * @regnum: register number to write ++ * @mask: bit mask of bits to clear ++ * @set: bit mask of bits to set ++ * ++ * NOTE: Convenience function which allows a PHY's extended register to be ++ * modified as new register value = (old register value & ~mask) | set. ++ * The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative error code ++ */ ++static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask, ++ u16 set) ++{ ++ int ret; ++ ++ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); ++ if (ret < 0) ++ return ret; ++ ++ return __phy_modify(phydev, YTPHY_PAGE_DATA, mask, set); ++} ++ ++/** ++ * ytphy_modify_ext_with_lock() - bits modify a PHY's extended register ++ * @phydev: a pointer to a &struct phy_device ++ * @regnum: register number to write ++ * @mask: bit mask of bits to clear ++ * @set: bit mask of bits to set ++ * ++ * NOTE: Convenience function which allows a PHY's extended register to be ++ * modified as new register value = (old register value & ~mask) | set. ++ * ++ * returns 0 or negative error code ++ */ ++static int ytphy_modify_ext_with_lock(struct phy_device *phydev, u16 regnum, ++ u16 mask, u16 set) ++{ ++ int ret; ++ ++ phy_lock_mdio_bus(phydev); ++ ret = ytphy_modify_ext(phydev, regnum, mask, set); ++ phy_unlock_mdio_bus(phydev); ++ ++ return ret; ++} ++ ++/** ++ * ytphy_get_wol() - report whether wake-on-lan is enabled ++ * @phydev: a pointer to a &struct phy_device ++ * @wol: a pointer to a &struct ethtool_wolinfo ++ * ++ * NOTE: YTPHY_WOL_CONFIG_REG is common ext reg. ++ */ ++static void ytphy_get_wol(struct phy_device *phydev, ++ struct ethtool_wolinfo *wol) ++{ ++ int wol_config; ++ ++ wol->supported = WAKE_MAGIC; ++ wol->wolopts = 0; ++ ++ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); ++ if (wol_config < 0) ++ return; ++ ++ if (wol_config & YTPHY_WCR_ENABLE) ++ wol->wolopts |= WAKE_MAGIC; ++} ++ ++/** ++ * ytphy_set_wol() - turn wake-on-lan on or off ++ * @phydev: a pointer to a &struct phy_device ++ * @wol: a pointer to a &struct ethtool_wolinfo ++ * ++ * NOTE: YTPHY_WOL_CONFIG_REG, YTPHY_WOL_MACADDR2_REG, YTPHY_WOL_MACADDR1_REG ++ * and YTPHY_WOL_MACADDR0_REG are common ext reg. The ++ * YTPHY_INTERRUPT_ENABLE_REG of UTP is special, fiber also use this register. ++ * ++ * returns 0 or negative errno code ++ */ ++static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) ++{ ++ struct net_device *p_attached_dev; ++ const u16 mac_addr_reg[] = { ++ YTPHY_WOL_MACADDR2_REG, ++ YTPHY_WOL_MACADDR1_REG, ++ YTPHY_WOL_MACADDR0_REG, ++ }; ++ const u8 *mac_addr; ++ int old_page; ++ int ret = 0; ++ u16 mask; ++ u16 val; ++ u8 i; ++ ++ if (wol->wolopts & WAKE_MAGIC) { ++ p_attached_dev = phydev->attached_dev; ++ if (!p_attached_dev) ++ return -ENODEV; ++ ++ mac_addr = (const u8 *)p_attached_dev->dev_addr; ++ if (!is_valid_ether_addr(mac_addr)) ++ return -EINVAL; ++ ++ /* lock mdio bus then switch to utp reg space */ ++ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); ++ if (old_page < 0) ++ goto err_restore_page; ++ ++ /* Store the device address for the magic packet */ ++ for (i = 0; i < 3; i++) { ++ ret = ytphy_write_ext(phydev, mac_addr_reg[i], ++ ((mac_addr[i * 2] << 8)) | ++ (mac_addr[i * 2 + 1])); ++ if (ret < 0) ++ goto err_restore_page; ++ } ++ ++ /* Enable WOL feature */ ++ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL; ++ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; ++ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS; ++ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, val); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* Enable WOL interrupt */ ++ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0, ++ YTPHY_IER_WOL); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ } else { ++ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); ++ if (old_page < 0) ++ goto err_restore_page; ++ ++ /* Disable WOL feature */ ++ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; ++ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, 0); ++ ++ /* Disable WOL interrupt */ ++ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, ++ YTPHY_IER_WOL, 0); ++ if (ret < 0) ++ goto err_restore_page; ++ } ++ ++err_restore_page: ++ return phy_restore_page(phydev, old_page, ret); ++} ++ + static int yt8511_read_page(struct phy_device *phydev) + { + return __phy_read(phydev, YT8511_PAGE_SELECT); +@@ -111,6 +548,1181 @@ err_restore_page: + return phy_restore_page(phydev, oldpage, ret); + } + ++/** ++ * yt8521_read_page() - read reg page ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns current reg space of yt8521 (YT8521_RSSR_FIBER_SPACE/ ++ * YT8521_RSSR_UTP_SPACE) or negative errno code ++ */ ++static int yt8521_read_page(struct phy_device *phydev) ++{ ++ int old_page; ++ ++ old_page = ytphy_read_ext(phydev, YT8521_REG_SPACE_SELECT_REG); ++ if (old_page < 0) ++ return old_page; ++ ++ if ((old_page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE) ++ return YT8521_RSSR_FIBER_SPACE; ++ ++ return YT8521_RSSR_UTP_SPACE; ++}; ++ ++/** ++ * yt8521_write_page() - write reg page ++ * @phydev: a pointer to a &struct phy_device ++ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to write. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_write_page(struct phy_device *phydev, int page) ++{ ++ int mask = YT8521_RSSR_SPACE_MASK; ++ int set; ++ ++ if ((page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE) ++ set = YT8521_RSSR_FIBER_SPACE; ++ else ++ set = YT8521_RSSR_UTP_SPACE; ++ ++ return ytphy_modify_ext(phydev, YT8521_REG_SPACE_SELECT_REG, mask, set); ++}; ++ ++/** ++ * yt8521_probe() - read chip config then set suitable polling_mode ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_probe(struct phy_device *phydev) ++{ ++ struct device *dev = &phydev->mdio.dev; ++ struct yt8521_priv *priv; ++ int chip_config; ++ int ret; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ phydev->priv = priv; ++ ++ chip_config = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG); ++ if (chip_config < 0) ++ return chip_config; ++ ++ priv->strap_mode = chip_config & YT8521_CCR_MODE_SEL_MASK; ++ switch (priv->strap_mode) { ++ case YT8521_CCR_MODE_FIBER_TO_RGMII: ++ case YT8521_CCR_MODE_SGPHY_TO_RGMAC: ++ case YT8521_CCR_MODE_SGMAC_TO_RGPHY: ++ priv->polling_mode = YT8521_MODE_FIBER; ++ priv->reg_page = YT8521_RSSR_FIBER_SPACE; ++ phydev->port = PORT_FIBRE; ++ break; ++ case YT8521_CCR_MODE_UTP_FIBER_TO_RGMII: ++ case YT8521_CCR_MODE_UTP_TO_FIBER_AUTO: ++ case YT8521_CCR_MODE_UTP_TO_FIBER_FORCE: ++ priv->polling_mode = YT8521_MODE_POLL; ++ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED; ++ phydev->port = PORT_NONE; ++ break; ++ case YT8521_CCR_MODE_UTP_TO_SGMII: ++ case YT8521_CCR_MODE_UTP_TO_RGMII: ++ priv->polling_mode = YT8521_MODE_UTP; ++ priv->reg_page = YT8521_RSSR_UTP_SPACE; ++ phydev->port = PORT_TP; ++ break; ++ } ++ /* set default reg space */ ++ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { ++ ret = ytphy_write_ext_with_lock(phydev, ++ YT8521_REG_SPACE_SELECT_REG, ++ priv->reg_page); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * NOTE:The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative errno code ++ */ ++static int ytphy_utp_read_lpa(struct phy_device *phydev) ++{ ++ int lpa, lpagb; ++ ++ if (phydev->autoneg == AUTONEG_ENABLE) { ++ if (!phydev->autoneg_complete) { ++ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ++ 0); ++ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0); ++ return 0; ++ } ++ ++ if (phydev->is_gigabit_capable) { ++ lpagb = __phy_read(phydev, MII_STAT1000); ++ if (lpagb < 0) ++ return lpagb; ++ ++ if (lpagb & LPA_1000MSFAIL) { ++ int adv = __phy_read(phydev, MII_CTRL1000); ++ ++ if (adv < 0) ++ return adv; ++ ++ if (adv & CTL1000_ENABLE_MASTER) ++ phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); ++ else ++ phydev_err(phydev, "Master/Slave resolution failed\n"); ++ return -ENOLINK; ++ } ++ ++ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ++ lpagb); ++ } ++ ++ lpa = __phy_read(phydev, MII_LPA); ++ if (lpa < 0) ++ return lpa; ++ ++ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); ++ } else { ++ linkmode_zero(phydev->lp_advertising); ++ } ++ ++ return 0; ++} ++ ++/** ++ * yt8521_adjust_status() - update speed and duplex to phydev. when in fiber ++ * mode, adjust speed and duplex. ++ * @phydev: a pointer to a &struct phy_device ++ * @status: yt8521 status read from YTPHY_SPECIFIC_STATUS_REG ++ * @is_utp: false(yt8521 work in fiber mode) or true(yt8521 work in utp mode) ++ * ++ * NOTE:The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 ++ */ ++static int yt8521_adjust_status(struct phy_device *phydev, int status, ++ bool is_utp) ++{ ++ int speed_mode, duplex; ++ int speed; ++ int err; ++ int lpa; ++ ++ if (is_utp) ++ duplex = (status & YTPHY_SSR_DUPLEX) >> YTPHY_SSR_DUPLEX_OFFSET; ++ else ++ duplex = DUPLEX_FULL; /* for fiber, it always DUPLEX_FULL */ ++ ++ speed_mode = (status & YTPHY_SSR_SPEED_MODE_MASK) >> ++ YTPHY_SSR_SPEED_MODE_OFFSET; ++ ++ switch (speed_mode) { ++ case YTPHY_SSR_SPEED_10M: ++ if (is_utp) ++ speed = SPEED_10; ++ else ++ /* for fiber, it will never run here, default to ++ * SPEED_UNKNOWN ++ */ ++ speed = SPEED_UNKNOWN; ++ break; ++ case YTPHY_SSR_SPEED_100M: ++ speed = SPEED_100; ++ break; ++ case YTPHY_SSR_SPEED_1000M: ++ speed = SPEED_1000; ++ break; ++ default: ++ speed = SPEED_UNKNOWN; ++ break; ++ } ++ ++ phydev->speed = speed; ++ phydev->duplex = duplex; ++ ++ if (is_utp) { ++ err = ytphy_utp_read_lpa(phydev); ++ if (err < 0) ++ return err; ++ ++ phy_resolve_aneg_pause(phydev); ++ } else { ++ lpa = __phy_read(phydev, MII_LPA); ++ if (lpa < 0) ++ return lpa; ++ ++ /* only support 1000baseX Full */ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, ++ phydev->lp_advertising, lpa & LPA_1000XFULL); ++ ++ if (!(lpa & YTPHY_FLPA_PAUSE)) { ++ phydev->pause = 0; ++ phydev->asym_pause = 0; ++ } else if ((lpa & YTPHY_FLPA_ASYM_PAUSE)) { ++ phydev->pause = 1; ++ phydev->asym_pause = 1; ++ } else { ++ phydev->pause = 1; ++ phydev->asym_pause = 0; ++ } ++ } ++ ++ return 0; ++} ++ ++/** ++ * yt8521_read_status_paged() - determines the speed and duplex of one page ++ * @phydev: a pointer to a &struct phy_device ++ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to ++ * operate. ++ * ++ * returns 1 (utp or fiber link),0 (no link) or negative errno code ++ */ ++static int yt8521_read_status_paged(struct phy_device *phydev, int page) ++{ ++ int fiber_latch_val; ++ int fiber_curr_val; ++ int old_page; ++ int ret = 0; ++ int status; ++ int link; ++ ++ linkmode_zero(phydev->lp_advertising); ++ phydev->duplex = DUPLEX_UNKNOWN; ++ phydev->speed = SPEED_UNKNOWN; ++ phydev->asym_pause = 0; ++ phydev->pause = 0; ++ ++ /* YT8521 has two reg space (utp/fiber) for linkup with utp/fiber ++ * respectively. but for utp/fiber combo mode, reg space should be ++ * arbitrated based on media priority. by default, utp takes ++ * priority. reg space should be properly set before read ++ * YTPHY_SPECIFIC_STATUS_REG. ++ */ ++ ++ page &= YT8521_RSSR_SPACE_MASK; ++ old_page = phy_select_page(phydev, page); ++ if (old_page < 0) ++ goto err_restore_page; ++ ++ /* Read YTPHY_SPECIFIC_STATUS_REG, which indicates the speed and duplex ++ * of the PHY is actually using. ++ */ ++ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ status = ret; ++ link = !!(status & YTPHY_SSR_LINK); ++ ++ /* When PHY is in fiber mode, speed transferred from 1000Mbps to ++ * 100Mbps,there is not link down from YTPHY_SPECIFIC_STATUS_REG, so ++ * we need check MII_BMSR to identify such case. ++ */ ++ if (page == YT8521_RSSR_FIBER_SPACE) { ++ ret = __phy_read(phydev, MII_BMSR); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ fiber_latch_val = ret; ++ ret = __phy_read(phydev, MII_BMSR); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ fiber_curr_val = ret; ++ if (link && fiber_latch_val != fiber_curr_val) { ++ link = 0; ++ phydev_info(phydev, ++ "%s, fiber link down detect, latch = %04x, curr = %04x\n", ++ __func__, fiber_latch_val, fiber_curr_val); ++ } ++ } else { ++ /* Read autonegotiation status */ ++ ret = __phy_read(phydev, MII_BMSR); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ phydev->autoneg_complete = ret & BMSR_ANEGCOMPLETE ? 1 : 0; ++ } ++ ++ if (link) { ++ if (page == YT8521_RSSR_UTP_SPACE) ++ yt8521_adjust_status(phydev, status, true); ++ else ++ yt8521_adjust_status(phydev, status, false); ++ } ++ return phy_restore_page(phydev, old_page, link); ++ ++err_restore_page: ++ return phy_restore_page(phydev, old_page, ret); ++} ++ ++/** ++ * yt8521_read_status() - determines the negotiated speed and duplex ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_read_status(struct phy_device *phydev) ++{ ++ struct yt8521_priv *priv = phydev->priv; ++ int link_fiber = 0; ++ int link_utp; ++ int link; ++ int ret; ++ ++ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { ++ link = yt8521_read_status_paged(phydev, priv->reg_page); ++ if (link < 0) ++ return link; ++ } else { ++ /* when page is YT8521_RSSR_TO_BE_ARBITRATED, arbitration is ++ * needed. by default, utp is higher priority. ++ */ ++ ++ link_utp = yt8521_read_status_paged(phydev, ++ YT8521_RSSR_UTP_SPACE); ++ if (link_utp < 0) ++ return link_utp; ++ ++ if (!link_utp) { ++ link_fiber = yt8521_read_status_paged(phydev, ++ YT8521_RSSR_FIBER_SPACE); ++ if (link_fiber < 0) ++ return link_fiber; ++ } ++ ++ link = link_utp || link_fiber; ++ } ++ ++ if (link) { ++ if (phydev->link == 0) { ++ /* arbitrate reg space based on linkup media type. */ ++ if (priv->polling_mode == YT8521_MODE_POLL && ++ priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) { ++ if (link_fiber) ++ priv->reg_page = ++ YT8521_RSSR_FIBER_SPACE; ++ else ++ priv->reg_page = YT8521_RSSR_UTP_SPACE; ++ ++ ret = ytphy_write_ext_with_lock(phydev, ++ YT8521_REG_SPACE_SELECT_REG, ++ priv->reg_page); ++ if (ret < 0) ++ return ret; ++ ++ phydev->port = link_fiber ? PORT_FIBRE : PORT_TP; ++ ++ phydev_info(phydev, "%s, link up, media: %s\n", ++ __func__, ++ (phydev->port == PORT_TP) ? ++ "UTP" : "Fiber"); ++ } ++ } ++ phydev->link = 1; ++ } else { ++ if (phydev->link == 1) { ++ phydev_info(phydev, "%s, link down, media: %s\n", ++ __func__, (phydev->port == PORT_TP) ? ++ "UTP" : "Fiber"); ++ ++ /* When in YT8521_MODE_POLL mode, need prepare for next ++ * arbitration. ++ */ ++ if (priv->polling_mode == YT8521_MODE_POLL) { ++ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED; ++ phydev->port = PORT_NONE; ++ } ++ } ++ ++ phydev->link = 0; ++ } ++ ++ return 0; ++} ++ ++/** ++ * yt8521_modify_bmcr_paged - bits modify a PHY's BMCR register of one page ++ * @phydev: the phy_device struct ++ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to operate ++ * @mask: bit mask of bits to clear ++ * @set: bit mask of bits to set ++ * ++ * NOTE: Convenience function which allows a PHY's BMCR register to be ++ * modified as new register value = (old register value & ~mask) | set. ++ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space ++ * has MII_BMCR. poll mode combines utp and faber,so need do both. ++ * If it is reset, it will wait for completion. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_modify_bmcr_paged(struct phy_device *phydev, int page, ++ u16 mask, u16 set) ++{ ++ int max_cnt = 500; /* the max wait time of reset ~ 500 ms */ ++ int old_page; ++ int ret = 0; ++ ++ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK); ++ if (old_page < 0) ++ goto err_restore_page; ++ ++ ret = __phy_modify(phydev, MII_BMCR, mask, set); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* If it is reset, need to wait for the reset to complete */ ++ if (set == BMCR_RESET) { ++ while (max_cnt--) { ++ usleep_range(1000, 1100); ++ ret = __phy_read(phydev, MII_BMCR); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ if (!(ret & BMCR_RESET)) ++ return phy_restore_page(phydev, old_page, 0); ++ } ++ } ++ ++err_restore_page: ++ return phy_restore_page(phydev, old_page, ret); ++} ++ ++/** ++ * yt8521_modify_utp_fiber_bmcr - bits modify a PHY's BMCR register ++ * @phydev: the phy_device struct ++ * @mask: bit mask of bits to clear ++ * @set: bit mask of bits to set ++ * ++ * NOTE: Convenience function which allows a PHY's BMCR register to be ++ * modified as new register value = (old register value & ~mask) | set. ++ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space ++ * has MII_BMCR. poll mode combines utp and faber,so need do both. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_modify_utp_fiber_bmcr(struct phy_device *phydev, u16 mask, ++ u16 set) ++{ ++ struct yt8521_priv *priv = phydev->priv; ++ int ret; ++ ++ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { ++ ret = yt8521_modify_bmcr_paged(phydev, priv->reg_page, mask, ++ set); ++ if (ret < 0) ++ return ret; ++ } else { ++ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_UTP_SPACE, ++ mask, set); ++ if (ret < 0) ++ return ret; ++ ++ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_FIBER_SPACE, ++ mask, set); ++ if (ret < 0) ++ return ret; ++ } ++ return 0; ++} ++ ++/** ++ * yt8521_soft_reset() - called to issue a PHY software reset ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_soft_reset(struct phy_device *phydev) ++{ ++ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_RESET); ++} ++ ++/** ++ * yt8521_suspend() - suspend the hardware ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_suspend(struct phy_device *phydev) ++{ ++ int wol_config; ++ ++ /* YTPHY_WOL_CONFIG_REG is common ext reg */ ++ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); ++ if (wol_config < 0) ++ return wol_config; ++ ++ /* if wol enable, do nothing */ ++ if (wol_config & YTPHY_WCR_ENABLE) ++ return 0; ++ ++ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_PDOWN); ++} ++ ++/** ++ * yt8521_resume() - resume the hardware ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_resume(struct phy_device *phydev) ++{ ++ int ret; ++ int wol_config; ++ ++ /* disable auto sleep */ ++ ret = ytphy_modify_ext_with_lock(phydev, ++ YT8521_EXTREG_SLEEP_CONTROL1_REG, ++ YT8521_ESC1R_SLEEP_SW, 0); ++ if (ret < 0) ++ return ret; ++ ++ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); ++ if (wol_config < 0) ++ return wol_config; ++ ++ /* if wol enable, do nothing */ ++ if (wol_config & YTPHY_WCR_ENABLE) ++ return 0; ++ ++ return yt8521_modify_utp_fiber_bmcr(phydev, BMCR_PDOWN, 0); ++} ++ ++/** ++ * yt8521_config_init() - called to initialize the PHY ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_config_init(struct phy_device *phydev) ++{ ++ int old_page; ++ int ret = 0; ++ u16 val; ++ ++ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); ++ if (old_page < 0) ++ goto err_restore_page; ++ ++ switch (phydev->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; ++ val |= YT8521_RC1R_RX_DELAY_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; ++ val |= YT8521_RC1R_RX_DELAY_EN; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; ++ val |= YT8521_RC1R_RX_DELAY_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; ++ val |= YT8521_RC1R_RX_DELAY_EN; ++ break; ++ case PHY_INTERFACE_MODE_SGMII: ++ break; ++ default: /* do not support other modes */ ++ ret = -EOPNOTSUPP; ++ goto err_restore_page; ++ } ++ ++ /* set rgmii delay mode */ ++ if (phydev->interface != PHY_INTERFACE_MODE_SGMII) { ++ ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, ++ (YT8521_RC1R_RX_DELAY_MASK | ++ YT8521_RC1R_FE_TX_DELAY_MASK | ++ YT8521_RC1R_GE_TX_DELAY_MASK), ++ val); ++ if (ret < 0) ++ goto err_restore_page; ++ } ++ ++ /* disable auto sleep */ ++ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG, ++ YT8521_ESC1R_SLEEP_SW, 0); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ /* enable RXC clock when no wire plug */ ++ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG, ++ YT8521_CGR_RX_CLK_EN, 0); ++ if (ret < 0) ++ goto err_restore_page; ++ ++err_restore_page: ++ return phy_restore_page(phydev, old_page, ret); ++} ++ ++/** ++ * yt8521_prepare_fiber_features() - A small helper function that setup ++ * fiber's features. ++ * @phydev: a pointer to a &struct phy_device ++ * @dst: a pointer to store fiber's features ++ */ ++static void yt8521_prepare_fiber_features(struct phy_device *phydev, ++ unsigned long *dst) ++{ ++ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, dst); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, dst); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, dst); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, dst); ++} ++ ++/** ++ * yt8521_fiber_setup_forced - configures/forces speed from @phydev ++ * @phydev: target phy_device struct ++ * ++ * NOTE:The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_fiber_setup_forced(struct phy_device *phydev) ++{ ++ u16 val; ++ int ret; ++ ++ if (phydev->speed == SPEED_1000) ++ val = YTPHY_MCR_FIBER_1000BX; ++ else if (phydev->speed == SPEED_100) ++ val = YTPHY_MCR_FIBER_100FX; ++ else ++ return -EINVAL; ++ ++ ret = __phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* disable Fiber auto sensing */ ++ ret = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG, ++ YT8521_LTCR_EN_AUTOSEN, 0); ++ if (ret < 0) ++ return ret; ++ ++ ret = ytphy_modify_ext(phydev, YTPHY_MISC_CONFIG_REG, ++ YTPHY_MCR_FIBER_SPEED_MASK, val); ++ if (ret < 0) ++ return ret; ++ ++ return ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG, ++ YT8521_CCR_SW_RST, 0); ++} ++ ++/** ++ * ytphy_check_and_restart_aneg - Enable and restart auto-negotiation ++ * @phydev: target phy_device struct ++ * @restart: whether aneg restart is requested ++ * ++ * NOTE:The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative errno code ++ */ ++static int ytphy_check_and_restart_aneg(struct phy_device *phydev, bool restart) ++{ ++ int ret; ++ ++ if (!restart) { ++ /* Advertisement hasn't changed, but maybe aneg was never on to ++ * begin with? Or maybe phy was isolated? ++ */ ++ ret = __phy_read(phydev, MII_BMCR); ++ if (ret < 0) ++ return ret; ++ ++ if (!(ret & BMCR_ANENABLE) || (ret & BMCR_ISOLATE)) ++ restart = true; ++ } ++ /* Enable and Restart Autonegotiation ++ * Don't isolate the PHY if we're negotiating ++ */ ++ if (restart) ++ return __phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, ++ BMCR_ANENABLE | BMCR_ANRESTART); ++ ++ return 0; ++} ++ ++/** ++ * yt8521_fiber_config_aneg - restart auto-negotiation or write ++ * YTPHY_MISC_CONFIG_REG. ++ * @phydev: target phy_device struct ++ * ++ * NOTE:The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_fiber_config_aneg(struct phy_device *phydev) ++{ ++ int err, changed = 0; ++ int bmcr; ++ u16 adv; ++ ++ if (phydev->autoneg != AUTONEG_ENABLE) ++ return yt8521_fiber_setup_forced(phydev); ++ ++ /* enable Fiber auto sensing */ ++ err = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG, ++ 0, YT8521_LTCR_EN_AUTOSEN); ++ if (err < 0) ++ return err; ++ ++ err = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG, ++ YT8521_CCR_SW_RST, 0); ++ if (err < 0) ++ return err; ++ ++ bmcr = __phy_read(phydev, MII_BMCR); ++ if (bmcr < 0) ++ return bmcr; ++ ++ /* When it is coming from fiber forced mode, add bmcr power down ++ * and power up to let aneg work fine. ++ */ ++ if (!(bmcr & BMCR_ANENABLE)) { ++ __phy_modify(phydev, MII_BMCR, 0, BMCR_PDOWN); ++ usleep_range(1000, 1100); ++ __phy_modify(phydev, MII_BMCR, BMCR_PDOWN, 0); ++ } ++ ++ adv = linkmode_adv_to_mii_adv_x(phydev->advertising, ++ ETHTOOL_LINK_MODE_1000baseX_Full_BIT); ++ ++ /* Setup fiber advertisement */ ++ err = __phy_modify_changed(phydev, MII_ADVERTISE, ++ ADVERTISE_1000XHALF | ADVERTISE_1000XFULL | ++ ADVERTISE_1000XPAUSE | ++ ADVERTISE_1000XPSE_ASYM, ++ adv); ++ if (err < 0) ++ return err; ++ ++ if (err > 0) ++ changed = 1; ++ ++ return ytphy_check_and_restart_aneg(phydev, changed); ++} ++ ++/** ++ * ytphy_setup_master_slave ++ * @phydev: target phy_device struct ++ * ++ * NOTE: The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative errno code ++ */ ++static int ytphy_setup_master_slave(struct phy_device *phydev) ++{ ++ u16 ctl = 0; ++ ++ if (!phydev->is_gigabit_capable) ++ return 0; ++ ++ switch (phydev->master_slave_set) { ++ case MASTER_SLAVE_CFG_MASTER_PREFERRED: ++ ctl |= CTL1000_PREFER_MASTER; ++ break; ++ case MASTER_SLAVE_CFG_SLAVE_PREFERRED: ++ break; ++ case MASTER_SLAVE_CFG_MASTER_FORCE: ++ ctl |= CTL1000_AS_MASTER; ++ fallthrough; ++ case MASTER_SLAVE_CFG_SLAVE_FORCE: ++ ctl |= CTL1000_ENABLE_MASTER; ++ break; ++ case MASTER_SLAVE_CFG_UNKNOWN: ++ case MASTER_SLAVE_CFG_UNSUPPORTED: ++ return 0; ++ default: ++ phydev_warn(phydev, "Unsupported Master/Slave mode\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ return __phy_modify_changed(phydev, MII_CTRL1000, ++ (CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER | ++ CTL1000_PREFER_MASTER), ctl); ++} ++ ++/** ++ * ytphy_utp_config_advert - sanitize and advertise auto-negotiation parameters ++ * @phydev: target phy_device struct ++ * ++ * NOTE: Writes MII_ADVERTISE with the appropriate values, ++ * after sanitizing the values to make sure we only advertise ++ * what is supported. Returns < 0 on error, 0 if the PHY's advertisement ++ * hasn't changed, and > 0 if it has changed. ++ * The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative errno code ++ */ ++static int ytphy_utp_config_advert(struct phy_device *phydev) ++{ ++ int err, bmsr, changed = 0; ++ u32 adv; ++ ++ /* Only allow advertising what this PHY supports */ ++ linkmode_and(phydev->advertising, phydev->advertising, ++ phydev->supported); ++ ++ adv = linkmode_adv_to_mii_adv_t(phydev->advertising); ++ ++ /* Setup standard advertisement */ ++ err = __phy_modify_changed(phydev, MII_ADVERTISE, ++ ADVERTISE_ALL | ADVERTISE_100BASE4 | ++ ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM, ++ adv); ++ if (err < 0) ++ return err; ++ if (err > 0) ++ changed = 1; ++ ++ bmsr = __phy_read(phydev, MII_BMSR); ++ if (bmsr < 0) ++ return bmsr; ++ ++ /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all ++ * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a ++ * logical 1. ++ */ ++ if (!(bmsr & BMSR_ESTATEN)) ++ return changed; ++ ++ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); ++ ++ err = __phy_modify_changed(phydev, MII_CTRL1000, ++ ADVERTISE_1000FULL | ADVERTISE_1000HALF, ++ adv); ++ if (err < 0) ++ return err; ++ if (err > 0) ++ changed = 1; ++ ++ return changed; ++} ++ ++/** ++ * ytphy_utp_config_aneg - restart auto-negotiation or write BMCR ++ * @phydev: target phy_device struct ++ * @changed: whether autoneg is requested ++ * ++ * NOTE: If auto-negotiation is enabled, we configure the ++ * advertising, and then restart auto-negotiation. If it is not ++ * enabled, then we write the BMCR. ++ * The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative errno code ++ */ ++static int ytphy_utp_config_aneg(struct phy_device *phydev, bool changed) ++{ ++ int err; ++ u16 ctl; ++ ++ err = ytphy_setup_master_slave(phydev); ++ if (err < 0) ++ return err; ++ else if (err) ++ changed = true; ++ ++ if (phydev->autoneg != AUTONEG_ENABLE) { ++ /* configures/forces speed/duplex from @phydev */ ++ ++ ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex); ++ ++ return __phy_modify(phydev, MII_BMCR, ~(BMCR_LOOPBACK | ++ BMCR_ISOLATE | BMCR_PDOWN), ctl); ++ } ++ ++ err = ytphy_utp_config_advert(phydev); ++ if (err < 0) /* error */ ++ return err; ++ else if (err) ++ changed = true; ++ ++ return ytphy_check_and_restart_aneg(phydev, changed); ++} ++ ++/** ++ * yt8521_config_aneg_paged() - switch reg space then call genphy_config_aneg ++ * of one page ++ * @phydev: a pointer to a &struct phy_device ++ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to ++ * operate. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_config_aneg_paged(struct phy_device *phydev, int page) ++{ ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(fiber_supported); ++ struct yt8521_priv *priv = phydev->priv; ++ int old_page; ++ int ret = 0; ++ ++ page &= YT8521_RSSR_SPACE_MASK; ++ ++ old_page = phy_select_page(phydev, page); ++ if (old_page < 0) ++ goto err_restore_page; ++ ++ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED, ++ * phydev->advertising should be updated. ++ */ ++ if (priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) { ++ linkmode_zero(fiber_supported); ++ yt8521_prepare_fiber_features(phydev, fiber_supported); ++ ++ /* prepare fiber_supported, then setup advertising. */ ++ if (page == YT8521_RSSR_FIBER_SPACE) { ++ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, ++ fiber_supported); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, ++ fiber_supported); ++ linkmode_and(phydev->advertising, ++ priv->combo_advertising, fiber_supported); ++ } else { ++ /* ETHTOOL_LINK_MODE_Autoneg_BIT is also used in utp */ ++ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, ++ fiber_supported); ++ linkmode_andnot(phydev->advertising, ++ priv->combo_advertising, ++ fiber_supported); ++ } ++ } ++ ++ if (page == YT8521_RSSR_FIBER_SPACE) ++ ret = yt8521_fiber_config_aneg(phydev); ++ else ++ ret = ytphy_utp_config_aneg(phydev, false); ++ ++err_restore_page: ++ return phy_restore_page(phydev, old_page, ret); ++} ++ ++/** ++ * yt8521_config_aneg() - change reg space then call yt8521_config_aneg_paged ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_config_aneg(struct phy_device *phydev) ++{ ++ struct yt8521_priv *priv = phydev->priv; ++ int ret; ++ ++ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { ++ ret = yt8521_config_aneg_paged(phydev, priv->reg_page); ++ if (ret < 0) ++ return ret; ++ } else { ++ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED, ++ * phydev->advertising need to be saved at first run. ++ * Because it contains the advertising which supported by both ++ * mac and yt8521(utp and fiber). ++ */ ++ if (linkmode_empty(priv->combo_advertising)) { ++ linkmode_copy(priv->combo_advertising, ++ phydev->advertising); ++ } ++ ++ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_UTP_SPACE); ++ if (ret < 0) ++ return ret; ++ ++ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_FIBER_SPACE); ++ if (ret < 0) ++ return ret; ++ ++ /* we don't known which will be link, so restore ++ * phydev->advertising as default value. ++ */ ++ linkmode_copy(phydev->advertising, priv->combo_advertising); ++ } ++ return 0; ++} ++ ++/** ++ * yt8521_aneg_done_paged() - determines the auto negotiation result of one ++ * page. ++ * @phydev: a pointer to a &struct phy_device ++ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to ++ * operate. ++ * ++ * returns 0(no link)or 1(fiber or utp link) or negative errno code ++ */ ++static int yt8521_aneg_done_paged(struct phy_device *phydev, int page) ++{ ++ int old_page; ++ int ret = 0; ++ int link; ++ ++ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK); ++ if (old_page < 0) ++ goto err_restore_page; ++ ++ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG); ++ if (ret < 0) ++ goto err_restore_page; ++ ++ link = !!(ret & YTPHY_SSR_LINK); ++ ret = link; ++ ++err_restore_page: ++ return phy_restore_page(phydev, old_page, ret); ++} ++ ++/** ++ * yt8521_aneg_done() - determines the auto negotiation result ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0(no link)or 1(fiber or utp link) or negative errno code ++ */ ++static int yt8521_aneg_done(struct phy_device *phydev) ++{ ++ struct yt8521_priv *priv = phydev->priv; ++ int link_fiber = 0; ++ int link_utp; ++ int link; ++ ++ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { ++ link = yt8521_aneg_done_paged(phydev, priv->reg_page); ++ } else { ++ link_utp = yt8521_aneg_done_paged(phydev, ++ YT8521_RSSR_UTP_SPACE); ++ if (link_utp < 0) ++ return link_utp; ++ ++ if (!link_utp) { ++ link_fiber = yt8521_aneg_done_paged(phydev, ++ YT8521_RSSR_FIBER_SPACE); ++ if (link_fiber < 0) ++ return link_fiber; ++ } ++ link = link_fiber || link_utp; ++ phydev_info(phydev, "%s, link_fiber: %d, link_utp: %d\n", ++ __func__, link_fiber, link_utp); ++ } ++ ++ return link; ++} ++ ++/** ++ * ytphy_utp_read_abilities - read PHY abilities from Clause 22 registers ++ * @phydev: target phy_device struct ++ * ++ * NOTE: Reads the PHY's abilities and populates ++ * phydev->supported accordingly. ++ * The caller must have taken the MDIO bus lock. ++ * ++ * returns 0 or negative errno code ++ */ ++static int ytphy_utp_read_abilities(struct phy_device *phydev) ++{ ++ int val; ++ ++ linkmode_set_bit_array(phy_basic_ports_array, ++ ARRAY_SIZE(phy_basic_ports_array), ++ phydev->supported); ++ ++ val = __phy_read(phydev, MII_BMSR); ++ if (val < 0) ++ return val; ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported, ++ val & BMSR_ANEGCAPABLE); ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported, ++ val & BMSR_100FULL); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, phydev->supported, ++ val & BMSR_100HALF); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported, ++ val & BMSR_10FULL); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, phydev->supported, ++ val & BMSR_10HALF); ++ ++ if (val & BMSR_ESTATEN) { ++ val = __phy_read(phydev, MII_ESTATUS); ++ if (val < 0) ++ return val; ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, ++ phydev->supported, val & ESTATUS_1000_TFULL); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, ++ phydev->supported, val & ESTATUS_1000_THALF); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, ++ phydev->supported, val & ESTATUS_1000_XFULL); ++ } ++ ++ return 0; ++} ++ ++/** ++ * yt8521_get_features_paged() - read supported link modes for one page ++ * @phydev: a pointer to a &struct phy_device ++ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to ++ * operate. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_get_features_paged(struct phy_device *phydev, int page) ++{ ++ int old_page; ++ int ret = 0; ++ ++ page &= YT8521_RSSR_SPACE_MASK; ++ old_page = phy_select_page(phydev, page); ++ if (old_page < 0) ++ goto err_restore_page; ++ ++ if (page == YT8521_RSSR_FIBER_SPACE) { ++ linkmode_zero(phydev->supported); ++ yt8521_prepare_fiber_features(phydev, phydev->supported); ++ } else { ++ ret = ytphy_utp_read_abilities(phydev); ++ if (ret < 0) ++ goto err_restore_page; ++ } ++ ++err_restore_page: ++ return phy_restore_page(phydev, old_page, ret); ++} ++ ++/** ++ * yt8521_get_features - switch reg space then call yt8521_get_features_paged ++ * @phydev: target phy_device struct ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8521_get_features(struct phy_device *phydev) ++{ ++ struct yt8521_priv *priv = phydev->priv; ++ int ret; ++ ++ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { ++ ret = yt8521_get_features_paged(phydev, priv->reg_page); ++ } else { ++ ret = yt8521_get_features_paged(phydev, ++ YT8521_RSSR_UTP_SPACE); ++ if (ret < 0) ++ return ret; ++ ++ /* add fiber's features to phydev->supported */ ++ yt8521_prepare_fiber_features(phydev, phydev->supported); ++ } ++ return ret; ++} ++ + static struct phy_driver motorcomm_phy_drvs[] = { + { + PHY_ID_MATCH_EXACT(PHY_ID_YT8511), +@@ -121,16 +1733,35 @@ static struct phy_driver motorcomm_phy_d + .read_page = yt8511_read_page, + .write_page = yt8511_write_page, + }, ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8521), ++ .name = "YT8521 Gigabit Ethernet", ++ .get_features = yt8521_get_features, ++ .probe = yt8521_probe, ++ .read_page = yt8521_read_page, ++ .write_page = yt8521_write_page, ++ .get_wol = ytphy_get_wol, ++ .set_wol = ytphy_set_wol, ++ .config_aneg = yt8521_config_aneg, ++ .aneg_done = yt8521_aneg_done, ++ .config_init = yt8521_config_init, ++ .read_status = yt8521_read_status, ++ .soft_reset = yt8521_soft_reset, ++ .suspend = yt8521_suspend, ++ .resume = yt8521_resume, ++ }, + }; + + module_phy_driver(motorcomm_phy_drvs); + +-MODULE_DESCRIPTION("Motorcomm PHY driver"); ++MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver"); + MODULE_AUTHOR("Peter Geis"); ++MODULE_AUTHOR("Frank"); + MODULE_LICENSE("GPL"); + + static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { + { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, ++ { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, + { /* sentinal */ } + }; + diff --git a/target/linux/rockchip/patches-6.1/012-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch b/target/linux/rockchip/patches-6.1/012-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch new file mode 100644 index 000000000..95c65bd57 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/012-v6.2-net-phy-add-Motorcomm-YT8531S-phy-id.patch @@ -0,0 +1,138 @@ +From 813abcd98fb1b2cccf850cdfa092a4bfc50b2363 Mon Sep 17 00:00:00 2001 +From: Frank +Date: Tue, 22 Nov 2022 16:42:32 +0800 +Subject: [PATCH] net: phy: add Motorcomm YT8531S phy id. + +We added patch for motorcomm.c to support YT8531S. This patch has +been tested on AM335x platform which has one YT8531S interface +card and passed all test cases. +The tested cases indluding: YT8531S UTP function with support of +10M/100M/1000M; YT8531S Fiber function with support of 100M/1000M; +and YT8531S Combo function that supports auto detection of media type. + +Since most functions of YT8531S are similar to YT8521 and we reuse some +codes for YT8521 in the patch file. + +Signed-off-by: Frank +Signed-off-by: David S. Miller +--- + drivers/net/phy/Kconfig | 2 +- + drivers/net/phy/motorcomm.c | 52 +++++++++++++++++++++++++++++++++---- + 2 files changed, 48 insertions(+), 6 deletions(-) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -334,7 +334,7 @@ config MOTORCOMM_PHY + tristate "Motorcomm PHYs" + help + Enables support for Motorcomm network PHYs. +- Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs. ++ Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. + + config NATIONAL_PHY + tristate "National Semiconductor PHYs" +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0+ + /* +- * Motorcomm 8511/8521 PHY driver. ++ * Motorcomm 8511/8521/8531S PHY driver. + * + * Author: Peter Geis + * Author: Frank +@@ -13,8 +13,9 @@ + + #define PHY_ID_YT8511 0x0000010a + #define PHY_ID_YT8521 0x0000011A ++#define PHY_ID_YT8531S 0x4F51E91A + +-/* YT8521 Register Overview ++/* YT8521/YT8531S Register Overview + * UTP Register space | FIBER Register space + * ------------------------------------------------------------ + * | UTP MII | FIBER MII | +@@ -147,7 +148,7 @@ + #define YT8521_LINK_TIMER_CFG2_REG 0xA5 + #define YT8521_LTCR_EN_AUTOSEN BIT(15) + +-/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers ++/* 0xA000, 0xA001, 0xA003, 0xA006 ~ 0xA00A and 0xA012 are common ext registers + * of yt8521 phy. There is no need to switch reg space when operating these + * registers. + */ +@@ -221,6 +222,9 @@ + */ + #define YTPHY_WCR_TYPE_PULSE BIT(0) + ++#define YT8531S_SYNCE_CFG_REG 0xA012 ++#define YT8531S_SCR_SYNCE_ENABLE BIT(6) ++ + /* Extended Register end */ + + struct yt8521_priv { +@@ -648,6 +652,26 @@ static int yt8521_probe(struct phy_devic + } + + /** ++ * yt8531s_probe() - read chip config then set suitable polling_mode ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531s_probe(struct phy_device *phydev) ++{ ++ int ret; ++ ++ /* Disable SyncE clock output by default */ ++ ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG, ++ YT8531S_SCR_SYNCE_ENABLE, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* same as yt8521_probe */ ++ return yt8521_probe(phydev); ++} ++ ++/** + * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp + * @phydev: a pointer to a &struct phy_device + * +@@ -1750,11 +1774,28 @@ static struct phy_driver motorcomm_phy_d + .suspend = yt8521_suspend, + .resume = yt8521_resume, + }, ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), ++ .name = "YT8531S Gigabit Ethernet", ++ .get_features = yt8521_get_features, ++ .probe = yt8531s_probe, ++ .read_page = yt8521_read_page, ++ .write_page = yt8521_write_page, ++ .get_wol = ytphy_get_wol, ++ .set_wol = ytphy_set_wol, ++ .config_aneg = yt8521_config_aneg, ++ .aneg_done = yt8521_aneg_done, ++ .config_init = yt8521_config_init, ++ .read_status = yt8521_read_status, ++ .soft_reset = yt8521_soft_reset, ++ .suspend = yt8521_suspend, ++ .resume = yt8521_resume, ++ }, + }; + + module_phy_driver(motorcomm_phy_drvs); + +-MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver"); ++MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); + MODULE_AUTHOR("Peter Geis"); + MODULE_AUTHOR("Frank"); + MODULE_LICENSE("GPL"); +@@ -1762,6 +1803,7 @@ MODULE_LICENSE("GPL"); + static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { + { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, + { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, ++ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, + { /* sentinal */ } + }; + diff --git a/target/linux/rockchip/patches-6.1/100-rockchip-use-system-LED-for-OpenWrt.patch b/target/linux/rockchip/patches-6.1/100-rockchip-use-system-LED-for-OpenWrt.patch new file mode 100644 index 000000000..051124519 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/100-rockchip-use-system-LED-for-OpenWrt.patch @@ -0,0 +1,47 @@ +From 6731d2c9039fbe1ecf21915eab3acee0a999508a Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Fri, 10 Jul 2020 21:38:20 +0200 +Subject: [PATCH] rockchip: use system LED for OpenWrt + +Use the SYS LED on the casing for showing system status. + +This patch is kept separate from the NanoPi R2S support patch, as i plan +on submitting the device support upstream. + +Signed-off-by: David Bauer +--- + arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +@@ -18,6 +18,13 @@ + mmc0 = &sdmmc; + }; + ++ aliases { ++ led-boot = &sys_led; ++ led-failsafe = &sys_led; ++ led-running = &sys_led; ++ led-upgrade = &sys_led; ++ }; ++ + chosen { + stdout-path = "serial2:1500000n8"; + }; +--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +@@ -19,6 +19,13 @@ + model = "FriendlyElec NanoPi R4S"; + compatible = "friendlyarm,nanopi-r4s", "rockchip,rk3399"; + ++ aliases { ++ led-boot = &sys_led; ++ led-failsafe = &sys_led; ++ led-running = &sys_led; ++ led-upgrade = &sys_led; ++ }; ++ + /delete-node/ display-subsystem; + + gpio-leds { diff --git a/target/linux/rockchip/patches-6.1/101-arm64-rockchip-add-OF-node-for-USB-eth-on-NanoPi-R2S.patch b/target/linux/rockchip/patches-6.1/101-arm64-rockchip-add-OF-node-for-USB-eth-on-NanoPi-R2S.patch new file mode 100644 index 000000000..5fe60d1ad --- /dev/null +++ b/target/linux/rockchip/patches-6.1/101-arm64-rockchip-add-OF-node-for-USB-eth-on-NanoPi-R2S.patch @@ -0,0 +1,24 @@ +From 2795c8b31a686bdb8338f9404d18ef7a154f0d75 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Sun, 26 Jul 2020 13:32:59 +0200 +Subject: [PATCH] arm64: rockchip: add OF node for USB eth on NanoPi R2S + +This adds the OF node for the USB3 ethernet adapter on the FriendlyARM +NanoPi R2S. Add the correct value for the RTL8153 LED configuration +register to match the blink behavior of the other port on the device. + +Signed-off-by: David Bauer +--- + arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 7 +++++++ + 1 file changed, 1 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +@@ -404,6 +404,7 @@ + rtl8153: device@2 { + compatible = "usbbda,8153"; + reg = <2>; ++ realtek,led-data = <0x87>; + }; + }; + diff --git a/target/linux/rockchip/patches-6.1/103-nanopi-r4s-sd-signalling.patch b/target/linux/rockchip/patches-6.1/103-nanopi-r4s-sd-signalling.patch new file mode 100644 index 000000000..1a72b02d4 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/103-nanopi-r4s-sd-signalling.patch @@ -0,0 +1,26 @@ +From: David Bauer +Subject: arm64: dts: rockchip: disable UHS modes for NanoPi R4S + +The NanoPi R4S leaves the SD card in 1.8V signalling when rebooting +while U-Boot requires the card to be in 3.3V mode. + +Remove UHS support from the SD controller so the card remains in 3.3V +mode. This reduces transfer speeds but ensures a reboot whether from +userspace or following a kernel panic is always working. + +Signed-off-by: David Bauer + +--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +@@ -128,6 +128,11 @@ + status = "disabled"; + }; + ++&sdmmc { ++ /delete-property/ sd-uhs-sdr104; ++ cap-sd-highspeed; ++}; ++ + &u2phy0_host { + phy-supply = <&vdd_5v>; + }; diff --git a/target/linux/rockchip/patches-6.1/104-rockchip-rock-pi-4.patch b/target/linux/rockchip/patches-6.1/104-rockchip-rock-pi-4.patch new file mode 100644 index 000000000..086259942 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/104-rockchip-rock-pi-4.patch @@ -0,0 +1,34 @@ +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -30,6 +30,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gr + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-scarlet-dumo.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-scarlet-inx.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-scarlet-kd.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4se.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-hugsun-x99.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-captain.dtb +@@ -50,6 +52,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-ro + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-plus.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-4c-plus.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4a.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4a-plus.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4b.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +@@ -0,0 +1,13 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2019 Akash Gajjar ++ * Copyright (c) 2019 Pragnesh Patel ++ */ ++ ++/dts-v1/; ++#include "rk3399-rock-pi-4.dtsi" ++ ++/ { ++ model = "Radxa ROCK Pi 4"; ++ compatible = "radxa,rockpi4", "rockchip,rk3399"; ++}; diff --git a/target/linux/rockchip/patches-6.1/105-mmc-core-set-initial-signal-voltage-on-power-off.patch b/target/linux/rockchip/patches-6.1/105-mmc-core-set-initial-signal-voltage-on-power-off.patch new file mode 100644 index 000000000..9b1f0bb0a --- /dev/null +++ b/target/linux/rockchip/patches-6.1/105-mmc-core-set-initial-signal-voltage-on-power-off.patch @@ -0,0 +1,35 @@ +From 0d329112c709d6cfedf0fffb19f0cc6b19043f6b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 20 Feb 2019 07:38:34 +0000 +Subject: [PATCH] mmc: core: set initial signal voltage on power off + +Some boards have SD card connectors where the power rail cannot be switched +off by the driver. If the card has not been power cycled, it may still be +using 1.8V signaling after a warm re-boot. Bootroms expecting 3.3V signaling +will fail to boot from a UHS card that continue to use 1.8V signaling. + +Set initial signal voltage in mmc_power_off() to allow re-boot to function. + +This fixes re-boot with UHS cards on Asus Tinker Board (Rockchip RK3288), +same issue have been seen on some Rockchip RK3399 boards. + +I am sending this as a RFC because I have no insights into SD/MMC subsystem, +this change fix a re-boot issue on my boards and does not break emmc/sdio. +Is this an acceptable workaround? Any advice is appreciated. + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/core/core.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/mmc/core/core.c ++++ b/drivers/mmc/core/core.c +@@ -1366,6 +1366,8 @@ void mmc_power_off(struct mmc_host *host + + mmc_pwrseq_power_off(host); + ++ mmc_set_initial_signal_voltage(host); ++ + host->ios.clock = 0; + host->ios.vdd = 0; + diff --git a/target/linux/rockchip/patches-6.1/106-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch b/target/linux/rockchip/patches-6.1/106-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch new file mode 100644 index 000000000..0071047f1 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/106-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit.patch @@ -0,0 +1,254 @@ +From cfb1aa4c805e58287dd0ce292b5c64309e3dba2f Mon Sep 17 00:00:00 2001 +From: Frank +Date: Wed, 30 Nov 2022 17:49:28 +0800 +Subject: [PATCH] net: phy: Add driver for Motorcomm yt8531 gigabit ethernet phy + +Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have +verified the patch on AM335x platform which has one YT8531 interface +card and passed all test cases. The tested cases indluding: YT8531 UTP +function with support of 10M/100M/1000M and wol(based on magic packet). + +Signed-off-by: Frank +--- + drivers/net/phy/Kconfig | 2 +- + drivers/net/phy/motorcomm.c | 162 ++++++++++++++++++++++++++++++++++-- + 2 files changed, 158 insertions(+), 6 deletions(-) + +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -334,7 +334,7 @@ config MOTORCOMM_PHY + tristate "Motorcomm PHYs" + help + Enables support for Motorcomm network PHYs. +- Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. ++ Currently supports the YT8511, YT8521, YT8531, YT8531S Gigabit Ethernet PHYs. + + config NATIONAL_PHY + tristate "National Semiconductor PHYs" +--- a/drivers/net/phy/motorcomm.c ++++ b/drivers/net/phy/motorcomm.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0+ + /* +- * Motorcomm 8511/8521/8531S PHY driver. ++ * Motorcomm 8511/8521/8531/8531S PHY driver. + * + * Author: Peter Geis + * Author: Frank +@@ -12,8 +12,9 @@ + #include + + #define PHY_ID_YT8511 0x0000010a +-#define PHY_ID_YT8521 0x0000011A +-#define PHY_ID_YT8531S 0x4F51E91A ++#define PHY_ID_YT8521 0x0000011a ++#define PHY_ID_YT8531 0x4f51e91b ++#define PHY_ID_YT8531S 0x4f51e91a + + /* YT8521/YT8531S Register Overview + * UTP Register space | FIBER Register space +@@ -225,6 +226,9 @@ + #define YT8531S_SYNCE_CFG_REG 0xA012 + #define YT8531S_SCR_SYNCE_ENABLE BIT(6) + ++#define YT8531_SYNCE_CFG_REG 0xA012 ++#define YT8531_SCR_SYNCE_ENABLE BIT(6) ++ + /* Extended Register end */ + + struct yt8521_priv { +@@ -479,6 +483,77 @@ err_restore_page: + return phy_restore_page(phydev, old_page, ret); + } + ++/** ++ * yt8531_set_wol() - turn wake-on-lan on or off ++ * @phydev: a pointer to a &struct phy_device ++ * @wol: a pointer to a &struct ethtool_wolinfo ++ * ++ * NOTE: YTPHY_WOL_CONFIG_REG, YTPHY_WOL_MACADDR2_REG, YTPHY_WOL_MACADDR1_REG ++ * and YTPHY_WOL_MACADDR0_REG are common ext reg. ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_set_wol(struct phy_device *phydev, ++ struct ethtool_wolinfo *wol) ++{ ++ struct net_device *p_attached_dev; ++ const u16 mac_addr_reg[] = { ++ YTPHY_WOL_MACADDR2_REG, ++ YTPHY_WOL_MACADDR1_REG, ++ YTPHY_WOL_MACADDR0_REG, ++ }; ++ const u8 *mac_addr; ++ u16 mask; ++ u16 val; ++ int ret; ++ u8 i; ++ ++ if (wol->wolopts & WAKE_MAGIC) { ++ p_attached_dev = phydev->attached_dev; ++ if (!p_attached_dev) ++ return -ENODEV; ++ ++ mac_addr = (const u8 *)p_attached_dev->dev_addr; ++ if (!is_valid_ether_addr(mac_addr)) ++ return -EINVAL; ++ ++ /* Store the device address for the magic packet */ ++ for (i = 0; i < 3; i++) { ++ ret = ytphy_write_ext(phydev, mac_addr_reg[i], ++ ((mac_addr[i * 2] << 8)) | ++ (mac_addr[i * 2 + 1])); ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* Enable WOL feature */ ++ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL; ++ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; ++ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS; ++ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, val); ++ if (ret < 0) ++ return ret; ++ ++ /* Enable WOL interrupt */ ++ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0, ++ YTPHY_IER_WOL); ++ if (ret < 0) ++ return ret; ++ } else { ++ /* Disable WOL feature */ ++ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; ++ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, 0); ++ ++ /* Disable WOL interrupt */ ++ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, ++ YTPHY_IER_WOL, 0); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int yt8511_read_page(struct phy_device *phydev) + { + return __phy_read(phydev, YT8511_PAGE_SELECT); +@@ -652,6 +727,19 @@ static int yt8521_probe(struct phy_devic + } + + /** ++ * yt8531_probe() - Now only disable SyncE clock output ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_probe(struct phy_device *phydev) ++{ ++ /* Disable SyncE clock output by default */ ++ return ytphy_modify_ext_with_lock(phydev, YT8531_SYNCE_CFG_REG, ++ YT8531_SCR_SYNCE_ENABLE, 0); ++} ++ ++/** + * yt8531s_probe() - read chip config then set suitable polling_mode + * @phydev: a pointer to a &struct phy_device + * +@@ -1193,6 +1281,59 @@ err_restore_page: + } + + /** ++ * yt8531_config_init() - called to initialize the PHY ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * returns 0 or negative errno code ++ */ ++static int yt8531_config_init(struct phy_device *phydev) ++{ ++ int ret; ++ u16 val; ++ ++ switch (phydev->interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; ++ val |= YT8521_RC1R_RX_DELAY_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; ++ val |= YT8521_RC1R_RX_DELAY_EN; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; ++ val |= YT8521_RC1R_RX_DELAY_DIS; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; ++ val |= YT8521_RC1R_RX_DELAY_EN; ++ break; ++ default: /* do not support other modes */ ++ return -EOPNOTSUPP; ++ } ++ ++ /* set rgmii delay mode */ ++ ret = ytphy_modify_ext_with_lock(phydev, YT8521_RGMII_CONFIG1_REG, ++ (YT8521_RC1R_RX_DELAY_MASK | ++ YT8521_RC1R_FE_TX_DELAY_MASK | ++ YT8521_RC1R_GE_TX_DELAY_MASK), ++ val); ++ if (ret < 0) ++ return ret; ++ ++ /* disable auto sleep */ ++ ret = ytphy_modify_ext_with_lock(phydev, ++ YT8521_EXTREG_SLEEP_CONTROL1_REG, ++ YT8521_ESC1R_SLEEP_SW, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* enable RXC clock when no wire plug */ ++ return ytphy_modify_ext_with_lock(phydev, YT8521_CLOCK_GATING_REG, ++ YT8521_CGR_RX_CLK_EN, 0); ++} ++ ++/** + * yt8521_prepare_fiber_features() - A small helper function that setup + * fiber's features. + * @phydev: a pointer to a &struct phy_device +@@ -1775,6 +1916,16 @@ static struct phy_driver motorcomm_phy_d + .resume = yt8521_resume, + }, + { ++ PHY_ID_MATCH_EXACT(PHY_ID_YT8531), ++ .name = "YT8531 Gigabit Ethernet", ++ .probe = yt8531_probe, ++ .config_init = yt8531_config_init, ++ .suspend = genphy_suspend, ++ .resume = genphy_resume, ++ .get_wol = ytphy_get_wol, ++ .set_wol = yt8531_set_wol, ++ }, ++ { + PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), + .name = "YT8531S Gigabit Ethernet", + .get_features = yt8521_get_features, +@@ -1795,7 +1946,7 @@ static struct phy_driver motorcomm_phy_d + + module_phy_driver(motorcomm_phy_drvs); + +-MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); ++MODULE_DESCRIPTION("Motorcomm 8511/8521/8531/8531S PHY driver"); + MODULE_AUTHOR("Peter Geis"); + MODULE_AUTHOR("Frank"); + MODULE_LICENSE("GPL"); +@@ -1803,8 +1954,9 @@ MODULE_LICENSE("GPL"); + static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { + { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, + { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, ++ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531) }, + { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, +- { /* sentinal */ } ++ { /* sentinel */ } + }; + + MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); diff --git a/target/linux/rockchip/patches-6.1/167-crypto-rockchip-use-dev_err-for-error-message-about-.patch b/target/linux/rockchip/patches-6.1/167-crypto-rockchip-use-dev_err-for-error-message-about-.patch new file mode 100644 index 000000000..587c7c8ed --- /dev/null +++ b/target/linux/rockchip/patches-6.1/167-crypto-rockchip-use-dev_err-for-error-message-about-.patch @@ -0,0 +1,26 @@ +From 5b85875f5b63720c85f525a0b94054041ca2a118 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:39 +0000 +Subject: [PATCH 17/49] crypto: rockchip: use dev_err for error message about + interrupt + +Interrupt is mandatory so the message should be printed as error. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -371,8 +371,7 @@ static int rk_crypto_probe(struct platfo + + crypto_info->irq = platform_get_irq(pdev, 0); + if (crypto_info->irq < 0) { +- dev_warn(crypto_info->dev, +- "control Interrupt is not available.\n"); ++ dev_err(&pdev->dev, "control Interrupt is not available.\n"); + err = crypto_info->irq; + goto err_crypto; + } diff --git a/target/linux/rockchip/patches-6.1/168-crypto-rockchip-do-not-use-uninitialized-variable.patch b/target/linux/rockchip/patches-6.1/168-crypto-rockchip-do-not-use-uninitialized-variable.patch new file mode 100644 index 000000000..b9011ce16 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/168-crypto-rockchip-do-not-use-uninitialized-variable.patch @@ -0,0 +1,24 @@ +From ccd6a7fd0b6afdfa47d3b4f6b850127031effc1f Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:40 +0000 +Subject: [PATCH 18/49] crypto: rockchip: do not use uninitialized variable + +crypto_info->dev is not yet set, so use pdev->dev instead. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -381,7 +381,7 @@ static int rk_crypto_probe(struct platfo + "rk-crypto", pdev); + + if (err) { +- dev_err(crypto_info->dev, "irq request failed.\n"); ++ dev_err(&pdev->dev, "irq request failed.\n"); + goto err_crypto; + } + diff --git a/target/linux/rockchip/patches-6.1/169-crypto-rockchip-do-not-do-custom-power-management.patch b/target/linux/rockchip/patches-6.1/169-crypto-rockchip-do-not-do-custom-power-management.patch new file mode 100644 index 000000000..f5edc895f --- /dev/null +++ b/target/linux/rockchip/patches-6.1/169-crypto-rockchip-do-not-do-custom-power-management.patch @@ -0,0 +1,94 @@ +From 4f973a49ea5f5c6a80468a1c8d28f57642f20f08 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:41 +0000 +Subject: [PATCH 19/49] crypto: rockchip: do not do custom power management + +The clock enable/disable at tfm init/exit is fragile, +if 2 tfm are init in the same time and one is removed just after, +it will leave the hardware uncloked even if a user remains. + +Instead simply enable clocks at probe time. +We will do PM later. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 4 ++-- + drivers/crypto/rockchip/rk3288_crypto.h | 2 -- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 3 +-- + drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 5 +++-- + 4 files changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -394,8 +394,7 @@ static int rk_crypto_probe(struct platfo + rk_crypto_done_task_cb, (unsigned long)crypto_info); + crypto_init_queue(&crypto_info->queue, 50); + +- crypto_info->enable_clk = rk_crypto_enable_clk; +- crypto_info->disable_clk = rk_crypto_disable_clk; ++ rk_crypto_enable_clk(crypto_info); + crypto_info->load_data = rk_load_data; + crypto_info->unload_data = rk_unload_data; + crypto_info->enqueue = rk_crypto_enqueue; +@@ -422,6 +421,7 @@ static int rk_crypto_remove(struct platf + struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev); + + rk_crypto_unregister(); ++ rk_crypto_disable_clk(crypto_tmp); + tasklet_kill(&crypto_tmp->done_task); + tasklet_kill(&crypto_tmp->queue_task); + return 0; +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -220,8 +220,6 @@ struct rk_crypto_info { + int (*start)(struct rk_crypto_info *dev); + int (*update)(struct rk_crypto_info *dev); + void (*complete)(struct crypto_async_request *base, int err); +- int (*enable_clk)(struct rk_crypto_info *dev); +- void (*disable_clk)(struct rk_crypto_info *dev); + int (*load_data)(struct rk_crypto_info *dev, + struct scatterlist *sg_src, + struct scatterlist *sg_dst); +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -301,7 +301,7 @@ static int rk_cra_hash_init(struct crypt + sizeof(struct rk_ahash_rctx) + + crypto_ahash_reqsize(tctx->fallback_tfm)); + +- return tctx->dev->enable_clk(tctx->dev); ++ return 0; + } + + static void rk_cra_hash_exit(struct crypto_tfm *tfm) +@@ -309,7 +309,6 @@ static void rk_cra_hash_exit(struct cryp + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + + free_page((unsigned long)tctx->dev->addr_vir); +- return tctx->dev->disable_clk(tctx->dev); + } + + struct rk_crypto_tmp rk_ahash_sha1 = { +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -388,8 +388,10 @@ static int rk_ablk_init_tfm(struct crypt + ctx->dev->update = rk_ablk_rx; + ctx->dev->complete = rk_crypto_complete; + ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL); ++ if (!ctx->dev->addr_vir) ++ return -ENOMEM; + +- return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM; ++ return 0; + } + + static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) +@@ -397,7 +399,6 @@ static void rk_ablk_exit_tfm(struct cryp + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + + free_page((unsigned long)ctx->dev->addr_vir); +- ctx->dev->disable_clk(ctx->dev); + } + + struct rk_crypto_tmp rk_ecb_aes_alg = { diff --git a/target/linux/rockchip/patches-6.1/170-crypto-rockchip-fix-privete-private-typo.patch b/target/linux/rockchip/patches-6.1/170-crypto-rockchip-fix-privete-private-typo.patch new file mode 100644 index 000000000..4a6f519f4 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/170-crypto-rockchip-fix-privete-private-typo.patch @@ -0,0 +1,24 @@ +From 7ea605d0e8b85ffac2bf152be86d010d9eac0193 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:42 +0000 +Subject: [PATCH 20/49] crypto: rockchip: fix privete/private typo + +This fix a simple typo on private word. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -235,7 +235,7 @@ struct rk_ahash_ctx { + struct crypto_ahash *fallback_tfm; + }; + +-/* the privete variable of hash for fallback */ ++/* the private variable of hash for fallback */ + struct rk_ahash_rctx { + struct ahash_request fallback_req; + u32 mode; diff --git a/target/linux/rockchip/patches-6.1/171-crypto-rockchip-do-not-store-mode-globally.patch b/target/linux/rockchip/patches-6.1/171-crypto-rockchip-do-not-store-mode-globally.patch new file mode 100644 index 000000000..c53552bf3 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/171-crypto-rockchip-do-not-store-mode-globally.patch @@ -0,0 +1,262 @@ +From 61b5f1fbc686ff89fe30ce4efe10ba4b23d692f0 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:43 +0000 +Subject: [PATCH 21/49] crypto: rockchip: do not store mode globally + +Storing the mode globally does not work if 2 requests are handled in the +same time. +We should store it in a request context. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.h | 5 +- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 58 ++++++++++++------- + 2 files changed, 41 insertions(+), 22 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -245,10 +245,13 @@ struct rk_ahash_rctx { + struct rk_cipher_ctx { + struct rk_crypto_info *dev; + unsigned int keylen; +- u32 mode; + u8 iv[AES_BLOCK_SIZE]; + }; + ++struct rk_cipher_rctx { ++ u32 mode; ++}; ++ + enum alg_type { + ALG_TYPE_HASH, + ALG_TYPE_CIPHER, +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -76,9 +76,10 @@ static int rk_aes_ecb_encrypt(struct skc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_ECB_MODE; ++ rctx->mode = RK_CRYPTO_AES_ECB_MODE; + return rk_handle_req(dev, req); + } + +@@ -86,9 +87,10 @@ static int rk_aes_ecb_decrypt(struct skc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -96,9 +98,10 @@ static int rk_aes_cbc_encrypt(struct skc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_CBC_MODE; ++ rctx->mode = RK_CRYPTO_AES_CBC_MODE; + return rk_handle_req(dev, req); + } + +@@ -106,9 +109,10 @@ static int rk_aes_cbc_decrypt(struct skc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -116,9 +120,10 @@ static int rk_des_ecb_encrypt(struct skc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = 0; ++ rctx->mode = 0; + return rk_handle_req(dev, req); + } + +@@ -126,9 +131,10 @@ static int rk_des_ecb_decrypt(struct skc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -136,9 +142,10 @@ static int rk_des_cbc_encrypt(struct skc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC; ++ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC; + return rk_handle_req(dev, req); + } + +@@ -146,9 +153,10 @@ static int rk_des_cbc_decrypt(struct skc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -156,9 +164,10 @@ static int rk_des3_ede_ecb_encrypt(struc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT; ++ rctx->mode = RK_CRYPTO_TDES_SELECT; + return rk_handle_req(dev, req); + } + +@@ -166,9 +175,10 @@ static int rk_des3_ede_ecb_decrypt(struc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -176,9 +186,10 @@ static int rk_des3_ede_cbc_encrypt(struc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC; ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC; + return rk_handle_req(dev, req); + } + +@@ -186,9 +197,10 @@ static int rk_des3_ede_cbc_decrypt(struc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC | ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC | + RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } +@@ -199,6 +211,7 @@ static void rk_ablk_hw_init(struct rk_cr + skcipher_request_cast(dev->async_req); + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); + u32 ivsize, block, conf_reg = 0; + +@@ -206,22 +219,22 @@ static void rk_ablk_hw_init(struct rk_cr + ivsize = crypto_skcipher_ivsize(cipher); + + if (block == DES_BLOCK_SIZE) { +- ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | ++ rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | + RK_CRYPTO_TDES_BYTESWAP_KEY | + RK_CRYPTO_TDES_BYTESWAP_IV; +- CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode); ++ CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); + memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); + conf_reg = RK_CRYPTO_DESSEL; + } else { +- ctx->mode |= RK_CRYPTO_AES_FIFO_MODE | ++ rctx->mode |= RK_CRYPTO_AES_FIFO_MODE | + RK_CRYPTO_AES_KEY_CHANGE | + RK_CRYPTO_AES_BYTESWAP_KEY | + RK_CRYPTO_AES_BYTESWAP_IV; + if (ctx->keylen == AES_KEYSIZE_192) +- ctx->mode |= RK_CRYPTO_AES_192BIT_key; ++ rctx->mode |= RK_CRYPTO_AES_192BIT_key; + else if (ctx->keylen == AES_KEYSIZE_256) +- ctx->mode |= RK_CRYPTO_AES_256BIT_key; +- CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode); ++ rctx->mode |= RK_CRYPTO_AES_256BIT_key; ++ CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); + memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); + } + conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | +@@ -246,6 +259,7 @@ static int rk_set_data_start(struct rk_c + struct skcipher_request *req = + skcipher_request_cast(dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); + u8 *src_last_blk = page_address(sg_page(dev->sg_src)) + +@@ -254,7 +268,7 @@ static int rk_set_data_start(struct rk_c + /* Store the iv that need to be updated in chain mode. + * And update the IV buffer to contain the next IV for decryption mode. + */ +- if (ctx->mode & RK_CRYPTO_DEC) { ++ if (rctx->mode & RK_CRYPTO_DEC) { + memcpy(ctx->iv, src_last_blk, ivsize); + sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv, + ivsize, dev->total - ivsize); +@@ -294,11 +308,12 @@ static void rk_iv_copyback(struct rk_cry + struct skcipher_request *req = + skcipher_request_cast(dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); + + /* Update the IV buffer to contain the next IV for encryption mode. */ +- if (!(ctx->mode & RK_CRYPTO_DEC)) { ++ if (!(rctx->mode & RK_CRYPTO_DEC)) { + if (dev->aligned) { + memcpy(req->iv, sg_virt(dev->sg_dst) + + dev->sg_dst->length - ivsize, ivsize); +@@ -314,11 +329,12 @@ static void rk_update_iv(struct rk_crypt + struct skcipher_request *req = + skcipher_request_cast(dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); + u8 *new_iv = NULL; + +- if (ctx->mode & RK_CRYPTO_DEC) { ++ if (rctx->mode & RK_CRYPTO_DEC) { + new_iv = ctx->iv; + } else { + new_iv = page_address(sg_page(dev->sg_dst)) + diff --git a/target/linux/rockchip/patches-6.1/172-crypto-rockchip-add-fallback-for-cipher.patch b/target/linux/rockchip/patches-6.1/172-crypto-rockchip-add-fallback-for-cipher.patch new file mode 100644 index 000000000..a82459924 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/172-crypto-rockchip-add-fallback-for-cipher.patch @@ -0,0 +1,244 @@ +From 3a978f75f454960fbe00355bd01f3cbb8c3bca33 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:44 +0000 +Subject: [PATCH 22/49] crypto: rockchip: add fallback for cipher + +The hardware does not handle 0 size length request, let's add a +fallback. +Furthermore fallback will be used for all unaligned case the hardware +cannot handle. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/Kconfig | 4 + + drivers/crypto/rockchip/rk3288_crypto.h | 2 + + .../crypto/rockchip/rk3288_crypto_skcipher.c | 97 ++++++++++++++++--- + 3 files changed, 90 insertions(+), 13 deletions(-) + +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -669,6 +669,10 @@ config CRYPTO_DEV_IMGTEC_HASH + config CRYPTO_DEV_ROCKCHIP + tristate "Rockchip's Cryptographic Engine driver" + depends on OF && ARCH_ROCKCHIP ++ depends on PM ++ select CRYPTO_ECB ++ select CRYPTO_CBC ++ select CRYPTO_DES + select CRYPTO_AES + select CRYPTO_LIB_DES + select CRYPTO_MD5 +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -246,10 +246,12 @@ struct rk_cipher_ctx { + struct rk_crypto_info *dev; + unsigned int keylen; + u8 iv[AES_BLOCK_SIZE]; ++ struct crypto_skcipher *fallback_tfm; + }; + + struct rk_cipher_rctx { + u32 mode; ++ struct skcipher_request fallback_req; // keep at the end + }; + + enum alg_type { +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -13,6 +13,63 @@ + + #define RK_CRYPTO_DEC BIT(0) + ++static int rk_cipher_need_fallback(struct skcipher_request *req) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ unsigned int bs = crypto_skcipher_blocksize(tfm); ++ struct scatterlist *sgs, *sgd; ++ unsigned int stodo, dtodo, len; ++ ++ if (!req->cryptlen) ++ return true; ++ ++ len = req->cryptlen; ++ sgs = req->src; ++ sgd = req->dst; ++ while (sgs && sgd) { ++ if (!IS_ALIGNED(sgs->offset, sizeof(u32))) { ++ return true; ++ } ++ if (!IS_ALIGNED(sgd->offset, sizeof(u32))) { ++ return true; ++ } ++ stodo = min(len, sgs->length); ++ if (stodo % bs) { ++ return true; ++ } ++ dtodo = min(len, sgd->length); ++ if (dtodo % bs) { ++ return true; ++ } ++ if (stodo != dtodo) { ++ return true; ++ } ++ len -= stodo; ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ } ++ return false; ++} ++ ++static int rk_cipher_fallback(struct skcipher_request *areq) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); ++ struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ int err; ++ ++ skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm); ++ skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags, ++ areq->base.complete, areq->base.data); ++ skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst, ++ areq->cryptlen, areq->iv); ++ if (rctx->mode & RK_CRYPTO_DEC) ++ err = crypto_skcipher_decrypt(&rctx->fallback_req); ++ else ++ err = crypto_skcipher_encrypt(&rctx->fallback_req); ++ return err; ++} ++ + static void rk_crypto_complete(struct crypto_async_request *base, int err) + { + if (base->complete) +@@ -22,10 +79,10 @@ static void rk_crypto_complete(struct cr + static int rk_handle_req(struct rk_crypto_info *dev, + struct skcipher_request *req) + { +- if (!IS_ALIGNED(req->cryptlen, dev->align_size)) +- return -EINVAL; +- else +- return dev->enqueue(dev, &req->base); ++ if (rk_cipher_need_fallback(req)) ++ return rk_cipher_fallback(req); ++ ++ return dev->enqueue(dev, &req->base); + } + + static int rk_aes_setkey(struct crypto_skcipher *cipher, +@@ -39,7 +96,8 @@ static int rk_aes_setkey(struct crypto_s + return -EINVAL; + ctx->keylen = keylen; + memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen); +- return 0; ++ ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_des_setkey(struct crypto_skcipher *cipher, +@@ -54,7 +112,8 @@ static int rk_des_setkey(struct crypto_s + + ctx->keylen = keylen; + memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); +- return 0; ++ ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_tdes_setkey(struct crypto_skcipher *cipher, +@@ -69,7 +128,7 @@ static int rk_tdes_setkey(struct crypto_ + + ctx->keylen = keylen; + memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); +- return 0; ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_aes_ecb_encrypt(struct skcipher_request *req) +@@ -394,6 +453,7 @@ static int rk_ablk_init_tfm(struct crypt + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ const char *name = crypto_tfm_alg_name(&tfm->base); + struct rk_crypto_tmp *algt; + + algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); +@@ -407,6 +467,16 @@ static int rk_ablk_init_tfm(struct crypt + if (!ctx->dev->addr_vir) + return -ENOMEM; + ++ ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->fallback_tfm)) { ++ dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n", ++ name, PTR_ERR(ctx->fallback_tfm)); ++ return PTR_ERR(ctx->fallback_tfm); ++ } ++ ++ tfm->reqsize = sizeof(struct rk_cipher_rctx) + ++ crypto_skcipher_reqsize(ctx->fallback_tfm); ++ + return 0; + } + +@@ -415,6 +485,7 @@ static void rk_ablk_exit_tfm(struct cryp + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + + free_page((unsigned long)ctx->dev->addr_vir); ++ crypto_free_skcipher(ctx->fallback_tfm); + } + + struct rk_crypto_tmp rk_ecb_aes_alg = { +@@ -423,7 +494,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = { + .base.cra_name = "ecb(aes)", + .base.cra_driver_name = "ecb-aes-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x0f, +@@ -445,7 +516,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = { + .base.cra_name = "cbc(aes)", + .base.cra_driver_name = "cbc-aes-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x0f, +@@ -468,7 +539,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = { + .base.cra_name = "ecb(des)", + .base.cra_driver_name = "ecb-des-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -490,7 +561,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = { + .base.cra_name = "cbc(des)", + .base.cra_driver_name = "cbc-des-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -513,7 +584,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg + .base.cra_name = "ecb(des3_ede)", + .base.cra_driver_name = "ecb-des3-ede-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -535,7 +606,7 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg + .base.cra_name = "cbc(des3_ede)", + .base.cra_driver_name = "cbc-des3-ede-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, diff --git a/target/linux/rockchip/patches-6.1/173-crypto-rockchip-add-fallback-for-ahash.patch b/target/linux/rockchip/patches-6.1/173-crypto-rockchip-add-fallback-for-ahash.patch new file mode 100644 index 000000000..bfd725a63 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/173-crypto-rockchip-add-fallback-for-ahash.patch @@ -0,0 +1,75 @@ +From ccfa662cf9f7dc8b5369f7ceb855e116e0b406be Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:45 +0000 +Subject: [PATCH 23/49] crypto: rockchip: add fallback for ahash + +Adds a fallback for all case hardware cannot handle. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 38 +++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -16,6 +16,40 @@ + * so we put the fixed hash out when met zero message. + */ + ++static bool rk_ahash_need_fallback(struct ahash_request *req) ++{ ++ struct scatterlist *sg; ++ ++ sg = req->src; ++ while (sg) { ++ if (!IS_ALIGNED(sg->offset, sizeof(u32))) { ++ return true; ++ } ++ if (sg->length % 4) { ++ return true; ++ } ++ sg = sg_next(sg); ++ } ++ return false; ++} ++ ++static int rk_ahash_digest_fb(struct ahash_request *areq) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); ++ rctx->fallback_req.base.flags = areq->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ rctx->fallback_req.nbytes = areq->nbytes; ++ rctx->fallback_req.src = areq->src; ++ rctx->fallback_req.result = areq->result; ++ ++ return crypto_ahash_digest(&rctx->fallback_req); ++} ++ + static int zero_message_process(struct ahash_request *req) + { + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); +@@ -167,6 +201,9 @@ static int rk_ahash_digest(struct ahash_ + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct rk_crypto_info *dev = tctx->dev; + ++ if (rk_ahash_need_fallback(req)) ++ return rk_ahash_digest_fb(req); ++ + if (!req->nbytes) + return zero_message_process(req); + else +@@ -309,6 +346,7 @@ static void rk_cra_hash_exit(struct cryp + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + + free_page((unsigned long)tctx->dev->addr_vir); ++ crypto_free_ahash(tctx->fallback_tfm); + } + + struct rk_crypto_tmp rk_ahash_sha1 = { diff --git a/target/linux/rockchip/patches-6.1/174-crypto-rockchip-better-handle-cipher-key.patch b/target/linux/rockchip/patches-6.1/174-crypto-rockchip-better-handle-cipher-key.patch new file mode 100644 index 000000000..955b381c1 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/174-crypto-rockchip-better-handle-cipher-key.patch @@ -0,0 +1,81 @@ +From 08b723e0bccdcb3c8d20dd3931a14ec32823e3e9 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:46 +0000 +Subject: [PATCH 24/49] crypto: rockchip: better handle cipher key + +The key should not be set in hardware too much in advance, this will +fail it 2 TFM with different keys generate alternative requests. +The key should be stored and used just before doing cipher operations. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.h | 1 + + drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 10 +++++++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -245,6 +245,7 @@ struct rk_ahash_rctx { + struct rk_cipher_ctx { + struct rk_crypto_info *dev; + unsigned int keylen; ++ u8 key[AES_MAX_KEY_SIZE]; + u8 iv[AES_BLOCK_SIZE]; + struct crypto_skcipher *fallback_tfm; + }; +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -95,7 +95,7 @@ static int rk_aes_setkey(struct crypto_s + keylen != AES_KEYSIZE_256) + return -EINVAL; + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen); ++ memcpy(ctx->key, key, keylen); + + return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } +@@ -111,7 +111,7 @@ static int rk_des_setkey(struct crypto_s + return err; + + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); ++ memcpy(ctx->key, key, keylen); + + return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } +@@ -127,7 +127,8 @@ static int rk_tdes_setkey(struct crypto_ + return err; + + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); ++ memcpy(ctx->key, key, keylen); ++ + return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + +@@ -283,6 +284,7 @@ static void rk_ablk_hw_init(struct rk_cr + RK_CRYPTO_TDES_BYTESWAP_IV; + CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); + memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen); + conf_reg = RK_CRYPTO_DESSEL; + } else { + rctx->mode |= RK_CRYPTO_AES_FIFO_MODE | +@@ -295,6 +297,7 @@ static void rk_ablk_hw_init(struct rk_cr + rctx->mode |= RK_CRYPTO_AES_256BIT_key; + CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); + memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen); + } + conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | + RK_CRYPTO_BYTESWAP_BRFIFO; +@@ -484,6 +487,7 @@ static void rk_ablk_exit_tfm(struct cryp + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + ++ memzero_explicit(ctx->key, ctx->keylen); + free_page((unsigned long)ctx->dev->addr_vir); + crypto_free_skcipher(ctx->fallback_tfm); + } diff --git a/target/linux/rockchip/patches-6.1/175-crypto-rockchip-remove-non-aligned-handling.patch b/target/linux/rockchip/patches-6.1/175-crypto-rockchip-remove-non-aligned-handling.patch new file mode 100644 index 000000000..4edbe7124 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/175-crypto-rockchip-remove-non-aligned-handling.patch @@ -0,0 +1,262 @@ +From a02173a29e7db0431a69ae4aefde0d50af0afe17 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:47 +0000 +Subject: [PATCH 25/49] crypto: rockchip: remove non-aligned handling + +Now driver have fallback for un-aligned cases, remove all code handling +those cases. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 69 +++++-------------- + drivers/crypto/rockchip/rk3288_crypto.h | 4 -- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 22 ++---- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 39 +++-------- + 4 files changed, 31 insertions(+), 103 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -88,63 +88,26 @@ static int rk_load_data(struct rk_crypto + { + unsigned int count; + +- dev->aligned = dev->aligned ? +- check_alignment(sg_src, sg_dst, dev->align_size) : +- dev->aligned; +- if (dev->aligned) { +- count = min(dev->left_bytes, sg_src->length); +- dev->left_bytes -= count; ++ count = min(dev->left_bytes, sg_src->length); ++ dev->left_bytes -= count; + +- if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) { +- dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n", ++ if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) { ++ dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n", + __func__, __LINE__); +- return -EINVAL; +- } +- dev->addr_in = sg_dma_address(sg_src); ++ return -EINVAL; ++ } ++ dev->addr_in = sg_dma_address(sg_src); + +- if (sg_dst) { +- if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) { +- dev_err(dev->dev, ++ if (sg_dst) { ++ if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) { ++ dev_err(dev->dev, + "[%s:%d] dma_map_sg(dst) error\n", + __func__, __LINE__); +- dma_unmap_sg(dev->dev, sg_src, 1, +- DMA_TO_DEVICE); +- return -EINVAL; +- } +- dev->addr_out = sg_dma_address(sg_dst); +- } +- } else { +- count = (dev->left_bytes > PAGE_SIZE) ? +- PAGE_SIZE : dev->left_bytes; +- +- if (!sg_pcopy_to_buffer(dev->first, dev->src_nents, +- dev->addr_vir, count, +- dev->total - dev->left_bytes)) { +- dev_err(dev->dev, "[%s:%d] pcopy err\n", +- __func__, __LINE__); ++ dma_unmap_sg(dev->dev, sg_src, 1, ++ DMA_TO_DEVICE); + return -EINVAL; + } +- dev->left_bytes -= count; +- sg_init_one(&dev->sg_tmp, dev->addr_vir, count); +- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, DMA_TO_DEVICE)) { +- dev_err(dev->dev, "[%s:%d] dma_map_sg(sg_tmp) error\n", +- __func__, __LINE__); +- return -ENOMEM; +- } +- dev->addr_in = sg_dma_address(&dev->sg_tmp); +- +- if (sg_dst) { +- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, +- DMA_FROM_DEVICE)) { +- dev_err(dev->dev, +- "[%s:%d] dma_map_sg(sg_tmp) error\n", +- __func__, __LINE__); +- dma_unmap_sg(dev->dev, &dev->sg_tmp, 1, +- DMA_TO_DEVICE); +- return -ENOMEM; +- } +- dev->addr_out = sg_dma_address(&dev->sg_tmp); +- } ++ dev->addr_out = sg_dma_address(sg_dst); + } + dev->count = count; + return 0; +@@ -154,11 +117,11 @@ static void rk_unload_data(struct rk_cry + { + struct scatterlist *sg_in, *sg_out; + +- sg_in = dev->aligned ? dev->sg_src : &dev->sg_tmp; ++ sg_in = dev->sg_src; + dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE); + + if (dev->sg_dst) { +- sg_out = dev->aligned ? dev->sg_dst : &dev->sg_tmp; ++ sg_out = dev->sg_dst; + dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE); + } + } +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -204,12 +204,8 @@ struct rk_crypto_info { + /* the public variable */ + struct scatterlist *sg_src; + struct scatterlist *sg_dst; +- struct scatterlist sg_tmp; + struct scatterlist *first; + unsigned int left_bytes; +- void *addr_vir; +- int aligned; +- int align_size; + size_t src_nents; + size_t dst_nents; + unsigned int total; +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -236,8 +236,6 @@ static int rk_ahash_start(struct rk_cryp + + dev->total = req->nbytes; + dev->left_bytes = req->nbytes; +- dev->aligned = 0; +- dev->align_size = 4; + dev->sg_dst = NULL; + dev->sg_src = req->src; + dev->first = req->src; +@@ -272,15 +270,13 @@ static int rk_ahash_crypto_rx(struct rk_ + + dev->unload_data(dev); + if (dev->left_bytes) { +- if (dev->aligned) { +- if (sg_is_last(dev->sg_src)) { +- dev_warn(dev->dev, "[%s:%d], Lack of data\n", +- __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; +- } +- dev->sg_src = sg_next(dev->sg_src); ++ if (sg_is_last(dev->sg_src)) { ++ dev_warn(dev->dev, "[%s:%d], Lack of data\n", ++ __func__, __LINE__); ++ err = -ENOMEM; ++ goto out_rx; + } ++ dev->sg_src = sg_next(dev->sg_src); + err = rk_ahash_set_data_start(dev); + } else { + /* +@@ -318,11 +314,6 @@ static int rk_cra_hash_init(struct crypt + algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + + tctx->dev = algt->dev; +- tctx->dev->addr_vir = (void *)__get_free_page(GFP_KERNEL); +- if (!tctx->dev->addr_vir) { +- dev_err(tctx->dev->dev, "failed to kmalloc for addr_vir\n"); +- return -ENOMEM; +- } + tctx->dev->start = rk_ahash_start; + tctx->dev->update = rk_ahash_crypto_rx; + tctx->dev->complete = rk_ahash_crypto_complete; +@@ -345,7 +336,6 @@ static void rk_cra_hash_exit(struct cryp + { + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + +- free_page((unsigned long)tctx->dev->addr_vir); + crypto_free_ahash(tctx->fallback_tfm); + } + +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -356,7 +356,6 @@ static int rk_ablk_start(struct rk_crypt + dev->src_nents = sg_nents(req->src); + dev->sg_dst = req->dst; + dev->dst_nents = sg_nents(req->dst); +- dev->aligned = 1; + + spin_lock_irqsave(&dev->lock, flags); + rk_ablk_hw_init(dev); +@@ -376,13 +375,9 @@ static void rk_iv_copyback(struct rk_cry + + /* Update the IV buffer to contain the next IV for encryption mode. */ + if (!(rctx->mode & RK_CRYPTO_DEC)) { +- if (dev->aligned) { +- memcpy(req->iv, sg_virt(dev->sg_dst) + +- dev->sg_dst->length - ivsize, ivsize); +- } else { +- memcpy(req->iv, dev->addr_vir + +- dev->count - ivsize, ivsize); +- } ++ memcpy(req->iv, ++ sg_virt(dev->sg_dst) + dev->sg_dst->length - ivsize, ++ ivsize); + } + } + +@@ -420,27 +415,16 @@ static int rk_ablk_rx(struct rk_crypto_i + skcipher_request_cast(dev->async_req); + + dev->unload_data(dev); +- if (!dev->aligned) { +- if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents, +- dev->addr_vir, dev->count, +- dev->total - dev->left_bytes - +- dev->count)) { +- err = -EINVAL; +- goto out_rx; +- } +- } + if (dev->left_bytes) { + rk_update_iv(dev); +- if (dev->aligned) { +- if (sg_is_last(dev->sg_src)) { +- dev_err(dev->dev, "[%s:%d] Lack of data\n", ++ if (sg_is_last(dev->sg_src)) { ++ dev_err(dev->dev, "[%s:%d] Lack of data\n", + __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; +- } +- dev->sg_src = sg_next(dev->sg_src); +- dev->sg_dst = sg_next(dev->sg_dst); ++ err = -ENOMEM; ++ goto out_rx; + } ++ dev->sg_src = sg_next(dev->sg_src); ++ dev->sg_dst = sg_next(dev->sg_dst); + err = rk_set_data_start(dev); + } else { + rk_iv_copyback(dev); +@@ -462,13 +446,9 @@ static int rk_ablk_init_tfm(struct crypt + algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + + ctx->dev = algt->dev; +- ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1; + ctx->dev->start = rk_ablk_start; + ctx->dev->update = rk_ablk_rx; + ctx->dev->complete = rk_crypto_complete; +- ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL); +- if (!ctx->dev->addr_vir) +- return -ENOMEM; + + ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(ctx->fallback_tfm)) { +@@ -488,7 +468,6 @@ static void rk_ablk_exit_tfm(struct cryp + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + + memzero_explicit(ctx->key, ctx->keylen); +- free_page((unsigned long)ctx->dev->addr_vir); + crypto_free_skcipher(ctx->fallback_tfm); + } + diff --git a/target/linux/rockchip/patches-6.1/176-crypto-rockchip-rework-by-using-crypto_engine.patch b/target/linux/rockchip/patches-6.1/176-crypto-rockchip-rework-by-using-crypto_engine.patch new file mode 100644 index 000000000..538ebcd88 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/176-crypto-rockchip-rework-by-using-crypto_engine.patch @@ -0,0 +1,881 @@ +From edc3999221d502bbb0b02b4af6110059622bb2f1 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:48 +0000 +Subject: [PATCH 26/49] crypto: rockchip: rework by using crypto_engine + +Instead of doing manual queue management, let's use the crypto/engine +for that. +In the same time, rework the requests handling to be easier to +understand (and fix all bugs related to them). + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/Kconfig | 1 + + drivers/crypto/rockchip/rk3288_crypto.c | 152 +---------- + drivers/crypto/rockchip/rk3288_crypto.h | 39 +-- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 144 +++++----- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 250 +++++++++--------- + 5 files changed, 221 insertions(+), 365 deletions(-) + +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -674,6 +674,7 @@ config CRYPTO_DEV_ROCKCHIP + select CRYPTO_CBC + select CRYPTO_DES + select CRYPTO_AES ++ select CRYPTO_ENGINE + select CRYPTO_LIB_DES + select CRYPTO_MD5 + select CRYPTO_SHA1 +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -65,149 +65,24 @@ static void rk_crypto_disable_clk(struct + clk_disable_unprepare(dev->sclk); + } + +-static int check_alignment(struct scatterlist *sg_src, +- struct scatterlist *sg_dst, +- int align_mask) +-{ +- int in, out, align; +- +- in = IS_ALIGNED((uint32_t)sg_src->offset, 4) && +- IS_ALIGNED((uint32_t)sg_src->length, align_mask); +- if (!sg_dst) +- return in; +- out = IS_ALIGNED((uint32_t)sg_dst->offset, 4) && +- IS_ALIGNED((uint32_t)sg_dst->length, align_mask); +- align = in && out; +- +- return (align && (sg_src->length == sg_dst->length)); +-} +- +-static int rk_load_data(struct rk_crypto_info *dev, +- struct scatterlist *sg_src, +- struct scatterlist *sg_dst) +-{ +- unsigned int count; +- +- count = min(dev->left_bytes, sg_src->length); +- dev->left_bytes -= count; +- +- if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) { +- dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n", +- __func__, __LINE__); +- return -EINVAL; +- } +- dev->addr_in = sg_dma_address(sg_src); +- +- if (sg_dst) { +- if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) { +- dev_err(dev->dev, +- "[%s:%d] dma_map_sg(dst) error\n", +- __func__, __LINE__); +- dma_unmap_sg(dev->dev, sg_src, 1, +- DMA_TO_DEVICE); +- return -EINVAL; +- } +- dev->addr_out = sg_dma_address(sg_dst); +- } +- dev->count = count; +- return 0; +-} +- +-static void rk_unload_data(struct rk_crypto_info *dev) +-{ +- struct scatterlist *sg_in, *sg_out; +- +- sg_in = dev->sg_src; +- dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE); +- +- if (dev->sg_dst) { +- sg_out = dev->sg_dst; +- dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE); +- } +-} +- + static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) + { + struct rk_crypto_info *dev = platform_get_drvdata(dev_id); + u32 interrupt_status; + +- spin_lock(&dev->lock); + interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); + CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status); + ++ dev->status = 1; + if (interrupt_status & 0x0a) { + dev_warn(dev->dev, "DMA Error\n"); +- dev->err = -EFAULT; ++ dev->status = 0; + } +- tasklet_schedule(&dev->done_task); ++ complete(&dev->complete); + +- spin_unlock(&dev->lock); + return IRQ_HANDLED; + } + +-static int rk_crypto_enqueue(struct rk_crypto_info *dev, +- struct crypto_async_request *async_req) +-{ +- unsigned long flags; +- int ret; +- +- spin_lock_irqsave(&dev->lock, flags); +- ret = crypto_enqueue_request(&dev->queue, async_req); +- if (dev->busy) { +- spin_unlock_irqrestore(&dev->lock, flags); +- return ret; +- } +- dev->busy = true; +- spin_unlock_irqrestore(&dev->lock, flags); +- tasklet_schedule(&dev->queue_task); +- +- return ret; +-} +- +-static void rk_crypto_queue_task_cb(unsigned long data) +-{ +- struct rk_crypto_info *dev = (struct rk_crypto_info *)data; +- struct crypto_async_request *async_req, *backlog; +- unsigned long flags; +- int err = 0; +- +- dev->err = 0; +- spin_lock_irqsave(&dev->lock, flags); +- backlog = crypto_get_backlog(&dev->queue); +- async_req = crypto_dequeue_request(&dev->queue); +- +- if (!async_req) { +- dev->busy = false; +- spin_unlock_irqrestore(&dev->lock, flags); +- return; +- } +- spin_unlock_irqrestore(&dev->lock, flags); +- +- if (backlog) { +- backlog->complete(backlog, -EINPROGRESS); +- backlog = NULL; +- } +- +- dev->async_req = async_req; +- err = dev->start(dev); +- if (err) +- dev->complete(dev->async_req, err); +-} +- +-static void rk_crypto_done_task_cb(unsigned long data) +-{ +- struct rk_crypto_info *dev = (struct rk_crypto_info *)data; +- +- if (dev->err) { +- dev->complete(dev->async_req, dev->err); +- return; +- } +- +- dev->err = dev->update(dev); +- if (dev->err) +- dev->complete(dev->async_req, dev->err); +-} +- + static struct rk_crypto_tmp *rk_cipher_algs[] = { + &rk_ecb_aes_alg, + &rk_cbc_aes_alg, +@@ -300,8 +175,6 @@ static int rk_crypto_probe(struct platfo + if (err) + goto err_crypto; + +- spin_lock_init(&crypto_info->lock); +- + crypto_info->reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(crypto_info->reg)) { + err = PTR_ERR(crypto_info->reg); +@@ -351,17 +224,11 @@ static int rk_crypto_probe(struct platfo + crypto_info->dev = &pdev->dev; + platform_set_drvdata(pdev, crypto_info); + +- tasklet_init(&crypto_info->queue_task, +- rk_crypto_queue_task_cb, (unsigned long)crypto_info); +- tasklet_init(&crypto_info->done_task, +- rk_crypto_done_task_cb, (unsigned long)crypto_info); +- crypto_init_queue(&crypto_info->queue, 50); ++ crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true); ++ crypto_engine_start(crypto_info->engine); ++ init_completion(&crypto_info->complete); + + rk_crypto_enable_clk(crypto_info); +- crypto_info->load_data = rk_load_data; +- crypto_info->unload_data = rk_unload_data; +- crypto_info->enqueue = rk_crypto_enqueue; +- crypto_info->busy = false; + + err = rk_crypto_register(crypto_info); + if (err) { +@@ -373,9 +240,9 @@ static int rk_crypto_probe(struct platfo + return 0; + + err_register_alg: +- tasklet_kill(&crypto_info->queue_task); +- tasklet_kill(&crypto_info->done_task); ++ crypto_engine_exit(crypto_info->engine); + err_crypto: ++ dev_err(dev, "Crypto Accelerator not successfully registered\n"); + return err; + } + +@@ -385,8 +252,7 @@ static int rk_crypto_remove(struct platf + + rk_crypto_unregister(); + rk_crypto_disable_clk(crypto_tmp); +- tasklet_kill(&crypto_tmp->done_task); +- tasklet_kill(&crypto_tmp->queue_task); ++ crypto_engine_exit(crypto_tmp->engine); + return 0; + } + +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -5,9 +5,11 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + +@@ -193,39 +195,15 @@ struct rk_crypto_info { + struct reset_control *rst; + void __iomem *reg; + int irq; +- struct crypto_queue queue; +- struct tasklet_struct queue_task; +- struct tasklet_struct done_task; +- struct crypto_async_request *async_req; +- int err; +- /* device lock */ +- spinlock_t lock; +- +- /* the public variable */ +- struct scatterlist *sg_src; +- struct scatterlist *sg_dst; +- struct scatterlist *first; +- unsigned int left_bytes; +- size_t src_nents; +- size_t dst_nents; +- unsigned int total; +- unsigned int count; +- dma_addr_t addr_in; +- dma_addr_t addr_out; +- bool busy; +- int (*start)(struct rk_crypto_info *dev); +- int (*update)(struct rk_crypto_info *dev); +- void (*complete)(struct crypto_async_request *base, int err); +- int (*load_data)(struct rk_crypto_info *dev, +- struct scatterlist *sg_src, +- struct scatterlist *sg_dst); +- void (*unload_data)(struct rk_crypto_info *dev); +- int (*enqueue)(struct rk_crypto_info *dev, +- struct crypto_async_request *async_req); ++ ++ struct crypto_engine *engine; ++ struct completion complete; ++ int status; + }; + + /* the private variable of hash */ + struct rk_ahash_ctx { ++ struct crypto_engine_ctx enginectx; + struct rk_crypto_info *dev; + /* for fallback */ + struct crypto_ahash *fallback_tfm; +@@ -235,10 +213,12 @@ struct rk_ahash_ctx { + struct rk_ahash_rctx { + struct ahash_request fallback_req; + u32 mode; ++ int nrsg; + }; + + /* the private variable of cipher */ + struct rk_cipher_ctx { ++ struct crypto_engine_ctx enginectx; + struct rk_crypto_info *dev; + unsigned int keylen; + u8 key[AES_MAX_KEY_SIZE]; +@@ -247,6 +227,7 @@ struct rk_cipher_ctx { + }; + + struct rk_cipher_rctx { ++ u8 backup_iv[AES_BLOCK_SIZE]; + u32 mode; + struct skcipher_request fallback_req; // keep at the end + }; +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -9,6 +9,7 @@ + * Some ideas are from marvell/cesa.c and s5p-sss.c driver. + */ + #include ++#include + #include "rk3288_crypto.h" + + /* +@@ -72,16 +73,12 @@ static int zero_message_process(struct a + return 0; + } + +-static void rk_ahash_crypto_complete(struct crypto_async_request *base, int err) ++static void rk_ahash_reg_init(struct ahash_request *req) + { +- if (base->complete) +- base->complete(base, err); +-} +- +-static void rk_ahash_reg_init(struct rk_crypto_info *dev) +-{ +- struct ahash_request *req = ahash_request_cast(dev->async_req); + struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct rk_crypto_info *dev = tctx->dev; + int reg_status; + + reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) | +@@ -108,7 +105,7 @@ static void rk_ahash_reg_init(struct rk_ + RK_CRYPTO_BYTESWAP_BRFIFO | + RK_CRYPTO_BYTESWAP_BTFIFO); + +- CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, dev->total); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, req->nbytes); + } + + static int rk_ahash_init(struct ahash_request *req) +@@ -206,44 +203,59 @@ static int rk_ahash_digest(struct ahash_ + + if (!req->nbytes) + return zero_message_process(req); +- else +- return dev->enqueue(dev, &req->base); ++ ++ return crypto_transfer_hash_request_to_engine(dev->engine, req); + } + +-static void crypto_ahash_dma_start(struct rk_crypto_info *dev) ++static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg) + { +- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, dev->addr_in); +- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, (dev->count + 3) / 4); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, sg_dma_address(sg)); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, sg_dma_len(sg) / 4); + CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_HASH_START | + (RK_CRYPTO_HASH_START << 16)); + } + +-static int rk_ahash_set_data_start(struct rk_crypto_info *dev) ++static int rk_hash_prepare(struct crypto_engine *engine, void *breq) + { +- int err; ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ int ret; ++ ++ ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); ++ if (ret <= 0) ++ return -EINVAL; ++ ++ rctx->nrsg = ret; + +- err = dev->load_data(dev, dev->sg_src, NULL); +- if (!err) +- crypto_ahash_dma_start(dev); +- return err; ++ return 0; + } + +-static int rk_ahash_start(struct rk_crypto_info *dev) ++static int rk_hash_unprepare(struct crypto_engine *engine, void *breq) + { +- struct ahash_request *req = ahash_request_cast(dev->async_req); +- struct crypto_ahash *tfm; +- struct rk_ahash_rctx *rctx; ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ ++ dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE); ++ return 0; ++} ++ ++static int rk_hash_run(struct crypto_engine *engine, void *breq) ++{ ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct scatterlist *sg = areq->src; ++ int err = 0; ++ int i; ++ u32 v; + +- dev->total = req->nbytes; +- dev->left_bytes = req->nbytes; +- dev->sg_dst = NULL; +- dev->sg_src = req->src; +- dev->first = req->src; +- dev->src_nents = sg_nents(req->src); +- rctx = ahash_request_ctx(req); + rctx->mode = 0; + +- tfm = crypto_ahash_reqtfm(req); + switch (crypto_ahash_digestsize(tfm)) { + case SHA1_DIGEST_SIZE: + rctx->mode = RK_CRYPTO_HASH_SHA1; +@@ -255,30 +267,26 @@ static int rk_ahash_start(struct rk_cryp + rctx->mode = RK_CRYPTO_HASH_MD5; + break; + default: +- return -EINVAL; ++ err = -EINVAL; ++ goto theend; + } + +- rk_ahash_reg_init(dev); +- return rk_ahash_set_data_start(dev); +-} +- +-static int rk_ahash_crypto_rx(struct rk_crypto_info *dev) +-{ +- int err = 0; +- struct ahash_request *req = ahash_request_cast(dev->async_req); +- struct crypto_ahash *tfm; ++ rk_ahash_reg_init(areq); + +- dev->unload_data(dev); +- if (dev->left_bytes) { +- if (sg_is_last(dev->sg_src)) { +- dev_warn(dev->dev, "[%s:%d], Lack of data\n", +- __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; ++ while (sg) { ++ reinit_completion(&tctx->dev->complete); ++ tctx->dev->status = 0; ++ crypto_ahash_dma_start(tctx->dev, sg); ++ wait_for_completion_interruptible_timeout(&tctx->dev->complete, ++ msecs_to_jiffies(2000)); ++ if (!tctx->dev->status) { ++ dev_err(tctx->dev->dev, "DMA timeout\n"); ++ err = -EFAULT; ++ goto theend; + } +- dev->sg_src = sg_next(dev->sg_src); +- err = rk_ahash_set_data_start(dev); +- } else { ++ sg = sg_next(sg); ++ } ++ + /* + * it will take some time to process date after last dma + * transmission. +@@ -289,18 +297,20 @@ static int rk_ahash_crypto_rx(struct rk_ + * efficiency, and make it response quickly when dma + * complete. + */ +- while (!CRYPTO_READ(dev, RK_CRYPTO_HASH_STS)) +- udelay(10); ++ while (!CRYPTO_READ(tctx->dev, RK_CRYPTO_HASH_STS)) ++ udelay(10); + +- tfm = crypto_ahash_reqtfm(req); +- memcpy_fromio(req->result, dev->reg + RK_CRYPTO_HASH_DOUT_0, +- crypto_ahash_digestsize(tfm)); +- dev->complete(dev->async_req, 0); +- tasklet_schedule(&dev->queue_task); ++ for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) { ++ v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4); ++ put_unaligned_le32(v, areq->result + i * 4); + } + +-out_rx: +- return err; ++theend: ++ local_bh_disable(); ++ crypto_finalize_hash_request(engine, breq, err); ++ local_bh_enable(); ++ ++ return 0; + } + + static int rk_cra_hash_init(struct crypto_tfm *tfm) +@@ -314,9 +324,6 @@ static int rk_cra_hash_init(struct crypt + algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + + tctx->dev = algt->dev; +- tctx->dev->start = rk_ahash_start; +- tctx->dev->update = rk_ahash_crypto_rx; +- tctx->dev->complete = rk_ahash_crypto_complete; + + /* for fallback */ + tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0, +@@ -325,10 +332,15 @@ static int rk_cra_hash_init(struct crypt + dev_err(tctx->dev->dev, "Could not load fallback driver.\n"); + return PTR_ERR(tctx->fallback_tfm); + } ++ + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct rk_ahash_rctx) + + crypto_ahash_reqsize(tctx->fallback_tfm)); + ++ tctx->enginectx.op.do_one_request = rk_hash_run; ++ tctx->enginectx.op.prepare_request = rk_hash_prepare; ++ tctx->enginectx.op.unprepare_request = rk_hash_unprepare; ++ + return 0; + } + +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -9,6 +9,7 @@ + * Some ideas are from marvell-cesa.c and s5p-sss.c driver. + */ + #include ++#include + #include "rk3288_crypto.h" + + #define RK_CRYPTO_DEC BIT(0) +@@ -70,19 +71,15 @@ static int rk_cipher_fallback(struct skc + return err; + } + +-static void rk_crypto_complete(struct crypto_async_request *base, int err) +-{ +- if (base->complete) +- base->complete(base, err); +-} +- + static int rk_handle_req(struct rk_crypto_info *dev, + struct skcipher_request *req) + { ++ struct crypto_engine *engine = dev->engine; ++ + if (rk_cipher_need_fallback(req)) + return rk_cipher_fallback(req); + +- return dev->enqueue(dev, &req->base); ++ return crypto_transfer_skcipher_request_to_engine(engine, req); + } + + static int rk_aes_setkey(struct crypto_skcipher *cipher, +@@ -265,25 +262,21 @@ static int rk_des3_ede_cbc_decrypt(struc + return rk_handle_req(dev, req); + } + +-static void rk_ablk_hw_init(struct rk_crypto_info *dev) ++static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req) + { +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); +- u32 ivsize, block, conf_reg = 0; ++ u32 block, conf_reg = 0; + + block = crypto_tfm_alg_blocksize(tfm); +- ivsize = crypto_skcipher_ivsize(cipher); + + if (block == DES_BLOCK_SIZE) { + rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | + RK_CRYPTO_TDES_BYTESWAP_KEY | + RK_CRYPTO_TDES_BYTESWAP_IV; + CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); +- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); + memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen); + conf_reg = RK_CRYPTO_DESSEL; + } else { +@@ -296,7 +289,6 @@ static void rk_ablk_hw_init(struct rk_cr + else if (ctx->keylen == AES_KEYSIZE_256) + rctx->mode |= RK_CRYPTO_AES_256BIT_key; + CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); +- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); + memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen); + } + conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | +@@ -306,133 +298,138 @@ static void rk_ablk_hw_init(struct rk_cr + RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA); + } + +-static void crypto_dma_start(struct rk_crypto_info *dev) +-{ +- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in); +- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4); +- CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out); ++static void crypto_dma_start(struct rk_crypto_info *dev, ++ struct scatterlist *sgs, ++ struct scatterlist *sgd, unsigned int todo) ++{ ++ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, sg_dma_address(sgs)); ++ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, todo); ++ CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, sg_dma_address(sgd)); + CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START | + _SBF(RK_CRYPTO_BLOCK_START, 16)); + } + +-static int rk_set_data_start(struct rk_crypto_info *dev) ++static int rk_cipher_run(struct crypto_engine *engine, void *async_req) + { +- int err; +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); ++ struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base); ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); +- u8 *src_last_blk = page_address(sg_page(dev->sg_src)) + +- dev->sg_src->offset + dev->sg_src->length - ivsize; +- +- /* Store the iv that need to be updated in chain mode. +- * And update the IV buffer to contain the next IV for decryption mode. +- */ +- if (rctx->mode & RK_CRYPTO_DEC) { +- memcpy(ctx->iv, src_last_blk, ivsize); +- sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv, +- ivsize, dev->total - ivsize); +- } +- +- err = dev->load_data(dev, dev->sg_src, dev->sg_dst); +- if (!err) +- crypto_dma_start(dev); +- return err; +-} +- +-static int rk_ablk_start(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- unsigned long flags; ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ struct scatterlist *sgs, *sgd; + int err = 0; ++ int ivsize = crypto_skcipher_ivsize(tfm); ++ int offset; ++ u8 iv[AES_BLOCK_SIZE]; ++ u8 biv[AES_BLOCK_SIZE]; ++ u8 *ivtouse = areq->iv; ++ unsigned int len = areq->cryptlen; ++ unsigned int todo; ++ ++ ivsize = crypto_skcipher_ivsize(tfm); ++ if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) { ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ offset = areq->cryptlen - ivsize; ++ scatterwalk_map_and_copy(rctx->backup_iv, areq->src, ++ offset, ivsize, 0); ++ } ++ } + +- dev->left_bytes = req->cryptlen; +- dev->total = req->cryptlen; +- dev->sg_src = req->src; +- dev->first = req->src; +- dev->src_nents = sg_nents(req->src); +- dev->sg_dst = req->dst; +- dev->dst_nents = sg_nents(req->dst); +- +- spin_lock_irqsave(&dev->lock, flags); +- rk_ablk_hw_init(dev); +- err = rk_set_data_start(dev); +- spin_unlock_irqrestore(&dev->lock, flags); +- return err; +-} ++ sgs = areq->src; ++ sgd = areq->dst; + +-static void rk_iv_copyback(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); ++ while (sgs && sgd && len) { ++ if (!sgs->length) { ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ continue; ++ } ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ /* we backup last block of source to be used as IV at next step */ ++ offset = sgs->length - ivsize; ++ scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0); ++ } ++ if (sgs == sgd) { ++ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_iv; ++ } ++ } else { ++ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_iv; ++ } ++ err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_sgs; ++ } ++ } ++ err = 0; ++ rk_ablk_hw_init(ctx->dev, areq); ++ if (ivsize) { ++ if (ivsize == DES_BLOCK_SIZE) ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize); ++ else ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize); ++ } ++ reinit_completion(&ctx->dev->complete); ++ ctx->dev->status = 0; + +- /* Update the IV buffer to contain the next IV for encryption mode. */ +- if (!(rctx->mode & RK_CRYPTO_DEC)) { +- memcpy(req->iv, +- sg_virt(dev->sg_dst) + dev->sg_dst->length - ivsize, +- ivsize); ++ todo = min(sg_dma_len(sgs), len); ++ len -= todo; ++ crypto_dma_start(ctx->dev, sgs, sgd, todo / 4); ++ wait_for_completion_interruptible_timeout(&ctx->dev->complete, ++ msecs_to_jiffies(2000)); ++ if (!ctx->dev->status) { ++ dev_err(ctx->dev->dev, "DMA timeout\n"); ++ err = -EFAULT; ++ goto theend; ++ } ++ if (sgs == sgd) { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ } else { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ } ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ memcpy(iv, biv, ivsize); ++ ivtouse = iv; ++ } else { ++ offset = sgd->length - ivsize; ++ scatterwalk_map_and_copy(iv, sgd, offset, ivsize, 0); ++ ivtouse = iv; ++ } ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); + } +-} +- +-static void rk_update_iv(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); +- u8 *new_iv = NULL; + +- if (rctx->mode & RK_CRYPTO_DEC) { +- new_iv = ctx->iv; +- } else { +- new_iv = page_address(sg_page(dev->sg_dst)) + +- dev->sg_dst->offset + dev->sg_dst->length - ivsize; ++ if (areq->iv && ivsize > 0) { ++ offset = areq->cryptlen - ivsize; ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ memcpy(areq->iv, rctx->backup_iv, ivsize); ++ memzero_explicit(rctx->backup_iv, ivsize); ++ } else { ++ scatterwalk_map_and_copy(areq->iv, areq->dst, offset, ++ ivsize, 0); ++ } + } + +- if (ivsize == DES_BLOCK_SIZE) +- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize); +- else if (ivsize == AES_BLOCK_SIZE) +- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize); +-} +- +-/* return: +- * true some err was occurred +- * fault no err, continue +- */ +-static int rk_ablk_rx(struct rk_crypto_info *dev) +-{ +- int err = 0; +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); ++theend: ++ local_bh_disable(); ++ crypto_finalize_skcipher_request(engine, areq, err); ++ local_bh_enable(); ++ return 0; + +- dev->unload_data(dev); +- if (dev->left_bytes) { +- rk_update_iv(dev); +- if (sg_is_last(dev->sg_src)) { +- dev_err(dev->dev, "[%s:%d] Lack of data\n", +- __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; +- } +- dev->sg_src = sg_next(dev->sg_src); +- dev->sg_dst = sg_next(dev->sg_dst); +- err = rk_set_data_start(dev); ++theend_sgs: ++ if (sgs == sgd) { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); + } else { +- rk_iv_copyback(dev); +- /* here show the calculation is over without any err */ +- dev->complete(dev->async_req, 0); +- tasklet_schedule(&dev->queue_task); ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); + } +-out_rx: ++theend_iv: + return err; + } + +@@ -446,9 +443,6 @@ static int rk_ablk_init_tfm(struct crypt + algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + + ctx->dev = algt->dev; +- ctx->dev->start = rk_ablk_start; +- ctx->dev->update = rk_ablk_rx; +- ctx->dev->complete = rk_crypto_complete; + + ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(ctx->fallback_tfm)) { +@@ -460,6 +454,8 @@ static int rk_ablk_init_tfm(struct crypt + tfm->reqsize = sizeof(struct rk_cipher_rctx) + + crypto_skcipher_reqsize(ctx->fallback_tfm); + ++ ctx->enginectx.op.do_one_request = rk_cipher_run; ++ + return 0; + } + diff --git a/target/linux/rockchip/patches-6.1/177-crypto-rockchip-rewrite-type.patch b/target/linux/rockchip/patches-6.1/177-crypto-rockchip-rewrite-type.patch new file mode 100644 index 000000000..032310fb6 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/177-crypto-rockchip-rewrite-type.patch @@ -0,0 +1,174 @@ +From b9d97d2708d9ae617a3bb7bbb91ca543c486f337 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:49 +0000 +Subject: [PATCH 27/49] crypto: rockchip: rewrite type + +Instead of using a custom type for classify algorithms, let's just use +already defined ones. +And let's made a bit more verbose about what is registered. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 26 +++++++++++++------ + drivers/crypto/rockchip/rk3288_crypto.h | 7 +---- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 6 ++--- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 12 ++++----- + 4 files changed, 28 insertions(+), 23 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -102,12 +102,22 @@ static int rk_crypto_register(struct rk_ + + for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) { + rk_cipher_algs[i]->dev = crypto_info; +- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER) +- err = crypto_register_skcipher( +- &rk_cipher_algs[i]->alg.skcipher); +- else +- err = crypto_register_ahash( +- &rk_cipher_algs[i]->alg.hash); ++ switch (rk_cipher_algs[i]->type) { ++ case CRYPTO_ALG_TYPE_SKCIPHER: ++ dev_info(crypto_info->dev, "Register %s as %s\n", ++ rk_cipher_algs[i]->alg.skcipher.base.cra_name, ++ rk_cipher_algs[i]->alg.skcipher.base.cra_driver_name); ++ err = crypto_register_skcipher(&rk_cipher_algs[i]->alg.skcipher); ++ break; ++ case CRYPTO_ALG_TYPE_AHASH: ++ dev_info(crypto_info->dev, "Register %s as %s\n", ++ rk_cipher_algs[i]->alg.hash.halg.base.cra_name, ++ rk_cipher_algs[i]->alg.hash.halg.base.cra_driver_name); ++ err = crypto_register_ahash(&rk_cipher_algs[i]->alg.hash); ++ break; ++ default: ++ dev_err(crypto_info->dev, "unknown algorithm\n"); ++ } + if (err) + goto err_cipher_algs; + } +@@ -115,7 +125,7 @@ static int rk_crypto_register(struct rk_ + + err_cipher_algs: + for (k = 0; k < i; k++) { +- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER) ++ if (rk_cipher_algs[i]->type == CRYPTO_ALG_TYPE_SKCIPHER) + crypto_unregister_skcipher(&rk_cipher_algs[k]->alg.skcipher); + else + crypto_unregister_ahash(&rk_cipher_algs[i]->alg.hash); +@@ -128,7 +138,7 @@ static void rk_crypto_unregister(void) + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) { +- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER) ++ if (rk_cipher_algs[i]->type == CRYPTO_ALG_TYPE_SKCIPHER) + crypto_unregister_skcipher(&rk_cipher_algs[i]->alg.skcipher); + else + crypto_unregister_ahash(&rk_cipher_algs[i]->alg.hash); +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -232,18 +232,13 @@ struct rk_cipher_rctx { + struct skcipher_request fallback_req; // keep at the end + }; + +-enum alg_type { +- ALG_TYPE_HASH, +- ALG_TYPE_CIPHER, +-}; +- + struct rk_crypto_tmp { ++ u32 type; + struct rk_crypto_info *dev; + union { + struct skcipher_alg skcipher; + struct ahash_alg hash; + } alg; +- enum alg_type type; + }; + + extern struct rk_crypto_tmp rk_ecb_aes_alg; +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -352,7 +352,7 @@ static void rk_cra_hash_exit(struct cryp + } + + struct rk_crypto_tmp rk_ahash_sha1 = { +- .type = ALG_TYPE_HASH, ++ .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = rk_ahash_init, + .update = rk_ahash_update, +@@ -382,7 +382,7 @@ struct rk_crypto_tmp rk_ahash_sha1 = { + }; + + struct rk_crypto_tmp rk_ahash_sha256 = { +- .type = ALG_TYPE_HASH, ++ .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = rk_ahash_init, + .update = rk_ahash_update, +@@ -412,7 +412,7 @@ struct rk_crypto_tmp rk_ahash_sha256 = { + }; + + struct rk_crypto_tmp rk_ahash_md5 = { +- .type = ALG_TYPE_HASH, ++ .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = rk_ahash_init, + .update = rk_ahash_update, +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -468,7 +468,7 @@ static void rk_ablk_exit_tfm(struct cryp + } + + struct rk_crypto_tmp rk_ecb_aes_alg = { +- .type = ALG_TYPE_CIPHER, ++ .type = CRYPTO_ALG_TYPE_SKCIPHER, + .alg.skcipher = { + .base.cra_name = "ecb(aes)", + .base.cra_driver_name = "ecb-aes-rk", +@@ -490,7 +490,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = { + }; + + struct rk_crypto_tmp rk_cbc_aes_alg = { +- .type = ALG_TYPE_CIPHER, ++ .type = CRYPTO_ALG_TYPE_SKCIPHER, + .alg.skcipher = { + .base.cra_name = "cbc(aes)", + .base.cra_driver_name = "cbc-aes-rk", +@@ -513,7 +513,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = { + }; + + struct rk_crypto_tmp rk_ecb_des_alg = { +- .type = ALG_TYPE_CIPHER, ++ .type = CRYPTO_ALG_TYPE_SKCIPHER, + .alg.skcipher = { + .base.cra_name = "ecb(des)", + .base.cra_driver_name = "ecb-des-rk", +@@ -535,7 +535,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = { + }; + + struct rk_crypto_tmp rk_cbc_des_alg = { +- .type = ALG_TYPE_CIPHER, ++ .type = CRYPTO_ALG_TYPE_SKCIPHER, + .alg.skcipher = { + .base.cra_name = "cbc(des)", + .base.cra_driver_name = "cbc-des-rk", +@@ -558,7 +558,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = { + }; + + struct rk_crypto_tmp rk_ecb_des3_ede_alg = { +- .type = ALG_TYPE_CIPHER, ++ .type = CRYPTO_ALG_TYPE_SKCIPHER, + .alg.skcipher = { + .base.cra_name = "ecb(des3_ede)", + .base.cra_driver_name = "ecb-des3-ede-rk", +@@ -580,7 +580,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg + }; + + struct rk_crypto_tmp rk_cbc_des3_ede_alg = { +- .type = ALG_TYPE_CIPHER, ++ .type = CRYPTO_ALG_TYPE_SKCIPHER, + .alg.skcipher = { + .base.cra_name = "cbc(des3_ede)", + .base.cra_driver_name = "cbc-des3-ede-rk", diff --git a/target/linux/rockchip/patches-6.1/178-crypto-rockchip-add-debugfs.patch b/target/linux/rockchip/patches-6.1/178-crypto-rockchip-add-debugfs.patch new file mode 100644 index 000000000..0ff54cc53 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/178-crypto-rockchip-add-debugfs.patch @@ -0,0 +1,232 @@ +From ca19c52753332836704019bc5f423b054ea2616b Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:50 +0000 +Subject: [PATCH 28/49] crypto: rockchip: add debugfs + +This patch enable to access usage stats for each algorithm. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/Kconfig | 10 ++++ + drivers/crypto/rockchip/rk3288_crypto.c | 47 +++++++++++++++++++ + drivers/crypto/rockchip/rk3288_crypto.h | 11 +++++ + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 8 ++++ + .../crypto/rockchip/rk3288_crypto_skcipher.c | 15 ++++++ + 5 files changed, 91 insertions(+) + +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -686,6 +686,16 @@ config CRYPTO_DEV_ROCKCHIP + This driver interfaces with the hardware crypto accelerator. + Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. + ++config CRYPTO_DEV_ROCKCHIP_DEBUG ++ bool "Enable Rockchip crypto stats" ++ depends on CRYPTO_DEV_ROCKCHIP ++ depends on DEBUG_FS ++ help ++ Say y to enable Rockchip crypto debug stats. ++ This will create /sys/kernel/debug/rk3288_crypto/stats for displaying ++ the number of requests per algorithm and other internal stats. ++ ++ + config CRYPTO_DEV_ZYNQMP_AES + tristate "Support for Xilinx ZynqMP AES hw accelerator" + depends on ZYNQMP_FIRMWARE || COMPILE_TEST +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -95,6 +95,41 @@ static struct rk_crypto_tmp *rk_cipher_a + &rk_ahash_md5, + }; + ++#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG ++static int rk_crypto_debugfs_show(struct seq_file *seq, void *v) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) { ++ if (!rk_cipher_algs[i]->dev) ++ continue; ++ switch (rk_cipher_algs[i]->type) { ++ case CRYPTO_ALG_TYPE_SKCIPHER: ++ seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", ++ rk_cipher_algs[i]->alg.skcipher.base.cra_driver_name, ++ rk_cipher_algs[i]->alg.skcipher.base.cra_name, ++ rk_cipher_algs[i]->stat_req, rk_cipher_algs[i]->stat_fb); ++ seq_printf(seq, "\tfallback due to length: %lu\n", ++ rk_cipher_algs[i]->stat_fb_len); ++ seq_printf(seq, "\tfallback due to alignment: %lu\n", ++ rk_cipher_algs[i]->stat_fb_align); ++ seq_printf(seq, "\tfallback due to SGs: %lu\n", ++ rk_cipher_algs[i]->stat_fb_sgdiff); ++ break; ++ case CRYPTO_ALG_TYPE_AHASH: ++ seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", ++ rk_cipher_algs[i]->alg.hash.halg.base.cra_driver_name, ++ rk_cipher_algs[i]->alg.hash.halg.base.cra_name, ++ rk_cipher_algs[i]->stat_req, rk_cipher_algs[i]->stat_fb); ++ break; ++ } ++ } ++ return 0; ++} ++ ++DEFINE_SHOW_ATTRIBUTE(rk_crypto_debugfs); ++#endif ++ + static int rk_crypto_register(struct rk_crypto_info *crypto_info) + { + unsigned int i, k; +@@ -246,6 +281,15 @@ static int rk_crypto_probe(struct platfo + goto err_register_alg; + } + ++#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG ++ /* Ignore error of debugfs */ ++ crypto_info->dbgfs_dir = debugfs_create_dir("rk3288_crypto", NULL); ++ crypto_info->dbgfs_stats = debugfs_create_file("stats", 0444, ++ crypto_info->dbgfs_dir, ++ crypto_info, ++ &rk_crypto_debugfs_fops); ++#endif ++ + dev_info(dev, "Crypto Accelerator successfully registered\n"); + return 0; + +@@ -260,6 +304,9 @@ static int rk_crypto_remove(struct platf + { + struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev); + ++#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG ++ debugfs_remove_recursive(crypto_tmp->dbgfs_dir); ++#endif + rk_crypto_unregister(); + rk_crypto_disable_clk(crypto_tmp); + crypto_engine_exit(crypto_tmp->engine); +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -199,6 +200,10 @@ struct rk_crypto_info { + struct crypto_engine *engine; + struct completion complete; + int status; ++#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG ++ struct dentry *dbgfs_dir; ++ struct dentry *dbgfs_stats; ++#endif + }; + + /* the private variable of hash */ +@@ -239,6 +244,12 @@ struct rk_crypto_tmp { + struct skcipher_alg skcipher; + struct ahash_alg hash; + } alg; ++ unsigned long stat_req; ++ unsigned long stat_fb; ++ unsigned long stat_fb_len; ++ unsigned long stat_fb_sglen; ++ unsigned long stat_fb_align; ++ unsigned long stat_fb_sgdiff; + }; + + extern struct rk_crypto_tmp rk_ecb_aes_alg; +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -39,6 +39,10 @@ static int rk_ahash_digest_fb(struct aha + struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm); ++ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); ++ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash); ++ ++ algt->stat_fb++; + + ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); + rctx->fallback_req.base.flags = areq->base.flags & +@@ -249,6 +253,8 @@ static int rk_hash_run(struct crypto_eng + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); + struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); ++ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + struct scatterlist *sg = areq->src; + int err = 0; + int i; +@@ -256,6 +262,8 @@ static int rk_hash_run(struct crypto_eng + + rctx->mode = 0; + ++ algt->stat_req++; ++ + switch (crypto_ahash_digestsize(tfm)) { + case SHA1_DIGEST_SIZE: + rctx->mode = RK_CRYPTO_HASH_SHA1; +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -18,6 +18,8 @@ static int rk_cipher_need_fallback(struc + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + unsigned int bs = crypto_skcipher_blocksize(tfm); ++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + struct scatterlist *sgs, *sgd; + unsigned int stodo, dtodo, len; + +@@ -29,20 +31,25 @@ static int rk_cipher_need_fallback(struc + sgd = req->dst; + while (sgs && sgd) { + if (!IS_ALIGNED(sgs->offset, sizeof(u32))) { ++ algt->stat_fb_align++; + return true; + } + if (!IS_ALIGNED(sgd->offset, sizeof(u32))) { ++ algt->stat_fb_align++; + return true; + } + stodo = min(len, sgs->length); + if (stodo % bs) { ++ algt->stat_fb_len++; + return true; + } + dtodo = min(len, sgd->length); + if (dtodo % bs) { ++ algt->stat_fb_len++; + return true; + } + if (stodo != dtodo) { ++ algt->stat_fb_sgdiff++; + return true; + } + len -= stodo; +@@ -57,8 +64,12 @@ static int rk_cipher_fallback(struct skc + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); + struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + int err; + ++ algt->stat_fb++; ++ + skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm); + skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags, + areq->base.complete, areq->base.data); +@@ -324,6 +335,10 @@ static int rk_cipher_run(struct crypto_e + u8 *ivtouse = areq->iv; + unsigned int len = areq->cryptlen; + unsigned int todo; ++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); ++ ++ algt->stat_req++; + + ivsize = crypto_skcipher_ivsize(tfm); + if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) { diff --git a/target/linux/rockchip/patches-6.1/179-crypto-rockchip-introduce-PM.patch b/target/linux/rockchip/patches-6.1/179-crypto-rockchip-introduce-PM.patch new file mode 100644 index 000000000..afe2a9a68 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/179-crypto-rockchip-introduce-PM.patch @@ -0,0 +1,181 @@ +From a8a988a5e67068b554f92418775f274771cfb068 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:51 +0000 +Subject: [PATCH 29/49] crypto: rockchip: introduce PM + +Add runtime PM support for rockchip crypto. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 51 ++++++++++++++++++- + drivers/crypto/rockchip/rk3288_crypto.h | 1 + + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 10 ++++ + .../crypto/rockchip/rk3288_crypto_skcipher.c | 9 ++++ + 4 files changed, 69 insertions(+), 2 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -65,6 +65,48 @@ static void rk_crypto_disable_clk(struct + clk_disable_unprepare(dev->sclk); + } + ++/* ++ * Power management strategy: The device is suspended unless a TFM exists for ++ * one of the algorithms proposed by this driver. ++ */ ++static int rk_crypto_pm_suspend(struct device *dev) ++{ ++ struct rk_crypto_info *rkdev = dev_get_drvdata(dev); ++ ++ rk_crypto_disable_clk(rkdev); ++ return 0; ++} ++ ++static int rk_crypto_pm_resume(struct device *dev) ++{ ++ struct rk_crypto_info *rkdev = dev_get_drvdata(dev); ++ ++ return rk_crypto_enable_clk(rkdev); ++} ++ ++static const struct dev_pm_ops rk_crypto_pm_ops = { ++ SET_RUNTIME_PM_OPS(rk_crypto_pm_suspend, rk_crypto_pm_resume, NULL) ++}; ++ ++static int rk_crypto_pm_init(struct rk_crypto_info *rkdev) ++{ ++ int err; ++ ++ pm_runtime_use_autosuspend(rkdev->dev); ++ pm_runtime_set_autosuspend_delay(rkdev->dev, 2000); ++ ++ err = pm_runtime_set_suspended(rkdev->dev); ++ if (err) ++ return err; ++ pm_runtime_enable(rkdev->dev); ++ return err; ++} ++ ++static void rk_crypto_pm_exit(struct rk_crypto_info *rkdev) ++{ ++ pm_runtime_disable(rkdev->dev); ++} ++ + static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) + { + struct rk_crypto_info *dev = platform_get_drvdata(dev_id); +@@ -273,7 +315,9 @@ static int rk_crypto_probe(struct platfo + crypto_engine_start(crypto_info->engine); + init_completion(&crypto_info->complete); + +- rk_crypto_enable_clk(crypto_info); ++ err = rk_crypto_pm_init(crypto_info); ++ if (err) ++ goto err_pm; + + err = rk_crypto_register(crypto_info); + if (err) { +@@ -294,6 +338,8 @@ static int rk_crypto_probe(struct platfo + return 0; + + err_register_alg: ++ rk_crypto_pm_exit(crypto_info); ++err_pm: + crypto_engine_exit(crypto_info->engine); + err_crypto: + dev_err(dev, "Crypto Accelerator not successfully registered\n"); +@@ -308,7 +354,7 @@ static int rk_crypto_remove(struct platf + debugfs_remove_recursive(crypto_tmp->dbgfs_dir); + #endif + rk_crypto_unregister(); +- rk_crypto_disable_clk(crypto_tmp); ++ rk_crypto_pm_exit(crypto_tmp); + crypto_engine_exit(crypto_tmp->engine); + return 0; + } +@@ -318,6 +364,7 @@ static struct platform_driver crypto_dri + .remove = rk_crypto_remove, + .driver = { + .name = "rk3288-crypto", ++ .pm = &rk_crypto_pm_ops, + .of_match_table = crypto_of_id_table, + }, + }; +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -328,6 +328,7 @@ static int rk_cra_hash_init(struct crypt + struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg); + + const char *alg_name = crypto_tfm_alg_name(tfm); ++ int err; + + algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + +@@ -349,7 +350,15 @@ static int rk_cra_hash_init(struct crypt + tctx->enginectx.op.prepare_request = rk_hash_prepare; + tctx->enginectx.op.unprepare_request = rk_hash_unprepare; + ++ err = pm_runtime_resume_and_get(tctx->dev->dev); ++ if (err < 0) ++ goto error_pm; ++ + return 0; ++error_pm: ++ crypto_free_ahash(tctx->fallback_tfm); ++ ++ return err; + } + + static void rk_cra_hash_exit(struct crypto_tfm *tfm) +@@ -357,6 +366,7 @@ static void rk_cra_hash_exit(struct cryp + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + + crypto_free_ahash(tctx->fallback_tfm); ++ pm_runtime_put_autosuspend(tctx->dev->dev); + } + + struct rk_crypto_tmp rk_ahash_sha1 = { +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -454,6 +454,7 @@ static int rk_ablk_init_tfm(struct crypt + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); + const char *name = crypto_tfm_alg_name(&tfm->base); + struct rk_crypto_tmp *algt; ++ int err; + + algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + +@@ -471,7 +472,14 @@ static int rk_ablk_init_tfm(struct crypt + + ctx->enginectx.op.do_one_request = rk_cipher_run; + ++ err = pm_runtime_resume_and_get(ctx->dev->dev); ++ if (err < 0) ++ goto error_pm; ++ + return 0; ++error_pm: ++ crypto_free_skcipher(ctx->fallback_tfm); ++ return err; + } + + static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) +@@ -480,6 +488,7 @@ static void rk_ablk_exit_tfm(struct cryp + + memzero_explicit(ctx->key, ctx->keylen); + crypto_free_skcipher(ctx->fallback_tfm); ++ pm_runtime_put_autosuspend(ctx->dev->dev); + } + + struct rk_crypto_tmp rk_ecb_aes_alg = { diff --git a/target/linux/rockchip/patches-6.1/180-crypto-rockchip-handle-reset-also-in-PM.patch b/target/linux/rockchip/patches-6.1/180-crypto-rockchip-handle-reset-also-in-PM.patch new file mode 100644 index 000000000..5c7e6953f --- /dev/null +++ b/target/linux/rockchip/patches-6.1/180-crypto-rockchip-handle-reset-also-in-PM.patch @@ -0,0 +1,66 @@ +From e1d7ad70ff4447218815f3b9427ee7cd8cc6836b Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:52 +0000 +Subject: [PATCH 30/49] crypto: rockchip: handle reset also in PM + +reset could be handled by PM functions. +We keep the initial reset pulse to be sure the hw is a know device state +after probe. + +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -74,14 +74,23 @@ static int rk_crypto_pm_suspend(struct d + struct rk_crypto_info *rkdev = dev_get_drvdata(dev); + + rk_crypto_disable_clk(rkdev); ++ reset_control_assert(rkdev->rst); ++ + return 0; + } + + static int rk_crypto_pm_resume(struct device *dev) + { + struct rk_crypto_info *rkdev = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = rk_crypto_enable_clk(rkdev); ++ if (ret) ++ return ret; ++ ++ reset_control_deassert(rkdev->rst); ++ return 0; + +- return rk_crypto_enable_clk(rkdev); + } + + static const struct dev_pm_ops rk_crypto_pm_ops = { +@@ -222,13 +231,6 @@ static void rk_crypto_unregister(void) + } + } + +-static void rk_crypto_action(void *data) +-{ +- struct rk_crypto_info *crypto_info = data; +- +- reset_control_assert(crypto_info->rst); +-} +- + static const struct of_device_id crypto_of_id_table[] = { + { .compatible = "rockchip,rk3288-crypto" }, + {} +@@ -258,10 +260,6 @@ static int rk_crypto_probe(struct platfo + usleep_range(10, 20); + reset_control_deassert(crypto_info->rst); + +- err = devm_add_action_or_reset(dev, rk_crypto_action, crypto_info); +- if (err) +- goto err_crypto; +- + crypto_info->reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(crypto_info->reg)) { + err = PTR_ERR(crypto_info->reg); diff --git a/target/linux/rockchip/patches-6.1/181-crypto-rockchip-use-clk_bulk-to-simplify-clock-manag.patch b/target/linux/rockchip/patches-6.1/181-crypto-rockchip-use-clk_bulk-to-simplify-clock-manag.patch new file mode 100644 index 000000000..2caf7f6c8 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/181-crypto-rockchip-use-clk_bulk-to-simplify-clock-manag.patch @@ -0,0 +1,118 @@ +From b388e1b6a75d477735f7e2b90130169638b72c37 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:53 +0000 +Subject: [PATCH 31/49] crypto: rockchip: use clk_bulk to simplify clock + management + +rk3328 does not have the same clock names than rk3288, instead of using a complex +clock management, let's use clk_bulk to simplify their handling. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 66 ++++--------------------- + drivers/crypto/rockchip/rk3288_crypto.h | 6 +-- + 2 files changed, 11 insertions(+), 61 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -22,47 +22,16 @@ static int rk_crypto_enable_clk(struct r + { + int err; + +- err = clk_prepare_enable(dev->sclk); +- if (err) { +- dev_err(dev->dev, "[%s:%d], Couldn't enable clock sclk\n", +- __func__, __LINE__); +- goto err_return; +- } +- err = clk_prepare_enable(dev->aclk); +- if (err) { +- dev_err(dev->dev, "[%s:%d], Couldn't enable clock aclk\n", +- __func__, __LINE__); +- goto err_aclk; +- } +- err = clk_prepare_enable(dev->hclk); +- if (err) { +- dev_err(dev->dev, "[%s:%d], Couldn't enable clock hclk\n", +- __func__, __LINE__); +- goto err_hclk; +- } +- err = clk_prepare_enable(dev->dmaclk); +- if (err) { +- dev_err(dev->dev, "[%s:%d], Couldn't enable clock dmaclk\n", +- __func__, __LINE__); +- goto err_dmaclk; +- } +- return err; +-err_dmaclk: +- clk_disable_unprepare(dev->hclk); +-err_hclk: +- clk_disable_unprepare(dev->aclk); +-err_aclk: +- clk_disable_unprepare(dev->sclk); +-err_return: ++ err = clk_bulk_prepare_enable(dev->num_clks, dev->clks); ++ if (err) ++ dev_err(dev->dev, "Could not enable clock clks\n"); ++ + return err; + } + + static void rk_crypto_disable_clk(struct rk_crypto_info *dev) + { +- clk_disable_unprepare(dev->dmaclk); +- clk_disable_unprepare(dev->hclk); +- clk_disable_unprepare(dev->aclk); +- clk_disable_unprepare(dev->sclk); ++ clk_bulk_disable_unprepare(dev->num_clks, dev->clks); + } + + /* +@@ -266,27 +235,10 @@ static int rk_crypto_probe(struct platfo + goto err_crypto; + } + +- crypto_info->aclk = devm_clk_get(&pdev->dev, "aclk"); +- if (IS_ERR(crypto_info->aclk)) { +- err = PTR_ERR(crypto_info->aclk); +- goto err_crypto; +- } +- +- crypto_info->hclk = devm_clk_get(&pdev->dev, "hclk"); +- if (IS_ERR(crypto_info->hclk)) { +- err = PTR_ERR(crypto_info->hclk); +- goto err_crypto; +- } +- +- crypto_info->sclk = devm_clk_get(&pdev->dev, "sclk"); +- if (IS_ERR(crypto_info->sclk)) { +- err = PTR_ERR(crypto_info->sclk); +- goto err_crypto; +- } +- +- crypto_info->dmaclk = devm_clk_get(&pdev->dev, "apb_pclk"); +- if (IS_ERR(crypto_info->dmaclk)) { +- err = PTR_ERR(crypto_info->dmaclk); ++ crypto_info->num_clks = devm_clk_bulk_get_all(&pdev->dev, ++ &crypto_info->clks); ++ if (crypto_info->num_clks < 3) { ++ err = -EINVAL; + goto err_crypto; + } + +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -190,10 +190,8 @@ + + struct rk_crypto_info { + struct device *dev; +- struct clk *aclk; +- struct clk *hclk; +- struct clk *sclk; +- struct clk *dmaclk; ++ struct clk_bulk_data *clks; ++ int num_clks; + struct reset_control *rst; + void __iomem *reg; + int irq; diff --git a/target/linux/rockchip/patches-6.1/182-crypto-rockchip-add-myself-as-maintainer.patch b/target/linux/rockchip/patches-6.1/182-crypto-rockchip-add-myself-as-maintainer.patch new file mode 100644 index 000000000..4746a9d05 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/182-crypto-rockchip-add-myself-as-maintainer.patch @@ -0,0 +1,30 @@ +From 771d6ebe99b61c1b143feab92e896fecc6ba16d0 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:54 +0000 +Subject: [PATCH 32/49] crypto: rockchip: add myself as maintainer + +Nobody is set as maintainer of rockchip crypto, I propose to do it as I +have already reworked lot of this code. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + MAINTAINERS | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -17781,6 +17781,13 @@ F: Documentation/ABI/*/sysfs-driver-hid- + F: drivers/hid/hid-roccat* + F: include/linux/hid-roccat* + ++ROCKCHIP CRYPTO DRIVERS ++M: Corentin Labbe ++L: linux-crypto@vger.kernel.org ++S: Maintained ++F: Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml ++F: drivers/crypto/rockchip/ ++ + ROCKCHIP I2S TDM DRIVER + M: Nicolas Frattaroli + L: linux-rockchip@lists.infradead.org diff --git a/target/linux/rockchip/patches-6.1/183-crypto-rockchip-use-read_poll_timeout.patch b/target/linux/rockchip/patches-6.1/183-crypto-rockchip-use-read_poll_timeout.patch new file mode 100644 index 000000000..b1ae94d2e --- /dev/null +++ b/target/linux/rockchip/patches-6.1/183-crypto-rockchip-use-read_poll_timeout.patch @@ -0,0 +1,54 @@ +From f7d1ea66d097a14e2c8dd312f2360db746db055f Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:55 +0000 +Subject: [PATCH 33/49] crypto: rockchip: use read_poll_timeout + +Use read_poll_timeout instead of open coding it. +In the same time, fix indentation of related comment. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 24 +++++++++---------- + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -10,6 +10,7 @@ + */ + #include + #include ++#include + #include "rk3288_crypto.h" + + /* +@@ -295,18 +296,17 @@ static int rk_hash_run(struct crypto_eng + sg = sg_next(sg); + } + +- /* +- * it will take some time to process date after last dma +- * transmission. +- * +- * waiting time is relative with the last date len, +- * so cannot set a fixed time here. +- * 10us makes system not call here frequently wasting +- * efficiency, and make it response quickly when dma +- * complete. +- */ +- while (!CRYPTO_READ(tctx->dev, RK_CRYPTO_HASH_STS)) +- udelay(10); ++ /* ++ * it will take some time to process date after last dma ++ * transmission. ++ * ++ * waiting time is relative with the last date len, ++ * so cannot set a fixed time here. ++ * 10us makes system not call here frequently wasting ++ * efficiency, and make it response quickly when dma ++ * complete. ++ */ ++ readl_poll_timeout(tctx->dev->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000); + + for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) { + v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4); diff --git a/target/linux/rockchip/patches-6.1/184-crypto-rockchip-fix-style-issue.patch b/target/linux/rockchip/patches-6.1/184-crypto-rockchip-fix-style-issue.patch new file mode 100644 index 000000000..4c6d89be1 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/184-crypto-rockchip-fix-style-issue.patch @@ -0,0 +1,55 @@ +From ce5aef761e09d6f17ed8f3e0dae3bf90fb06a838 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:56 +0000 +Subject: [PATCH 34/49] crypto: rockchip: fix style issue + +This patch fixes some warning reported by checkpatch + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -336,7 +336,7 @@ static int rk_cra_hash_init(struct crypt + + /* for fallback */ + tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0, +- CRYPTO_ALG_NEED_FALLBACK); ++ CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(tctx->fallback_tfm)) { + dev_err(tctx->dev->dev, "Could not load fallback driver.\n"); + return PTR_ERR(tctx->fallback_tfm); +@@ -394,8 +394,8 @@ struct rk_crypto_tmp rk_ahash_sha1 = { + .cra_init = rk_cra_hash_init, + .cra_exit = rk_cra_hash_exit, + .cra_module = THIS_MODULE, +- } +- } ++ } ++ } + } + }; + +@@ -424,8 +424,8 @@ struct rk_crypto_tmp rk_ahash_sha256 = { + .cra_init = rk_cra_hash_init, + .cra_exit = rk_cra_hash_exit, + .cra_module = THIS_MODULE, +- } +- } ++ } ++ } + } + }; + +@@ -454,7 +454,7 @@ struct rk_crypto_tmp rk_ahash_md5 = { + .cra_init = rk_cra_hash_init, + .cra_exit = rk_cra_hash_exit, + .cra_module = THIS_MODULE, +- } + } ++ } + } + }; diff --git a/target/linux/rockchip/patches-6.1/185-crypto-rockchip-add-support-for-rk3328.patch b/target/linux/rockchip/patches-6.1/185-crypto-rockchip-add-support-for-rk3328.patch new file mode 100644 index 000000000..7319de603 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/185-crypto-rockchip-add-support-for-rk3328.patch @@ -0,0 +1,23 @@ +From 50f01f648e6cc3d2b20674b50b662290c98e9041 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:57 +0000 +Subject: [PATCH 35/49] crypto: rockchip: add support for rk3328 + +The rk3328 could be used as-is by the rockchip driver. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -202,6 +202,7 @@ static void rk_crypto_unregister(void) + + static const struct of_device_id crypto_of_id_table[] = { + { .compatible = "rockchip,rk3288-crypto" }, ++ { .compatible = "rockchip,rk3328-crypto" }, + {} + }; + MODULE_DEVICE_TABLE(of, crypto_of_id_table); diff --git a/target/linux/rockchip/patches-6.1/186-crypto-rockchip-rename-ablk-functions-to-cipher.patch b/target/linux/rockchip/patches-6.1/186-crypto-rockchip-rename-ablk-functions-to-cipher.patch new file mode 100644 index 000000000..bc6337569 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/186-crypto-rockchip-rename-ablk-functions-to-cipher.patch @@ -0,0 +1,119 @@ +From d6996995f04ac2be833d87b94e78aa532ed9ee16 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:58 +0000 +Subject: [PATCH 36/49] crypto: rockchip: rename ablk functions to cipher + +Some functions have still ablk in their name even if there are +not handling ablk_cipher anymore. +So let's rename them. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 32 +++++++++---------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -273,7 +273,7 @@ static int rk_des3_ede_cbc_decrypt(struc + return rk_handle_req(dev, req); + } + +-static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req) ++static void rk_cipher_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req) + { + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); +@@ -382,7 +382,7 @@ static int rk_cipher_run(struct crypto_e + } + } + err = 0; +- rk_ablk_hw_init(ctx->dev, areq); ++ rk_cipher_hw_init(ctx->dev, areq); + if (ivsize) { + if (ivsize == DES_BLOCK_SIZE) + memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize); +@@ -448,7 +448,7 @@ theend_iv: + return err; + } + +-static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) ++static int rk_cipher_tfm_init(struct crypto_skcipher *tfm) + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); +@@ -482,7 +482,7 @@ error_pm: + return err; + } + +-static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) ++static void rk_cipher_tfm_exit(struct crypto_skcipher *tfm) + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + +@@ -503,8 +503,8 @@ struct rk_crypto_tmp rk_ecb_aes_alg = { + .base.cra_alignmask = 0x0f, + .base.cra_module = THIS_MODULE, + +- .init = rk_ablk_init_tfm, +- .exit = rk_ablk_exit_tfm, ++ .init = rk_cipher_tfm_init, ++ .exit = rk_cipher_tfm_exit, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = rk_aes_setkey, +@@ -525,8 +525,8 @@ struct rk_crypto_tmp rk_cbc_aes_alg = { + .base.cra_alignmask = 0x0f, + .base.cra_module = THIS_MODULE, + +- .init = rk_ablk_init_tfm, +- .exit = rk_ablk_exit_tfm, ++ .init = rk_cipher_tfm_init, ++ .exit = rk_cipher_tfm_exit, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, +@@ -548,8 +548,8 @@ struct rk_crypto_tmp rk_ecb_des_alg = { + .base.cra_alignmask = 0x07, + .base.cra_module = THIS_MODULE, + +- .init = rk_ablk_init_tfm, +- .exit = rk_ablk_exit_tfm, ++ .init = rk_cipher_tfm_init, ++ .exit = rk_cipher_tfm_exit, + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .setkey = rk_des_setkey, +@@ -570,8 +570,8 @@ struct rk_crypto_tmp rk_cbc_des_alg = { + .base.cra_alignmask = 0x07, + .base.cra_module = THIS_MODULE, + +- .init = rk_ablk_init_tfm, +- .exit = rk_ablk_exit_tfm, ++ .init = rk_cipher_tfm_init, ++ .exit = rk_cipher_tfm_exit, + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .ivsize = DES_BLOCK_SIZE, +@@ -593,8 +593,8 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg + .base.cra_alignmask = 0x07, + .base.cra_module = THIS_MODULE, + +- .init = rk_ablk_init_tfm, +- .exit = rk_ablk_exit_tfm, ++ .init = rk_cipher_tfm_init, ++ .exit = rk_cipher_tfm_exit, + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .setkey = rk_tdes_setkey, +@@ -615,8 +615,8 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg + .base.cra_alignmask = 0x07, + .base.cra_module = THIS_MODULE, + +- .init = rk_ablk_init_tfm, +- .exit = rk_ablk_exit_tfm, ++ .init = rk_cipher_tfm_init, ++ .exit = rk_cipher_tfm_exit, + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .ivsize = DES_BLOCK_SIZE, diff --git a/target/linux/rockchip/patches-6.1/187-crypto-rockchip-rework-rk_handle_req-function.patch b/target/linux/rockchip/patches-6.1/187-crypto-rockchip-rework-rk_handle_req-function.patch new file mode 100644 index 000000000..136423a66 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/187-crypto-rockchip-rework-rk_handle_req-function.patch @@ -0,0 +1,180 @@ +From d294827ca9bf9c9a893ea0b70f5cec93a3248706 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:54:59 +0000 +Subject: [PATCH 37/49] crypto: rockchip: rework rk_handle_req function + +This patch rework the rk_handle_req(), simply removing the +rk_crypto_info parameter. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 68 +++++-------------- + 1 file changed, 17 insertions(+), 51 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -82,10 +82,12 @@ static int rk_cipher_fallback(struct skc + return err; + } + +-static int rk_handle_req(struct rk_crypto_info *dev, +- struct skcipher_request *req) ++static int rk_cipher_handle_req(struct skcipher_request *req) + { +- struct crypto_engine *engine = dev->engine; ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct rk_cipher_ctx *tctx = crypto_skcipher_ctx(tfm); ++ struct rk_crypto_info *rkc = tctx->dev; ++ struct crypto_engine *engine = rkc->engine; + + if (rk_cipher_need_fallback(req)) + return rk_cipher_fallback(req); +@@ -142,135 +144,99 @@ static int rk_tdes_setkey(struct crypto_ + + static int rk_aes_ecb_encrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_AES_ECB_MODE; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_aes_ecb_decrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_aes_cbc_encrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_AES_CBC_MODE; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_aes_cbc_decrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_des_ecb_encrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = 0; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_des_ecb_decrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_DEC; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_des_cbc_encrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_des_cbc_decrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_TDES_SELECT; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *dev = ctx->dev; + + rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC | + RK_CRYPTO_DEC; +- return rk_handle_req(dev, req); ++ return rk_cipher_handle_req(req); + } + + static void rk_cipher_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req) diff --git a/target/linux/rockchip/patches-6.1/188-crypto-rockchip-use-a-rk_crypto_info-variable-instea.patch b/target/linux/rockchip/patches-6.1/188-crypto-rockchip-use-a-rk_crypto_info-variable-instea.patch new file mode 100644 index 000000000..b663638df --- /dev/null +++ b/target/linux/rockchip/patches-6.1/188-crypto-rockchip-use-a-rk_crypto_info-variable-instea.patch @@ -0,0 +1,172 @@ +From b792b8f33d2c772cab201a068884feb0c10c1533 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:00 +0000 +Subject: [PATCH 38/49] crypto: rockchip: use a rk_crypto_info variable instead + of lot of indirection + +Instead of using lot of ctx->dev->xx indirections, use an intermediate +variable for rk_crypto_info. +This will help later, when 2 different rk_crypto_info would be used. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 23 +++++++----- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 37 ++++++++++--------- + 2 files changed, 32 insertions(+), 28 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -226,9 +226,10 @@ static int rk_hash_prepare(struct crypto + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); + struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct rk_crypto_info *rkc = tctx->dev; + int ret; + +- ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); ++ ret = dma_map_sg(rkc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); + if (ret <= 0) + return -EINVAL; + +@@ -243,8 +244,9 @@ static int rk_hash_unprepare(struct cryp + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); + struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct rk_crypto_info *rkc = tctx->dev; + +- dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE); ++ dma_unmap_sg(rkc->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE); + return 0; + } + +@@ -257,6 +259,7 @@ static int rk_hash_run(struct crypto_eng + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + struct scatterlist *sg = areq->src; ++ struct rk_crypto_info *rkc = tctx->dev; + int err = 0; + int i; + u32 v; +@@ -283,13 +286,13 @@ static int rk_hash_run(struct crypto_eng + rk_ahash_reg_init(areq); + + while (sg) { +- reinit_completion(&tctx->dev->complete); +- tctx->dev->status = 0; +- crypto_ahash_dma_start(tctx->dev, sg); +- wait_for_completion_interruptible_timeout(&tctx->dev->complete, ++ reinit_completion(&rkc->complete); ++ rkc->status = 0; ++ crypto_ahash_dma_start(rkc, sg); ++ wait_for_completion_interruptible_timeout(&rkc->complete, + msecs_to_jiffies(2000)); +- if (!tctx->dev->status) { +- dev_err(tctx->dev->dev, "DMA timeout\n"); ++ if (!rkc->status) { ++ dev_err(rkc->dev, "DMA timeout\n"); + err = -EFAULT; + goto theend; + } +@@ -306,10 +309,10 @@ static int rk_hash_run(struct crypto_eng + * efficiency, and make it response quickly when dma + * complete. + */ +- readl_poll_timeout(tctx->dev->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000); ++ readl_poll_timeout(rkc->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000); + + for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) { +- v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4); ++ v = readl(rkc->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4); + put_unaligned_le32(v, areq->result + i * 4); + } + +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -303,6 +303,7 @@ static int rk_cipher_run(struct crypto_e + unsigned int todo; + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); + struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); ++ struct rk_crypto_info *rkc = ctx->dev; + + algt->stat_req++; + +@@ -330,49 +331,49 @@ static int rk_cipher_run(struct crypto_e + scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0); + } + if (sgs == sgd) { +- err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ err = dma_map_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL); + if (err <= 0) { + err = -EINVAL; + goto theend_iv; + } + } else { +- err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ err = dma_map_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE); + if (err <= 0) { + err = -EINVAL; + goto theend_iv; + } +- err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ err = dma_map_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE); + if (err <= 0) { + err = -EINVAL; + goto theend_sgs; + } + } + err = 0; +- rk_cipher_hw_init(ctx->dev, areq); ++ rk_cipher_hw_init(rkc, areq); + if (ivsize) { + if (ivsize == DES_BLOCK_SIZE) +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize); ++ memcpy_toio(rkc->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize); + else +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize); ++ memcpy_toio(rkc->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize); + } +- reinit_completion(&ctx->dev->complete); +- ctx->dev->status = 0; ++ reinit_completion(&rkc->complete); ++ rkc->status = 0; + + todo = min(sg_dma_len(sgs), len); + len -= todo; +- crypto_dma_start(ctx->dev, sgs, sgd, todo / 4); +- wait_for_completion_interruptible_timeout(&ctx->dev->complete, ++ crypto_dma_start(rkc, sgs, sgd, todo / 4); ++ wait_for_completion_interruptible_timeout(&rkc->complete, + msecs_to_jiffies(2000)); +- if (!ctx->dev->status) { +- dev_err(ctx->dev->dev, "DMA timeout\n"); ++ if (!rkc->status) { ++ dev_err(rkc->dev, "DMA timeout\n"); + err = -EFAULT; + goto theend; + } + if (sgs == sgd) { +- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ dma_unmap_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL); + } else { +- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); +- dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ dma_unmap_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE); + } + if (rctx->mode & RK_CRYPTO_DEC) { + memcpy(iv, biv, ivsize); +@@ -405,10 +406,10 @@ theend: + + theend_sgs: + if (sgs == sgd) { +- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ dma_unmap_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL); + } else { +- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); +- dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ dma_unmap_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE); + } + theend_iv: + return err; diff --git a/target/linux/rockchip/patches-6.1/189-crypto-rockchip-use-the-rk_crypto_info-given-as-para.patch b/target/linux/rockchip/patches-6.1/189-crypto-rockchip-use-the-rk_crypto_info-given-as-para.patch new file mode 100644 index 000000000..d5d582fd2 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/189-crypto-rockchip-use-the-rk_crypto_info-given-as-para.patch @@ -0,0 +1,34 @@ +From 9cbaeb79b6353f2b13c592754739d33f027e6662 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:01 +0000 +Subject: [PATCH 39/49] crypto: rockchip: use the rk_crypto_info given as + parameter + +Instead of using the crypto_info from TFM ctx, use the one given as parameter. + +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -254,7 +254,7 @@ static void rk_cipher_hw_init(struct rk_ + RK_CRYPTO_TDES_BYTESWAP_KEY | + RK_CRYPTO_TDES_BYTESWAP_IV; + CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen); ++ memcpy_toio(dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen); + conf_reg = RK_CRYPTO_DESSEL; + } else { + rctx->mode |= RK_CRYPTO_AES_FIFO_MODE | +@@ -266,7 +266,7 @@ static void rk_cipher_hw_init(struct rk_ + else if (ctx->keylen == AES_KEYSIZE_256) + rctx->mode |= RK_CRYPTO_AES_256BIT_key; + CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen); ++ memcpy_toio(dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen); + } + conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | + RK_CRYPTO_BYTESWAP_BRFIFO; diff --git a/target/linux/rockchip/patches-6.1/190-dt-bindings-crypto-convert-rockchip-crypto-to-YAML.patch b/target/linux/rockchip/patches-6.1/190-dt-bindings-crypto-convert-rockchip-crypto-to-YAML.patch new file mode 100644 index 000000000..6d41f1a01 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/190-dt-bindings-crypto-convert-rockchip-crypto-to-YAML.patch @@ -0,0 +1,115 @@ +From b4f63ecb0942ead52697ef3790c79546804fe478 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:02 +0000 +Subject: [PATCH 40/49] dt-bindings: crypto: convert rockchip-crypto to YAML + +Convert rockchip-crypto to YAML. + +Reviewed-by: John Keeping +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Corentin Labbe +--- + .../crypto/rockchip,rk3288-crypto.yaml | 64 +++++++++++++++++++ + .../bindings/crypto/rockchip-crypto.txt | 28 -------- + 2 files changed, 64 insertions(+), 28 deletions(-) + create mode 100644 Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml + delete mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml +@@ -0,0 +1,64 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/crypto/rockchip,rk3288-crypto.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip Electronics Security Accelerator ++ ++maintainers: ++ - Heiko Stuebner ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,rk3288-crypto ++ ++ reg: ++ maxItems: 1 ++ ++ interrupts: ++ maxItems: 1 ++ ++ clocks: ++ maxItems: 4 ++ ++ clock-names: ++ items: ++ - const: aclk ++ - const: hclk ++ - const: sclk ++ - const: apb_pclk ++ ++ resets: ++ maxItems: 1 ++ ++ reset-names: ++ items: ++ - const: crypto-rst ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ crypto@ff8a0000 { ++ compatible = "rockchip,rk3288-crypto"; ++ reg = <0xff8a0000 0x4000>; ++ interrupts = ; ++ clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>, ++ <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>; ++ clock-names = "aclk", "hclk", "sclk", "apb_pclk"; ++ resets = <&cru SRST_CRYPTO>; ++ reset-names = "crypto-rst"; ++ }; +--- a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt ++++ /dev/null +@@ -1,28 +0,0 @@ +-Rockchip Electronics And Security Accelerator +- +-Required properties: +-- compatible: Should be "rockchip,rk3288-crypto" +-- reg: Base physical address of the engine and length of memory mapped +- region +-- interrupts: Interrupt number +-- clocks: Reference to the clocks about crypto +-- clock-names: "aclk" used to clock data +- "hclk" used to clock data +- "sclk" used to clock crypto accelerator +- "apb_pclk" used to clock dma +-- resets: Must contain an entry for each entry in reset-names. +- See ../reset/reset.txt for details. +-- reset-names: Must include the name "crypto-rst". +- +-Examples: +- +- crypto: cypto-controller@ff8a0000 { +- compatible = "rockchip,rk3288-crypto"; +- reg = <0xff8a0000 0x4000>; +- interrupts = ; +- clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>, +- <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>; +- clock-names = "aclk", "hclk", "sclk", "apb_pclk"; +- resets = <&cru SRST_CRYPTO>; +- reset-names = "crypto-rst"; +- }; diff --git a/target/linux/rockchip/patches-6.1/191-dt-bindings-crypto-rockchip-add-new-compatible.patch b/target/linux/rockchip/patches-6.1/191-dt-bindings-crypto-rockchip-add-new-compatible.patch new file mode 100644 index 000000000..dfe6203a0 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/191-dt-bindings-crypto-rockchip-add-new-compatible.patch @@ -0,0 +1,114 @@ +From a20c32bcc5b5067368adc5ae47c467e32ffc0994 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:03 +0000 +Subject: [PATCH 41/49] dt-bindings: crypto: rockchip: add new compatible + +Since driver support new compatible, we need to update the driver bindings. + +Signed-off-by: Corentin Labbe +--- + .../crypto/rockchip,rk3288-crypto.yaml | 79 +++++++++++++++++-- + 1 file changed, 71 insertions(+), 8 deletions(-) + +--- a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml ++++ b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml +@@ -13,6 +13,8 @@ properties: + compatible: + enum: + - rockchip,rk3288-crypto ++ - rockchip,rk3328-crypto ++ - rockchip,rk3399-crypto + + reg: + maxItems: 1 +@@ -21,21 +23,82 @@ properties: + maxItems: 1 + + clocks: ++ minItems: 3 + maxItems: 4 + + clock-names: +- items: +- - const: aclk +- - const: hclk +- - const: sclk +- - const: apb_pclk ++ minItems: 3 ++ maxItems: 4 + + resets: +- maxItems: 1 ++ minItems: 1 ++ maxItems: 3 + + reset-names: +- items: +- - const: crypto-rst ++ minItems: 1 ++ maxItems: 3 ++ ++allOf: ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3288-crypto ++ then: ++ properties: ++ clocks: ++ minItems: 4 ++ clock-names: ++ items: ++ - const: aclk ++ - const: hclk ++ - const: sclk ++ - const: apb_pclk ++ resets: ++ maxItems: 1 ++ reset-names: ++ items: ++ - const: crypto-rst ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3328-crypto ++ then: ++ properties: ++ clocks: ++ maxItems: 3 ++ clock-names: ++ items: ++ - const: hclk_master ++ - const: hclk_slave ++ - const: sclk ++ resets: ++ maxItems: 1 ++ reset-names: ++ items: ++ - const: crypto-rst ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: rockchip,rk3399-crypto ++ then: ++ properties: ++ clocks: ++ maxItems: 3 ++ clock-names: ++ items: ++ - const: hclk_master ++ - const: hclk_slave ++ - const: sclk ++ resets: ++ minItems: 3 ++ reset-names: ++ items: ++ - const: master ++ - const: slave ++ - const: crypto-rst + + required: + - compatible diff --git a/target/linux/rockchip/patches-6.1/192-clk-rk3399-use-proper-crypto0-name.patch b/target/linux/rockchip/patches-6.1/192-clk-rk3399-use-proper-crypto0-name.patch new file mode 100644 index 000000000..6c2d5eb4c --- /dev/null +++ b/target/linux/rockchip/patches-6.1/192-clk-rk3399-use-proper-crypto0-name.patch @@ -0,0 +1,37 @@ +From b55b62250202a6d95872e367963190aaad6f9f08 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:04 +0000 +Subject: [PATCH 42/49] clk: rk3399: use proper crypto0 name + +RK3399 has 2 crypto instance, named crypto0 and crypto1 in the TRM. +Only reset for crypto1 is correctly named, but crypto0 is not. +Since nobody use them , add a 0 to be consistent with the TRM and crypto1 entries. + +Acked-by: Rob Herring +Signed-off-by: Corentin Labbe +--- + include/dt-bindings/clock/rk3399-cru.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/include/dt-bindings/clock/rk3399-cru.h ++++ b/include/dt-bindings/clock/rk3399-cru.h +@@ -547,8 +547,8 @@ + #define SRST_H_PERILP0 171 + #define SRST_H_PERILP0_NOC 172 + #define SRST_ROM 173 +-#define SRST_CRYPTO_S 174 +-#define SRST_CRYPTO_M 175 ++#define SRST_CRYPTO0_S 174 ++#define SRST_CRYPTO0_M 175 + + /* cru_softrst_con11 */ + #define SRST_P_DCF 176 +@@ -556,7 +556,7 @@ + #define SRST_CM0S 178 + #define SRST_CM0S_DBG 179 + #define SRST_CM0S_PO 180 +-#define SRST_CRYPTO 181 ++#define SRST_CRYPTO0 181 + #define SRST_P_PERILP1_SGRF 182 + #define SRST_P_PERILP1_GRF 183 + #define SRST_CRYPTO1_S 184 diff --git a/target/linux/rockchip/patches-6.1/193-arm64-dts-rockchip-add-rk3328-crypto-node.patch b/target/linux/rockchip/patches-6.1/193-arm64-dts-rockchip-add-rk3328-crypto-node.patch new file mode 100644 index 000000000..ef812d7cd --- /dev/null +++ b/target/linux/rockchip/patches-6.1/193-arm64-dts-rockchip-add-rk3328-crypto-node.patch @@ -0,0 +1,33 @@ +From e39620e4a26f650c72ad5624f27dfe964ccf3e03 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:05 +0000 +Subject: [PATCH 43/49] arm64: dts: rockchip: add rk3328 crypto node + +rk3328 has a crypto IP handled by the rk3288 crypto driver so adds a +node for it. + +Signed-off-by: Corentin Labbe +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -1025,6 +1025,17 @@ + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + }; + ++ crypto: crypto@ff060000 { ++ compatible = "rockchip,rk3328-crypto"; ++ reg = <0x0 0xff060000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_CRYPTO_MST>, <&cru HCLK_CRYPTO_SLV>, ++ <&cru SCLK_CRYPTO>; ++ clock-names = "hclk_master", "hclk_slave", "sclk"; ++ resets = <&cru SRST_CRYPTO>; ++ reset-names = "crypto-rst"; ++ }; ++ + pinctrl: pinctrl { + compatible = "rockchip,rk3328-pinctrl"; + rockchip,grf = <&grf>; diff --git a/target/linux/rockchip/patches-6.1/194-arm64-dts-rockchip-rk3399-add-crypto-node.patch b/target/linux/rockchip/patches-6.1/194-arm64-dts-rockchip-rk3399-add-crypto-node.patch new file mode 100644 index 000000000..c99019093 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/194-arm64-dts-rockchip-rk3399-add-crypto-node.patch @@ -0,0 +1,43 @@ +From e0d5c068d092b0c1a60f706cb18ac71ff4ec5268 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:06 +0000 +Subject: [PATCH 44/49] arm64: dts: rockchip: rk3399: add crypto node + +The rk3399 has a crypto IP handled by the rk3288 crypto driver so adds a +node for it. + +Tested-by Diederik de Haas +Signed-off-by: Corentin Labbe +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -582,6 +582,26 @@ + status = "disabled"; + }; + ++ crypto0: crypto@ff8b0000 { ++ compatible = "rockchip,rk3399-crypto"; ++ reg = <0x0 0xff8b0000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_M_CRYPTO0>, <&cru HCLK_S_CRYPTO0>, <&cru SCLK_CRYPTO0>; ++ clock-names = "hclk_master", "hclk_slave", "sclk"; ++ resets = <&cru SRST_CRYPTO0>, <&cru SRST_CRYPTO0_S>, <&cru SRST_CRYPTO0_M>; ++ reset-names = "master", "slave", "crypto-rst"; ++ }; ++ ++ crypto1: crypto@ff8b8000 { ++ compatible = "rockchip,rk3399-crypto"; ++ reg = <0x0 0xff8b8000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_M_CRYPTO1>, <&cru HCLK_S_CRYPTO1>, <&cru SCLK_CRYPTO1>; ++ clock-names = "hclk_master", "hclk_slave", "sclk"; ++ resets = <&cru SRST_CRYPTO1>, <&cru SRST_CRYPTO1_S>, <&cru SRST_CRYPTO1_M>; ++ reset-names = "master", "slave", "crypto-rst"; ++ }; ++ + i2c1: i2c@ff110000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x0 0xff110000 0x0 0x1000>; diff --git a/target/linux/rockchip/patches-6.1/195-crypto-rockchip-store-crypto_info-in-request-context.patch b/target/linux/rockchip/patches-6.1/195-crypto-rockchip-store-crypto_info-in-request-context.patch new file mode 100644 index 000000000..d8c4d173e --- /dev/null +++ b/target/linux/rockchip/patches-6.1/195-crypto-rockchip-store-crypto_info-in-request-context.patch @@ -0,0 +1,124 @@ +From 61900b43baea9ed606aacb824b761feca7511eaa Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:07 +0000 +Subject: [PATCH 45/49] crypto: rockchip: store crypto_info in request context + +The crypto_info to use must be stored in the request context. +This will help when 2 crypto_info will be available on rk3399. + +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.h | 2 ++ + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 14 ++++++-------- + drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 6 ++++-- + 3 files changed, 12 insertions(+), 10 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -215,6 +215,7 @@ struct rk_ahash_ctx { + + /* the private variable of hash for fallback */ + struct rk_ahash_rctx { ++ struct rk_crypto_info *dev; + struct ahash_request fallback_req; + u32 mode; + int nrsg; +@@ -231,6 +232,7 @@ struct rk_cipher_ctx { + }; + + struct rk_cipher_rctx { ++ struct rk_crypto_info *dev; + u8 backup_iv[AES_BLOCK_SIZE]; + u32 mode; + struct skcipher_request fallback_req; // keep at the end +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -200,6 +200,7 @@ static int rk_ahash_export(struct ahash_ + + static int rk_ahash_digest(struct ahash_request *req) + { ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(req); + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct rk_crypto_info *dev = tctx->dev; + +@@ -209,6 +210,8 @@ static int rk_ahash_digest(struct ahash_ + if (!req->nbytes) + return zero_message_process(req); + ++ rctx->dev = dev; ++ + return crypto_transfer_hash_request_to_engine(dev->engine, req); + } + +@@ -223,10 +226,8 @@ static void crypto_ahash_dma_start(struc + static int rk_hash_prepare(struct crypto_engine *engine, void *breq) + { + struct ahash_request *areq = container_of(breq, struct ahash_request, base); +- struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); +- struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); +- struct rk_crypto_info *rkc = tctx->dev; ++ struct rk_crypto_info *rkc = rctx->dev; + int ret; + + ret = dma_map_sg(rkc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); +@@ -241,10 +242,8 @@ static int rk_hash_prepare(struct crypto + static int rk_hash_unprepare(struct crypto_engine *engine, void *breq) + { + struct ahash_request *areq = container_of(breq, struct ahash_request, base); +- struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); +- struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); +- struct rk_crypto_info *rkc = tctx->dev; ++ struct rk_crypto_info *rkc = rctx->dev; + + dma_unmap_sg(rkc->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE); + return 0; +@@ -255,11 +254,10 @@ static int rk_hash_run(struct crypto_eng + struct ahash_request *areq = container_of(breq, struct ahash_request, base); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); +- struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); + struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); + struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + struct scatterlist *sg = areq->src; +- struct rk_crypto_info *rkc = tctx->dev; ++ struct rk_crypto_info *rkc = rctx->dev; + int err = 0; + int i; + u32 v; +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -86,12 +86,15 @@ static int rk_cipher_handle_req(struct s + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *tctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *rkc = tctx->dev; + struct crypto_engine *engine = rkc->engine; + + if (rk_cipher_need_fallback(req)) + return rk_cipher_fallback(req); + ++ rctx->dev = rkc; ++ + return crypto_transfer_skcipher_request_to_engine(engine, req); + } + +@@ -290,7 +293,6 @@ static int rk_cipher_run(struct crypto_e + { + struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); + struct scatterlist *sgs, *sgd; + int err = 0; +@@ -303,7 +305,7 @@ static int rk_cipher_run(struct crypto_e + unsigned int todo; + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); + struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); +- struct rk_crypto_info *rkc = ctx->dev; ++ struct rk_crypto_info *rkc = rctx->dev; + + algt->stat_req++; + diff --git a/target/linux/rockchip/patches-6.1/196-crypto-rockchip-Check-for-clocks-numbers-and-their-f.patch b/target/linux/rockchip/patches-6.1/196-crypto-rockchip-Check-for-clocks-numbers-and-their-f.patch new file mode 100644 index 000000000..5cebb131e --- /dev/null +++ b/target/linux/rockchip/patches-6.1/196-crypto-rockchip-Check-for-clocks-numbers-and-their-f.patch @@ -0,0 +1,165 @@ +From 5301685e031d21df2b2a2d5959805f3292f3d481 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:08 +0000 +Subject: [PATCH 46/49] crypto: rockchip: Check for clocks numbers and their + frequencies + +Add the number of clocks needed for each compatible. +Rockchip's datasheet give maximum frequencies for some clocks, so add +checks for verifying they are within limits. Let's start with rk3288 for +clock frequency check, other will came later. + +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 75 +++++++++++++++++++++---- + drivers/crypto/rockchip/rk3288_crypto.h | 16 +++++- + 2 files changed, 79 insertions(+), 12 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -14,10 +14,58 @@ + #include + #include + #include ++#include + #include + #include + #include + ++static const struct rk_variant rk3288_variant = { ++ .num_clks = 4, ++ .rkclks = { ++ { "sclk", 150000000}, ++ } ++}; ++ ++static const struct rk_variant rk3328_variant = { ++ .num_clks = 3, ++}; ++ ++static int rk_crypto_get_clks(struct rk_crypto_info *dev) ++{ ++ int i, j, err; ++ unsigned long cr; ++ ++ dev->num_clks = devm_clk_bulk_get_all(dev->dev, &dev->clks); ++ if (dev->num_clks < dev->variant->num_clks) { ++ dev_err(dev->dev, "Missing clocks, got %d instead of %d\n", ++ dev->num_clks, dev->variant->num_clks); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < dev->num_clks; i++) { ++ cr = clk_get_rate(dev->clks[i].clk); ++ for (j = 0; j < ARRAY_SIZE(dev->variant->rkclks); j++) { ++ if (dev->variant->rkclks[j].max == 0) ++ continue; ++ if (strcmp(dev->variant->rkclks[j].name, dev->clks[i].id)) ++ continue; ++ if (cr > dev->variant->rkclks[j].max) { ++ err = clk_set_rate(dev->clks[i].clk, ++ dev->variant->rkclks[j].max); ++ if (err) ++ dev_err(dev->dev, "Fail downclocking %s from %lu to %lu\n", ++ dev->variant->rkclks[j].name, cr, ++ dev->variant->rkclks[j].max); ++ else ++ dev_info(dev->dev, "Downclocking %s from %lu to %lu\n", ++ dev->variant->rkclks[j].name, cr, ++ dev->variant->rkclks[j].max); ++ } ++ } ++ } ++ return 0; ++} ++ + static int rk_crypto_enable_clk(struct rk_crypto_info *dev) + { + int err; +@@ -201,8 +249,12 @@ static void rk_crypto_unregister(void) + } + + static const struct of_device_id crypto_of_id_table[] = { +- { .compatible = "rockchip,rk3288-crypto" }, +- { .compatible = "rockchip,rk3328-crypto" }, ++ { .compatible = "rockchip,rk3288-crypto", ++ .data = &rk3288_variant, ++ }, ++ { .compatible = "rockchip,rk3328-crypto", ++ .data = &rk3328_variant, ++ }, + {} + }; + MODULE_DEVICE_TABLE(of, crypto_of_id_table); +@@ -220,6 +272,15 @@ static int rk_crypto_probe(struct platfo + goto err_crypto; + } + ++ crypto_info->dev = &pdev->dev; ++ platform_set_drvdata(pdev, crypto_info); ++ ++ crypto_info->variant = of_device_get_match_data(&pdev->dev); ++ if (!crypto_info->variant) { ++ dev_err(&pdev->dev, "Missing variant\n"); ++ return -EINVAL; ++ } ++ + crypto_info->rst = devm_reset_control_get(dev, "crypto-rst"); + if (IS_ERR(crypto_info->rst)) { + err = PTR_ERR(crypto_info->rst); +@@ -236,12 +297,9 @@ static int rk_crypto_probe(struct platfo + goto err_crypto; + } + +- crypto_info->num_clks = devm_clk_bulk_get_all(&pdev->dev, +- &crypto_info->clks); +- if (crypto_info->num_clks < 3) { +- err = -EINVAL; ++ err = rk_crypto_get_clks(crypto_info); ++ if (err) + goto err_crypto; +- } + + crypto_info->irq = platform_get_irq(pdev, 0); + if (crypto_info->irq < 0) { +@@ -259,9 +317,6 @@ static int rk_crypto_probe(struct platfo + goto err_crypto; + } + +- crypto_info->dev = &pdev->dev; +- platform_set_drvdata(pdev, crypto_info); +- + crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true); + crypto_engine_start(crypto_info->engine); + init_completion(&crypto_info->complete); +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -188,14 +188,26 @@ + #define CRYPTO_WRITE(dev, offset, val) \ + writel_relaxed((val), ((dev)->reg + (offset))) + ++#define RK_MAX_CLKS 4 ++ ++struct rk_clks { ++ const char *name; ++ unsigned long max; ++}; ++ ++struct rk_variant { ++ int num_clks; ++ struct rk_clks rkclks[RK_MAX_CLKS]; ++}; ++ + struct rk_crypto_info { + struct device *dev; + struct clk_bulk_data *clks; +- int num_clks; ++ int num_clks; + struct reset_control *rst; + void __iomem *reg; + int irq; +- ++ const struct rk_variant *variant; + struct crypto_engine *engine; + struct completion complete; + int status; diff --git a/target/linux/rockchip/patches-6.1/197-crypto-rockchip-rk_ahash_reg_init-use-crypto_info-fr.patch b/target/linux/rockchip/patches-6.1/197-crypto-rockchip-rk_ahash_reg_init-use-crypto_info-fr.patch new file mode 100644 index 000000000..bb6b4f256 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/197-crypto-rockchip-rk_ahash_reg_init-use-crypto_info-fr.patch @@ -0,0 +1,40 @@ +From 566cce03ee27f1288a4a029f5c7d437cc2e11eac Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:09 +0000 +Subject: [PATCH 47/49] crypto: rockchip: rk_ahash_reg_init use crypto_info + from parameter + +rk_ahash_reg_init() use crypto_info from TFM context, since we will +remove it, let's take if from parameters. + +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -78,12 +78,10 @@ static int zero_message_process(struct a + return 0; + } + +-static void rk_ahash_reg_init(struct ahash_request *req) ++static void rk_ahash_reg_init(struct ahash_request *req, ++ struct rk_crypto_info *dev) + { + struct rk_ahash_rctx *rctx = ahash_request_ctx(req); +- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); +- struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); +- struct rk_crypto_info *dev = tctx->dev; + int reg_status; + + reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) | +@@ -281,7 +279,7 @@ static int rk_hash_run(struct crypto_eng + goto theend; + } + +- rk_ahash_reg_init(areq); ++ rk_ahash_reg_init(areq, rkc); + + while (sg) { + reinit_completion(&rkc->complete); diff --git a/target/linux/rockchip/patches-6.1/198-crypto-rockchip-permit-to-have-more-than-one-reset.patch b/target/linux/rockchip/patches-6.1/198-crypto-rockchip-permit-to-have-more-than-one-reset.patch new file mode 100644 index 000000000..a56241149 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/198-crypto-rockchip-permit-to-have-more-than-one-reset.patch @@ -0,0 +1,24 @@ +From 5a73176384bd62a9ac4300805d243592e93fe5d4 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:10 +0000 +Subject: [PATCH 48/49] crypto: rockchip: permit to have more than one reset + +The RK3399 has 3 resets, so the driver to handle multiple resets. +This is done by using devm_reset_control_array_get_exclusive(). + +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -281,7 +281,7 @@ static int rk_crypto_probe(struct platfo + return -EINVAL; + } + +- crypto_info->rst = devm_reset_control_get(dev, "crypto-rst"); ++ crypto_info->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(crypto_info->rst)) { + err = PTR_ERR(crypto_info->rst); + goto err_crypto; diff --git a/target/linux/rockchip/patches-6.1/199-crypto-rockchip-Add-support-for-RK3399.patch b/target/linux/rockchip/patches-6.1/199-crypto-rockchip-Add-support-for-RK3399.patch new file mode 100644 index 000000000..7c5902ff5 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/199-crypto-rockchip-Add-support-for-RK3399.patch @@ -0,0 +1,464 @@ +From 5a0b753155b5d3cbba77ecd6a017e6f3733e344e Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 07:55:11 +0000 +Subject: [PATCH 49/49] crypto: rockchip: Add support for RK3399 + +The RK3399 has 2 rk3288 compatible crypto device named crypto0 and +crypto1. The only difference is lack of RSA in crypto1. + +We need to add driver support for 2 parallel instance as only one need +to register crypto algorithms. +Then the driver will round robin each request on each device. + +For avoiding complexity (device bringup after a TFM is created), PM is +modified to be handled per request. +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/rk3288_crypto.c | 92 +++++++++++++++---- + drivers/crypto/rockchip/rk3288_crypto.h | 25 +++-- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 37 ++++---- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 37 ++++---- + 4 files changed, 123 insertions(+), 68 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -19,6 +19,23 @@ + #include + #include + ++static struct rockchip_ip rocklist = { ++ .dev_list = LIST_HEAD_INIT(rocklist.dev_list), ++ .lock = __SPIN_LOCK_UNLOCKED(rocklist.lock), ++}; ++ ++struct rk_crypto_info *get_rk_crypto(void) ++{ ++ struct rk_crypto_info *first; ++ ++ spin_lock(&rocklist.lock); ++ first = list_first_entry_or_null(&rocklist.dev_list, ++ struct rk_crypto_info, list); ++ list_rotate_left(&rocklist.dev_list); ++ spin_unlock(&rocklist.lock); ++ return first; ++} ++ + static const struct rk_variant rk3288_variant = { + .num_clks = 4, + .rkclks = { +@@ -30,6 +47,10 @@ static const struct rk_variant rk3328_va + .num_clks = 3, + }; + ++static const struct rk_variant rk3399_variant = { ++ .num_clks = 3, ++}; ++ + static int rk_crypto_get_clks(struct rk_crypto_info *dev) + { + int i, j, err; +@@ -83,8 +104,8 @@ static void rk_crypto_disable_clk(struct + } + + /* +- * Power management strategy: The device is suspended unless a TFM exists for +- * one of the algorithms proposed by this driver. ++ * Power management strategy: The device is suspended until a request ++ * is handled. For avoiding suspend/resume yoyo, the autosuspend is set to 2s. + */ + static int rk_crypto_pm_suspend(struct device *dev) + { +@@ -166,8 +187,17 @@ static struct rk_crypto_tmp *rk_cipher_a + #ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG + static int rk_crypto_debugfs_show(struct seq_file *seq, void *v) + { ++ struct rk_crypto_info *dd; + unsigned int i; + ++ spin_lock(&rocklist.lock); ++ list_for_each_entry(dd, &rocklist.dev_list, list) { ++ seq_printf(seq, "%s %s requests: %lu\n", ++ dev_driver_string(dd->dev), dev_name(dd->dev), ++ dd->nreq); ++ } ++ spin_unlock(&rocklist.lock); ++ + for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) { + if (!rk_cipher_algs[i]->dev) + continue; +@@ -198,6 +228,18 @@ static int rk_crypto_debugfs_show(struct + DEFINE_SHOW_ATTRIBUTE(rk_crypto_debugfs); + #endif + ++static void register_debugfs(struct rk_crypto_info *crypto_info) ++{ ++#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG ++ /* Ignore error of debugfs */ ++ rocklist.dbgfs_dir = debugfs_create_dir("rk3288_crypto", NULL); ++ rocklist.dbgfs_stats = debugfs_create_file("stats", 0444, ++ rocklist.dbgfs_dir, ++ &rocklist, ++ &rk_crypto_debugfs_fops); ++#endif ++} ++ + static int rk_crypto_register(struct rk_crypto_info *crypto_info) + { + unsigned int i, k; +@@ -255,6 +297,9 @@ static const struct of_device_id crypto_ + { .compatible = "rockchip,rk3328-crypto", + .data = &rk3328_variant, + }, ++ { .compatible = "rockchip,rk3399-crypto", ++ .data = &rk3399_variant, ++ }, + {} + }; + MODULE_DEVICE_TABLE(of, crypto_of_id_table); +@@ -262,7 +307,7 @@ MODULE_DEVICE_TABLE(of, crypto_of_id_tab + static int rk_crypto_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- struct rk_crypto_info *crypto_info; ++ struct rk_crypto_info *crypto_info, *first; + int err = 0; + + crypto_info = devm_kzalloc(&pdev->dev, +@@ -325,22 +370,22 @@ static int rk_crypto_probe(struct platfo + if (err) + goto err_pm; + +- err = rk_crypto_register(crypto_info); +- if (err) { +- dev_err(dev, "err in register alg"); +- goto err_register_alg; +- } ++ spin_lock(&rocklist.lock); ++ first = list_first_entry_or_null(&rocklist.dev_list, ++ struct rk_crypto_info, list); ++ list_add_tail(&crypto_info->list, &rocklist.dev_list); ++ spin_unlock(&rocklist.lock); ++ ++ if (!first) { ++ err = rk_crypto_register(crypto_info); ++ if (err) { ++ dev_err(dev, "Fail to register crypto algorithms"); ++ goto err_register_alg; ++ } + +-#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG +- /* Ignore error of debugfs */ +- crypto_info->dbgfs_dir = debugfs_create_dir("rk3288_crypto", NULL); +- crypto_info->dbgfs_stats = debugfs_create_file("stats", 0444, +- crypto_info->dbgfs_dir, +- crypto_info, +- &rk_crypto_debugfs_fops); +-#endif ++ register_debugfs(crypto_info); ++ } + +- dev_info(dev, "Crypto Accelerator successfully registered\n"); + return 0; + + err_register_alg: +@@ -355,11 +400,20 @@ err_crypto: + static int rk_crypto_remove(struct platform_device *pdev) + { + struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev); ++ struct rk_crypto_info *first; ++ ++ spin_lock_bh(&rocklist.lock); ++ list_del(&crypto_tmp->list); ++ first = list_first_entry_or_null(&rocklist.dev_list, ++ struct rk_crypto_info, list); ++ spin_unlock_bh(&rocklist.lock); + ++ if (!first) { + #ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG +- debugfs_remove_recursive(crypto_tmp->dbgfs_dir); ++ debugfs_remove_recursive(rocklist.dbgfs_dir); + #endif +- rk_crypto_unregister(); ++ rk_crypto_unregister(); ++ } + rk_crypto_pm_exit(crypto_tmp); + crypto_engine_exit(crypto_tmp->engine); + return 0; +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -190,6 +190,20 @@ + + #define RK_MAX_CLKS 4 + ++/* ++ * struct rockchip_ip - struct for managing a list of RK crypto instance ++ * @dev_list: Used for doing a list of rk_crypto_info ++ * @lock: Control access to dev_list ++ * @dbgfs_dir: Debugfs dentry for statistic directory ++ * @dbgfs_stats: Debugfs dentry for statistic counters ++ */ ++struct rockchip_ip { ++ struct list_head dev_list; ++ spinlock_t lock; /* Control access to dev_list */ ++ struct dentry *dbgfs_dir; ++ struct dentry *dbgfs_stats; ++}; ++ + struct rk_clks { + const char *name; + unsigned long max; +@@ -201,6 +215,7 @@ struct rk_variant { + }; + + struct rk_crypto_info { ++ struct list_head list; + struct device *dev; + struct clk_bulk_data *clks; + int num_clks; +@@ -208,19 +223,15 @@ struct rk_crypto_info { + void __iomem *reg; + int irq; + const struct rk_variant *variant; ++ unsigned long nreq; + struct crypto_engine *engine; + struct completion complete; + int status; +-#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG +- struct dentry *dbgfs_dir; +- struct dentry *dbgfs_stats; +-#endif + }; + + /* the private variable of hash */ + struct rk_ahash_ctx { + struct crypto_engine_ctx enginectx; +- struct rk_crypto_info *dev; + /* for fallback */ + struct crypto_ahash *fallback_tfm; + }; +@@ -236,7 +247,6 @@ struct rk_ahash_rctx { + /* the private variable of cipher */ + struct rk_cipher_ctx { + struct crypto_engine_ctx enginectx; +- struct rk_crypto_info *dev; + unsigned int keylen; + u8 key[AES_MAX_KEY_SIZE]; + u8 iv[AES_BLOCK_SIZE]; +@@ -252,7 +262,7 @@ struct rk_cipher_rctx { + + struct rk_crypto_tmp { + u32 type; +- struct rk_crypto_info *dev; ++ struct rk_crypto_info *dev; + union { + struct skcipher_alg skcipher; + struct ahash_alg hash; +@@ -276,4 +286,5 @@ extern struct rk_crypto_tmp rk_ahash_sha + extern struct rk_crypto_tmp rk_ahash_sha256; + extern struct rk_crypto_tmp rk_ahash_md5; + ++struct rk_crypto_info *get_rk_crypto(void); + #endif +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -199,8 +199,8 @@ static int rk_ahash_export(struct ahash_ + static int rk_ahash_digest(struct ahash_request *req) + { + struct rk_ahash_rctx *rctx = ahash_request_ctx(req); +- struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm); +- struct rk_crypto_info *dev = tctx->dev; ++ struct rk_crypto_info *dev; ++ struct crypto_engine *engine; + + if (rk_ahash_need_fallback(req)) + return rk_ahash_digest_fb(req); +@@ -208,9 +208,12 @@ static int rk_ahash_digest(struct ahash_ + if (!req->nbytes) + return zero_message_process(req); + ++ dev = get_rk_crypto(); ++ + rctx->dev = dev; ++ engine = dev->engine; + +- return crypto_transfer_hash_request_to_engine(dev->engine, req); ++ return crypto_transfer_hash_request_to_engine(engine, req); + } + + static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg) +@@ -260,9 +263,14 @@ static int rk_hash_run(struct crypto_eng + int i; + u32 v; + ++ err = pm_runtime_resume_and_get(rkc->dev); ++ if (err) ++ return err; ++ + rctx->mode = 0; + + algt->stat_req++; ++ rkc->nreq++; + + switch (crypto_ahash_digestsize(tfm)) { + case SHA1_DIGEST_SIZE: +@@ -313,6 +321,8 @@ static int rk_hash_run(struct crypto_eng + } + + theend: ++ pm_runtime_put_autosuspend(rkc->dev); ++ + local_bh_disable(); + crypto_finalize_hash_request(engine, breq, err); + local_bh_enable(); +@@ -323,21 +333,15 @@ theend: + static int rk_cra_hash_init(struct crypto_tfm *tfm) + { + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); +- struct rk_crypto_tmp *algt; +- struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg); +- + const char *alg_name = crypto_tfm_alg_name(tfm); +- int err; +- +- algt = container_of(alg, struct rk_crypto_tmp, alg.hash); +- +- tctx->dev = algt->dev; ++ struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg); ++ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + + /* for fallback */ + tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(tctx->fallback_tfm)) { +- dev_err(tctx->dev->dev, "Could not load fallback driver.\n"); ++ dev_err(algt->dev->dev, "Could not load fallback driver.\n"); + return PTR_ERR(tctx->fallback_tfm); + } + +@@ -349,15 +353,7 @@ static int rk_cra_hash_init(struct crypt + tctx->enginectx.op.prepare_request = rk_hash_prepare; + tctx->enginectx.op.unprepare_request = rk_hash_unprepare; + +- err = pm_runtime_resume_and_get(tctx->dev->dev); +- if (err < 0) +- goto error_pm; +- + return 0; +-error_pm: +- crypto_free_ahash(tctx->fallback_tfm); +- +- return err; + } + + static void rk_cra_hash_exit(struct crypto_tfm *tfm) +@@ -365,7 +361,6 @@ static void rk_cra_hash_exit(struct cryp + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + + crypto_free_ahash(tctx->fallback_tfm); +- pm_runtime_put_autosuspend(tctx->dev->dev); + } + + struct rk_crypto_tmp rk_ahash_sha1 = { +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -17,11 +17,11 @@ + static int rk_cipher_need_fallback(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- unsigned int bs = crypto_skcipher_blocksize(tfm); + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); + struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + struct scatterlist *sgs, *sgd; + unsigned int stodo, dtodo, len; ++ unsigned int bs = crypto_skcipher_blocksize(tfm); + + if (!req->cryptlen) + return true; +@@ -84,15 +84,16 @@ static int rk_cipher_fallback(struct skc + + static int rk_cipher_handle_req(struct skcipher_request *req) + { +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_ctx *tctx = crypto_skcipher_ctx(tfm); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_crypto_info *rkc = tctx->dev; +- struct crypto_engine *engine = rkc->engine; ++ struct rk_crypto_info *rkc; ++ struct crypto_engine *engine; + + if (rk_cipher_need_fallback(req)) + return rk_cipher_fallback(req); + ++ rkc = get_rk_crypto(); ++ ++ engine = rkc->engine; + rctx->dev = rkc; + + return crypto_transfer_skcipher_request_to_engine(engine, req); +@@ -307,7 +308,12 @@ static int rk_cipher_run(struct crypto_e + struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + struct rk_crypto_info *rkc = rctx->dev; + ++ err = pm_runtime_resume_and_get(rkc->dev); ++ if (err) ++ return err; ++ + algt->stat_req++; ++ rkc->nreq++; + + ivsize = crypto_skcipher_ivsize(tfm); + if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) { +@@ -401,6 +407,8 @@ static int rk_cipher_run(struct crypto_e + } + + theend: ++ pm_runtime_put_autosuspend(rkc->dev); ++ + local_bh_disable(); + crypto_finalize_skcipher_request(engine, areq, err); + local_bh_enable(); +@@ -420,18 +428,13 @@ theend_iv: + static int rk_cipher_tfm_init(struct crypto_skcipher *tfm) + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- struct skcipher_alg *alg = crypto_skcipher_alg(tfm); + const char *name = crypto_tfm_alg_name(&tfm->base); +- struct rk_crypto_tmp *algt; +- int err; +- +- algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); +- +- ctx->dev = algt->dev; ++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + + ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(ctx->fallback_tfm)) { +- dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n", ++ dev_err(algt->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n", + name, PTR_ERR(ctx->fallback_tfm)); + return PTR_ERR(ctx->fallback_tfm); + } +@@ -441,14 +444,7 @@ static int rk_cipher_tfm_init(struct cry + + ctx->enginectx.op.do_one_request = rk_cipher_run; + +- err = pm_runtime_resume_and_get(ctx->dev->dev); +- if (err < 0) +- goto error_pm; +- + return 0; +-error_pm: +- crypto_free_skcipher(ctx->fallback_tfm); +- return err; + } + + static void rk_cipher_tfm_exit(struct crypto_skcipher *tfm) +@@ -457,7 +453,6 @@ static void rk_cipher_tfm_exit(struct cr + + memzero_explicit(ctx->key, ctx->keylen); + crypto_free_skcipher(ctx->fallback_tfm); +- pm_runtime_put_autosuspend(ctx->dev->dev); + } + + struct rk_crypto_tmp rk_ecb_aes_alg = { diff --git a/target/linux/rockchip/patches-6.1/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch b/target/linux/rockchip/patches-6.1/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch new file mode 100644 index 000000000..013e14981 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch @@ -0,0 +1,22 @@ +From 3b7eb946b1d640d684a921e53e1e50985ab7eb89 Mon Sep 17 00:00:00 2001 +From: QiuSimons <45143996+QiuSimons@users.noreply.github.com> +Date: Tue, 4 Aug 2020 20:17:53 +0800 +Subject: [PATCH] rockchip: rk3328: add i2c0 controller for nanopi r2s + +--- + arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 4 ++++ + 1 files changed, 4 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +@@ -173,6 +173,10 @@ + }; + }; + ++&i2c0 { ++ status = "okay"; ++}; ++ + &i2c1 { + status = "okay"; + diff --git a/target/linux/rockchip/patches-6.1/202-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus.patch b/target/linux/rockchip/patches-6.1/202-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus.patch new file mode 100644 index 000000000..e1f441ba3 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/202-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus.patch @@ -0,0 +1,52 @@ +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -11,6 +11,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-od + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts +@@ -0,0 +1,39 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++#include "rk3328-nanopi-r2s.dts" ++ ++/ { ++ model = "Xunlong Orange Pi R1 Plus"; ++ compatible = "xunlong,orangepi-r1-plus", "rockchip,rk3328"; ++}; ++ ++&lan_led { ++ label = "orangepi-r1-plus:green:lan"; ++}; ++ ++&spi0 { ++ max-freq = <48000000>; ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <10000000>; ++ }; ++}; ++ ++&sys_led { ++ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>; ++ label = "orangepi-r1-plus:red:sys"; ++}; ++ ++&sys_led_pin { ++ rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&wan_led { ++ label = "orangepi-r1-plus:green:wan"; ++}; diff --git a/target/linux/rockchip/patches-6.1/203-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch b/target/linux/rockchip/patches-6.1/203-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch new file mode 100644 index 000000000..f6547ceef --- /dev/null +++ b/target/linux/rockchip/patches-6.1/203-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch @@ -0,0 +1,79 @@ +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1 + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +@@ -0,0 +1,66 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2016 Xunlong Software. Co., Ltd. ++ * (http://www.orangepi.org) ++ * ++ * Copyright (c) 2021 Tianling Shen ++ */ ++ ++#include "rk3328-orangepi-r1-plus.dts" ++ ++/ { ++ model = "Xunlong Orange Pi R1 Plus LTS"; ++ compatible = "xunlong,orangepi-r1-plus-lts", "rockchip,rk3328"; ++}; ++ ++&dmc_opp_table { ++ opp-798000000 { ++ status = "disabled"; ++ }; ++ opp-840000000 { ++ status = "disabled"; ++ }; ++ opp-924000000 { ++ status = "disabled"; ++ }; ++ opp-1056000000 { ++ status = "disabled"; ++ }; ++}; ++ ++&gmac2io { ++ phy-handle = <&yt8531c>; ++ tx_delay = <0x19>; ++ rx_delay = <0x05>; ++ ++ mdio { ++ /delete-node/ ethernet-phy@1; ++ ++ yt8531c: ethernet-phy@0 { ++ compatible = "ethernet-phy-id4f51.e91b", ++ "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ pinctrl-0 = <ð_phy_reset_pin>; ++ pinctrl-names = "default"; ++ reset-assert-us = <15000>; ++ reset-deassert-us = <50000>; ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&lan_led { ++ label = "orangepi-r1-plus-lts:green:lan"; ++}; ++ ++&rtl8153 { ++ realtek,led-data = <0x78>; ++}; ++ ++&sys_led { ++ label = "orangepi-r1-plus-lts:red:sys"; ++}; ++ ++&wan_led { ++ label = "orangepi-r1-plus-lts:green:wan"; ++}; diff --git a/target/linux/rockchip/patches-6.1/204-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch b/target/linux/rockchip/patches-6.1/204-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch new file mode 100644 index 000000000..3cfe4d708 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/204-rockchip-rk3328-Add-support-for-FriendlyARM-NanoPi-R.patch @@ -0,0 +1,64 @@ +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a9 + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c.dts +@@ -0,0 +1,51 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2021 FriendlyElec Computer Tech. Co., Ltd. ++ * (http://www.friendlyarm.com) ++ * ++ * Copyright (c) 2021 Tianling Shen ++ */ ++ ++/dts-v1/; ++ ++#include "rk3328-nanopi-r2s.dts" ++ ++/ { ++ model = "FriendlyElec NanoPi R2C"; ++ compatible = "friendlyarm,nanopi-r2c", "rockchip,rk3328"; ++}; ++ ++&gmac2io { ++ phy-handle = <&yt8521s>; ++ ++ mdio { ++ /delete-node/ ethernet-phy@1; ++ ++ yt8521s: ethernet-phy@3 { ++ compatible = "ethernet-phy-id0000.011a", ++ "ethernet-phy-ieee802.3-c22"; ++ reg = <3>; ++ pinctrl-0 = <ð_phy_reset_pin>; ++ pinctrl-names = "default"; ++ reset-assert-us = <10000>; ++ reset-deassert-us = <50000>; ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&lan_led { ++ label = "nanopi-r2c:green:lan"; ++}; ++ ++&rtl8153 { ++ realtek,led-data = <0x78>; ++}; ++ ++&sys_led { ++ label = "nanopi-r2c:red:sys"; ++}; ++ ++&wan_led { ++ label = "nanopi-r2c:green:wan"; ++}; diff --git a/target/linux/rockchip/patches-6.1/205-rockchip-rk3328-add-support-for-FriendlyARM-NanoPi-Neo3.patch b/target/linux/rockchip/patches-6.1/205-rockchip-rk3328-add-support-for-FriendlyARM-NanoPi-Neo3.patch new file mode 100644 index 000000000..620e28a41 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/205-rockchip-rk3328-add-support-for-FriendlyARM-NanoPi-Neo3.patch @@ -0,0 +1,442 @@ +From 0f989817a4c1d2c3d196d550ff05cda98bc91324 Mon Sep 17 00:00:00 2001 +From: Julian Pidancet +Date: Sun, 23 Jan 2022 16:34:08 +0100 +Subject: [PATCH v2] rockchip: rk3328: add support for FriendlyARM NanoPi NEO3 + +This patch adds support for FriendlyARM NanoPi NEO3 + +Soc: RockChip RK3328 +RAM: 1GB/2GB DDR4 +LAN: 10/100/1000M Ethernet with unique MAC +USB Host: 1x USB3.0 Type A and 2x USB2.0 on 2.54mm pin header +MicroSD: x 1 for system boot and storage +LED: Power LED x 1, System LED x 1 +Key: User Button x 1 +Fan: 2 Pin JST ZH 1.5mm Connector for 5V Fan +GPIO: 26 pin-header, include I2C, UART, SPI, I2S, GPIO +Power: 5V/1A, via Type-C or GPIO + +Signed-off-by: Julian Pidancet +--- + +This is another shot at previous work submitted by Marty Jones + (https://lore.kernel.org/linux-arm-kernel/20201228152836.02795e09.mj8263788@gmail.com/), +which is now a year old. + +v2: Following up on Robin Murphy's comments, the NEO3 DTS is now +standalone and no longer includes the nanopi R2S one. The lan_led and +wan_len nodes have been removed, and the sys_led node has been renamed +to status_led in accordance with the board schematics. + + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../boot/dts/rockchip/rk3328-nanopi-neo3.dts | 396 ++++++++++++++++++ + 2 files changed, 397 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3.dts + +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1 + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-neo3.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3.dts +@@ -0,0 +1,394 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 David Bauer ++ * Copyright (c) 2022 Julian Pidancet ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include "rk3328.dtsi" ++ ++/ { ++ model = "FriendlyElec NanoPi NEO3"; ++ compatible = "friendlyarm,nanopi-neo3", "rockchip,rk3328"; ++ ++ aliases { ++ led-boot = &status_led; ++ led-failsafe = &status_led; ++ led-running = &status_led; ++ led-upgrade = &status_led; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ gmac_clk: gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ pinctrl-0 = <&reset_button_pin>; ++ pinctrl-names = "default"; ++ ++ reset { ++ label = "reset"; ++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <50>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-0 = <&status_led_pin>; ++ pinctrl-names = "default"; ++ ++ status_led: led-0 { ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ label = "nanopi-neo3:green:status"; ++ }; ++ }; ++ ++ vcc_io_sdio: sdmmcio-regulator { ++ compatible = "regulator-gpio"; ++ enable-active-high; ++ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; ++ pinctrl-0 = <&sdio_vcc_pin>; ++ pinctrl-names = "default"; ++ regulator-name = "vcc_io_sdio"; ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-settling-time-us = <5000>; ++ regulator-type = "voltage"; ++ startup-delay-us = <2000>; ++ states = <1800000 0x1>, ++ <3300000 0x0>; ++ vin-supply = <&vcc_io_33>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&sdmmc0m1_pin>; ++ pinctrl-names = "default"; ++ regulator-name = "vcc_sd"; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io_33>; ++ }; ++ ++ vdd_5v: vdd-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "vdd_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_rtl8153: vcc-rtl8153-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rtl8153_en_drv>; ++ regulator-always-on; ++ regulator-name = "vcc_rtl8153"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&display_subsystem { ++ status = "disabled"; ++}; ++ ++&gmac2io { ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; ++ clock_in_out = "input"; ++ phy-handle = <&rtl8211e>; ++ phy-mode = "rgmii"; ++ phy-supply = <&vcc_io_33>; ++ pinctrl-0 = <&rgmiim1_pins>; ++ pinctrl-names = "default"; ++ rx_delay = <0x18>; ++ snps,aal; ++ tx_delay = <0x24>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rtl8211e: ethernet-phy@1 { ++ reg = <1>; ++ pinctrl-0 = <ð_phy_reset_pin>; ++ pinctrl-names = "default"; ++ reset-assert-us = <10000>; ++ reset-deassert-us = <50000>; ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: pmic@18 { ++ compatible = "rockchip,rk805"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-0 = <&pmic_int_l>; ++ pinctrl-names = "default"; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vdd_5v>; ++ vcc2-supply = <&vdd_5v>; ++ vcc3-supply = <&vdd_5v>; ++ vcc4-supply = <&vdd_5v>; ++ vcc5-supply = <&vcc_io_33>; ++ vcc6-supply = <&vdd_5v>; ++ ++ regulators { ++ vdd_log: DCDC_REG1 { ++ regulator-name = "vdd_log"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-ramp-delay = <12500>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-ramp-delay = <12500>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io_33: DCDC_REG4 { ++ regulator-name = "vcc_io_33"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&io_domains { ++ pmuio-supply = <&vcc_io_33>; ++ vccio1-supply = <&vcc_io_33>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io_sdio>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io_33>; ++ vccio6-supply = <&vcc_io_33>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ button { ++ reset_button_pin: reset-button-pin { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ ethernet-phy { ++ eth_phy_reset_pin: eth-phy-reset-pin { ++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ leds { ++ status_led_pin: status-led-pin { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sd { ++ sdio_vcc_pin: sdio-vcc-pin { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ usb { ++ rtl8153_en_drv: rtl8153-en-drv { ++ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pwm2 { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; ++ pinctrl-names = "default"; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vcc_io_sdio>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ status = "okay"; ++ dr_mode = "host"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ dr_mode = "host"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ usb-eth@2 { ++ compatible = "realtek,rtl8153"; ++ reg = <2>; ++ ++ realtek,led-data = <0x87>; ++ }; ++}; diff --git a/target/linux/rockchip/patches-6.1/210-rockchip-rk356x-add-support-for-new-boards.patch b/target/linux/rockchip/patches-6.1/210-rockchip-rk356x-add-support-for-new-boards.patch new file mode 100644 index 000000000..e9bc96f1c --- /dev/null +++ b/target/linux/rockchip/patches-6.1/210-rockchip-rk356x-add-support-for-new-boards.patch @@ -0,0 +1,32 @@ +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -79,3 +79,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-so + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-doornet1.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat1.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat1n.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-lubancat2.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-lubancat2n.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-opc-h68k.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -1770,6 +1770,15 @@ usb2phy1_otg: otg-port { + }; + }; + ++ rng: rng@fe388000 { ++ compatible = "rockchip,rk3568-rng"; ++ reg = <0x0 0xfe388000 0x0 0x4000>; ++ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>; ++ clock-names = "trng_clk", "trng_hclk"; ++ resets = <&cru SRST_TRNG_NS>; ++ reset-names = "reset"; ++ }; ++ + pinctrl: pinctrl { + compatible = "rockchip,rk3568-pinctrl"; + rockchip,grf = <&grf>; diff --git a/target/linux/rockchip/patches-6.1/211-rockchip-rk3399-Add-support-for-EmbedFire-DoorNet2.patch b/target/linux/rockchip/patches-6.1/211-rockchip-rk3399-Add-support-for-EmbedFire-DoorNet2.patch new file mode 100644 index 000000000..90a4c0e2d --- /dev/null +++ b/target/linux/rockchip/patches-6.1/211-rockchip-rk3399-Add-support-for-EmbedFire-DoorNet2.patch @@ -0,0 +1,793 @@ +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -55,6 +55,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-ro + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4b.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4b-plus.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4c.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-doornet2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64-v2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-doornet2.dts +@@ -0,0 +1,115 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include "rk3399-doornet2.dtsi" ++ ++/ { ++ model = "EmbedFire DoorNet2"; ++ compatible = "embedfire,doornet2", "rockchip,rk3399"; ++ ++ aliases { ++ led-boot = &sys_led; ++ led-failsafe = &sys_led; ++ led-running = &sys_led; ++ led-upgrade = &sys_led; ++ }; ++ ++ /delete-node/ display-subsystem; ++ ++ gpio-leds { ++ pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; ++ ++ /delete-node/ status; ++ ++ lan_led: led-lan { ++ gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>; ++ label = "green:lan"; ++ }; ++ ++ sys_led: led-sys { ++ gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; ++ label = "red:sys"; ++ default-state = "on"; ++ }; ++ ++ wan_led: led-wan { ++ gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; ++ label = "green:wan"; ++ }; ++ }; ++ ++ gpio-keys { ++ pinctrl-0 = <&reset_button_pin>; ++ ++ /delete-node/ power; ++ ++ reset { ++ debounce-interval = <50>; ++ gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>; ++ label = "reset"; ++ linux,code = ; ++ }; ++ }; ++ ++ vdd_5v: vdd-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "vdd_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++}; ++ ++&pcie0 { ++ max-link-speed = <1>; ++ num-lanes = <1>; ++ vpcie3v3-supply = <&vcc3v3_sys>; ++ ++ pcie@0 { ++ reg = <0x00000000 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ++ pcie-eth@0,0 { ++ compatible = "realtek,r8168"; ++ reg = <0x000000 0 0 0 0>; ++ ++ realtek,led-data = <0x870>; ++ }; ++ }; ++}; ++ ++&pinctrl { ++ gpio-leds { ++ /delete-node/ leds-gpio; ++ ++ lan_led_pin: lan-led-pin { ++ rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ sys_led_pin: sys-led-pin { ++ rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wan_led_pin: wan-led-pin { ++ rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ rockchip-key { ++ /delete-node/ power-key; ++ ++ reset_button_pin: reset-button-pin { ++ rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&u2phy0_host { ++ phy-supply = <&vdd_5v>; ++}; ++ ++&vcc3v3_sys { ++ vin-supply = <&vcc5v0_sys>; ++}; ++ ++ +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-doornet2.dtsi +@@ -0,0 +1,637 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include ++#include "rk3399.dtsi" ++#include "rk3399-opp.dtsi" ++ ++/ { ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc3v3_sys: vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc3v3_sys"; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-name = "vcc5v0_sys"; ++ vin-supply = <&vdd_5v>; ++ }; ++ ++ /* switched by pmic_sleep */ ++ vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { ++ compatible = "regulator-fixed"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc1v8_s3"; ++ vin-supply = <&vcc_1v8>; ++ }; ++ ++ vcc3v0_sd: vcc3v0-sd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_pwr_h>; ++ regulator-always-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcc3v0_sd"; ++ vin-supply = <&vcc3v3_sys>; ++ }; ++ ++ vbus_typec: vbus-typec { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-name = "vbus_typec"; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ autorepeat; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&power_key>; ++ ++ power { ++ debounce-interval = <100>; ++ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "GPIO Key Power"; ++ linux,code = ; ++ wakeup-source; ++ }; ++ }; ++ ++ leds: gpio-leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&leds_gpio>; ++ ++ status { ++ gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; ++ label = "status_led"; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk808 1>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_reg_on_h>; ++ reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&gmac { ++ assigned-clocks = <&cru SCLK_RMII_SRC>; ++ assigned-clock-parents = <&clkin_gmac>; ++ clock_in_out = "input"; ++ phy-supply = <&vcc3v3_s3>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii_pins>; ++ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 100000 50000>; ++ tx_delay = <0x28>; ++ rx_delay = <0x11>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&hdmi { ++ ddc-i2c-bus = <&i2c7>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_cec>; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <160>; ++ i2c-scl-falling-time-ns = <30>; ++ status = "okay"; ++ ++ vdd_cpu_b: regulator@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cpu_b_sleep>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-name = "vdd_cpu_b"; ++ regulator-ramp-delay = <1000>; ++ vin-supply = <&vcc3v3_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: regulator@41 { ++ compatible = "silergy,syr828"; ++ reg = <0x41>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpu_sleep>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-name = "vdd_gpu"; ++ regulator-ramp-delay = <1000>; ++ vin-supply = <&vcc3v3_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ clock-output-names = "xin32k", "rtc_clko_wifi"; ++ #clock-cells = <1>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <21 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc3v3_sys>; ++ vcc2-supply = <&vcc3v3_sys>; ++ vcc3-supply = <&vcc3v3_sys>; ++ vcc4-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc3v3_sys>; ++ vcc10-supply = <&vcc3v3_sys>; ++ vcc11-supply = <&vcc3v3_sys>; ++ vcc12-supply = <&vcc3v3_sys>; ++ vddio-supply = <&vcc_3v0>; ++ ++ regulators { ++ vdd_center: DCDC_REG1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-name = "vdd_center"; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-name = "vdd_cpu_l"; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vcc_ddr"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc_1v8"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc1v8_cam: LDO_REG1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc1v8_cam"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v0_touch: LDO_REG2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcc3v0_touch"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc1v8_pmupll: LDO_REG3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc1v8_pmupll"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sdio: LDO_REG4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-init-microvolt = <3000000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc_sdio"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcca3v0_codec: LDO_REG5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcca3v0_codec"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v5: LDO_REG6 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-name = "vcc_1v5"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ vcca1v8_codec: LDO_REG7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcca1v8_codec"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v0: LDO_REG8 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcc_3v0"; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_s3: SWITCH_REG1 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vcc3v3_s3"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_s0: SWITCH_REG2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "vcc3v3_s0"; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ clock-frequency = <200000>; ++ i2c-scl-rising-time-ns = <150>; ++ i2c-scl-falling-time-ns = <30>; ++ status = "okay"; ++}; ++ ++&i2c2 { ++ status = "okay"; ++}; ++ ++&i2c7 { ++ status = "okay"; ++}; ++ ++&io_domains { ++ bt656-supply = <&vcc_1v8>; ++ audio-supply = <&vcca1v8_codec>; ++ sdmmc-supply = <&vcc_sdio>; ++ gpio1830-supply = <&vcc_3v0>; ++ status = "okay"; ++}; ++ ++&pcie_phy { ++ assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>; ++ assigned-clock-rates = <100000000>; ++ assigned-clocks = <&cru SCLK_PCIEPHY_REF>; ++ status = "okay"; ++}; ++ ++&pcie0 { ++ ep-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_HIGH>; ++ max-link-speed = <2>; ++ num-lanes = <4>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ fusb30x { ++ fusb0_int: fusb0-int { ++ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ gpio-leds { ++ leds_gpio: leds-gpio { ++ rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ ethernet-phy { ++ eth_phy_reset_pin: eth-phy-reset-pin { ++ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ pmic { ++ cpu_b_sleep: cpu-b-sleep { ++ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ gpu_sleep: gpu-sleep { ++ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ rockchip-key { ++ power_key: power-key { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio { ++ bt_host_wake_l: bt-host-wake-l { ++ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_reg_on_h: bt-reg-on-h { ++ /* external pullup to VCC1V8_PMUPLL */ ++ rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_wake_l: bt-wake-l { ++ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wifi_reg_on_h: wifi-reg_on-h { ++ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc0_det_l: sdmmc0-det-l { ++ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ sdmmc0_pwr_h: sdmmc0-pwr-h { ++ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ pmu1830-supply = <&vcc_3v0>; ++ status = "okay"; ++}; ++ ++&pwm1 { ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcca1v8_s3>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-mmc-highspeed; ++ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc0_det_l>; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc3v0_sd>; ++ vqmmc-supply = <&vcc_sdio>; ++ status = "okay"; ++}; ++ ++&tcphy0 { ++ status = "okay"; ++}; ++ ++&tcphy1 { ++ status = "okay"; ++}; ++ ++&tsadc { ++ /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-mode = <1>; ++ /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,hw-tshut-polarity = <1>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++}; ++ ++&u2phy0_host { ++ status = "okay"; ++}; ++ ++&u2phy0_otg { ++ status = "okay"; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++}; ++ ++&u2phy1_otg { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usbdrd3_0 { ++ status = "okay"; ++}; ++ ++&usbdrd3_1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_1 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "okay"; ++}; ++ ++&vopl_mmu { ++ status = "okay"; ++}; ++ +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +@@ -504,6 +504,11 @@ int stmmac_mdio_register(struct net_devi + } + } + ++ stmmac_mdio_write(new_bus,0,31,2627); ++ stmmac_mdio_write(new_bus,0,25,0x1801); ++ stmmac_mdio_write(new_bus,0,31,0); ++ stmmac_mdio_write(new_bus,0,0,0x8000); ++ + if (priv->plat->phy_node || mdio_node) + goto bus_register_done; + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -2901,6 +2901,8 @@ static int stmmac_init_dma_engine(struct + if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE)) + atds = 1; + ++ msleep(1500); ++ + ret = stmmac_reset(priv, priv->ioaddr); + if (ret) { + dev_err(priv->device, "Failed to reset the dma\n"); diff --git a/target/linux/rockchip/patches-6.1/212-arm64-dts-rockchip-fix-spdif-fe460000-ordering-on-rk.patch b/target/linux/rockchip/patches-6.1/212-arm64-dts-rockchip-fix-spdif-fe460000-ordering-on-rk.patch new file mode 100644 index 000000000..349275ff7 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/212-arm64-dts-rockchip-fix-spdif-fe460000-ordering-on-rk.patch @@ -0,0 +1,59 @@ +From 59e0ec5e5916ed4fac238a3da39aa0659831c41c Mon Sep 17 00:00:00 2001 +From: Heiko Stuebner +Date: Sun, 30 Oct 2022 20:34:42 +0100 +Subject: [PATCH 6/7] arm64: dts: rockchip: fix spdif@fe460000 ordering on + rk356x + +Move the node to its correct position, based on its +mmio-address. + +Link: https://lore.kernel.org/all/20221030193708.1671069-1-heiko@sntech.de +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 28 ++++++++++++------------ + 1 file changed, 14 insertions(+), 14 deletions(-) + +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -1049,20 +1049,6 @@ + status = "disabled"; + }; + +- spdif: spdif@fe460000 { +- compatible = "rockchip,rk3568-spdif"; +- reg = <0x0 0xfe460000 0x0 0x1000>; +- interrupts = ; +- clock-names = "mclk", "hclk"; +- clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>; +- dmas = <&dmac1 1>; +- dma-names = "tx"; +- pinctrl-names = "default"; +- pinctrl-0 = <&spdifm0_tx>; +- #sound-dai-cells = <0>; +- status = "disabled"; +- }; +- + i2s0_8ch: i2s@fe400000 { + compatible = "rockchip,rk3568-i2s-tdm"; + reg = <0x0 0xfe400000 0x0 0x1000>; +@@ -1141,6 +1127,20 @@ + #sound-dai-cells = <0>; + status = "disabled"; + }; ++ ++ spdif: spdif@fe460000 { ++ compatible = "rockchip,rk3568-spdif"; ++ reg = <0x0 0xfe460000 0x0 0x1000>; ++ interrupts = ; ++ clock-names = "mclk", "hclk"; ++ clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>; ++ dmas = <&dmac1 1>; ++ dma-names = "tx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdifm0_tx>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; + + dmac0: dma-controller@fe530000 { + compatible = "arm,pl330", "arm,primecell"; diff --git a/target/linux/rockchip/patches-6.1/212-rockchip-rk3328-Add-support-for-EmbedFire-DoorNet1.patch b/target/linux/rockchip/patches-6.1/212-rockchip-rk3328-Add-support-for-EmbedFire-DoorNet1.patch new file mode 100644 index 000000000..705f65fb8 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/212-rockchip-rk3328-Add-support-for-EmbedFire-DoorNet1.patch @@ -0,0 +1,499 @@ +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-doornet1.dts +@@ -0,0 +1,495 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2021 EmbedFire ++ */ ++ ++/dts-v1/; ++ ++#include ++#include ++#include "rk3328-dram-default-timing.dtsi" ++#include "rk3328.dtsi" ++ ++/ { ++ model = "EmbedFire DoorNet1"; ++ compatible = "embedfire,doornet1", "rockchip,rk3328"; ++ ++ aliases { ++ led-boot = &sys_led; ++ led-failsafe = &sys_led; ++ led-running = &sys_led; ++ led-upgrade = &sys_led; ++ // mmc1 = &sdmmc; ++ // mmc0 = &emmc; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ gmac_clk: gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ pinctrl-0 = <&reset_button_pin>; ++ pinctrl-names = "default"; ++ ++ reset { ++ label = "reset"; ++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ debounce-interval = <50>; ++ }; ++ }; ++ ++ vcc_rtl8153: vcc-rtl8153-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rtl8153_en_drv>; ++ regulator-always-on; ++ regulator-name = "vcc_rtl8153"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ }; ++ ++ dmc: dmc { ++ compatible = "rockchip,rk3328-dmc"; ++ devfreq-events = <&dfi>; ++ center-supply = <&vdd_log>; ++ clocks = <&cru SCLK_DDRCLK>; ++ clock-names = "dmc_clk"; ++ operating-points-v2 = <&dmc_opp_table>; ++ ddr_timing = <&ddr_timing>; ++ upthreshold = <40>; ++ downdifferential = <20>; ++ auto-min-freq = <786000>; ++ auto-freq-en = <1>; ++ #cooling-cells = <2>; ++ status = "okay"; ++ ++ ddr_power_model: ddr_power_model { ++ compatible = "ddr_power_model"; ++ dynamic-power-coefficient = <120>; ++ static-power-coefficient = <200>; ++ ts = <32000 4700 (-80) 2>; ++ thermal-zone = "soc-thermal"; ++ }; ++ }; ++ ++ dmc_opp_table: dmc-opp-table { ++ compatible = "operating-points-v2"; ++ ++ rockchip,leakage-voltage-sel = < ++ 1 10 0 ++ 11 254 1 ++ >; ++ nvmem-cells = <&logic_leakage>; ++ nvmem-cell-names = "ddr_leakage"; ++ ++ opp-786000000 { ++ opp-hz = /bits/ 64 <786000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-798000000 { ++ opp-hz = /bits/ 64 <798000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-840000000 { ++ opp-hz = /bits/ 64 <840000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-924000000 { ++ opp-hz = /bits/ 64 <924000000>; ++ opp-microvolt = <1100000>; ++ opp-microvolt-L0 = <1100000>; ++ opp-microvolt-L1 = <1075000>; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-microvolt = <1175000>; ++ opp-microvolt-L0 = <1175000>; ++ opp-microvolt-L1 = <1150000>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; ++ pinctrl-names = "default"; ++ ++ lan_led: led-0 { ++ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; ++ label = "doornet1:green:lan"; ++ }; ++ ++ sys_led: led-1 { ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ label = "doornet1:red:sys"; ++ }; ++ ++ wan_led: led-2 { ++ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; ++ label = "doornet1:green:wan"; ++ }; ++ ++ wifi_enable: wifi_enable { ++ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>; ++ label = "wifi-enable"; ++ }; ++ }; ++ ++ vcc_io_sdio: sdmmcio-regulator { ++ compatible = "regulator-gpio"; ++ enable-active-high; ++ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; ++ pinctrl-0 = <&sdio_vcc_pin>; ++ pinctrl-names = "default"; ++ regulator-name = "vcc_io_sdio"; ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-settling-time-us = <5000>; ++ regulator-type = "voltage"; ++ startup-delay-us = <2000>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ vin-supply = <&vcc_io_33>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&sdmmc0m1_pin>; ++ pinctrl-names = "default"; ++ regulator-name = "vcc_sd"; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io_33>; ++ }; ++ ++ vdd_5v: vdd-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "vdd_5v"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&gmac2io { ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; ++ clock_in_out = "input"; ++ phy-mode = "rgmii"; ++ phy-supply = <&vcc_io_33>; ++ pinctrl-0 = <&rgmiim1_pins>; ++ pinctrl-names = "default"; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-delays-us = <0 1000000 50000>; ++ snps,reset-active-low; ++ tx_delay = <0x18>; ++ rx_delay = <0x24>; ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: pmic@18 { ++ compatible = "rockchip,rk805"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio1>; ++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-0 = <&pmic_int_l>; ++ pinctrl-names = "default"; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vdd_5v>; ++ vcc2-supply = <&vdd_5v>; ++ vcc3-supply = <&vdd_5v>; ++ vcc4-supply = <&vdd_5v>; ++ vcc5-supply = <&vcc_io_33>; ++ vcc6-supply = <&vdd_5v>; ++ ++ regulators { ++ vdd_log: DCDC_REG1 { ++ regulator-name = "vdd_log"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-init-microvolt = <1075000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-ramp-delay = <12500>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-init-microvolt = <1225000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-ramp-delay = <12500>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io_33: DCDC_REG4 { ++ regulator-name = "vcc_io_33"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++ usb { ++ rtl8153_en_drv: rtl8153-en-drv { ++ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&io_domains { ++ pmuio-supply = <&vcc_io_33>; ++ vccio1-supply = <&vcc_io_33>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io_sdio>; ++ vccio4-supply = <&vcc_18>; ++ vccio5-supply = <&vcc_io_33>; ++ vccio6-supply = <&vcc_io_33>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ button { ++ reset_button_pin: reset-button-pin { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ ethernet-phy { ++ eth_phy_reset_pin: eth-phy-reset-pin { ++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ leds { ++ lan_led_pin: lan-led-pin { ++ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ sys_led_pin: sys-led-pin { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wan_led_pin: wan-led-pin { ++ rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wifi_pin: wifi_pin{ ++ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sd { ++ sdio_vcc_pin: sdio-vcc-pin { ++ rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&pwm2 { ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; ++ pinctrl-names = "default"; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vcc_io_sdio>; ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ max-frequency = <150000000>; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io_33>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <0>; ++ rockchip,hw-tshut-polarity = <0>; ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ status = "okay"; ++ dr_mode = "host"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ dr_mode = "host"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* Second port is for USB 3.0 */ ++ rtl8153: device@2 { ++ compatible = "usbbda,8153"; ++ reg = <2>; ++ ++ realtek,led-data = <0x87>; ++ }; ++}; +\ No newline at end of file diff --git a/target/linux/rockchip/patches-6.1/213-arm64-dts-rockchip-RK356x-Add-I2S2-device-node.patch b/target/linux/rockchip/patches-6.1/213-arm64-dts-rockchip-RK356x-Add-I2S2-device-node.patch new file mode 100644 index 000000000..a8a43787e --- /dev/null +++ b/target/linux/rockchip/patches-6.1/213-arm64-dts-rockchip-RK356x-Add-I2S2-device-node.patch @@ -0,0 +1,45 @@ +From 6c51234cd4e1bfd637c3aab0a94893e832670fe5 Mon Sep 17 00:00:00 2001 +From: Shengyu Qu +Date: Sun, 30 Oct 2022 01:09:04 +0800 +Subject: [PATCH 7/7] arm64: dts: rockchip: RK356x: Add I2S2 device node + +This patch adds I2S2 device tree node for RK3566/RK3568. + +Signed-off-by: Shengyu Qu +Link: https://lore.kernel.org/r/OS3P286MB259771C12F2B15A4DDF435FE98359@OS3P286MB2597.JPNP286.PROD.OUTLOOK.COM +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -1091,6 +1091,28 @@ + status = "disabled"; + }; + ++ i2s2_2ch: i2s@fe420000 { ++ compatible = "rockchip,rk3568-i2s-tdm"; ++ reg = <0x0 0xfe420000 0x0 0x1000>; ++ interrupts = ; ++ assigned-clocks = <&cru CLK_I2S2_2CH_SRC>; ++ assigned-clock-rates = <1188000000>; ++ clocks = <&cru MCLK_I2S2_2CH>, <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>; ++ clock-names = "mclk_tx", "mclk_rx", "hclk"; ++ dmas = <&dmac1 4>, <&dmac1 5>; ++ dma-names = "tx", "rx"; ++ resets = <&cru SRST_M_I2S2_2CH>; ++ reset-names = "m"; ++ rockchip,grf = <&grf>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s2m0_sclktx ++ &i2s2m0_lrcktx ++ &i2s2m0_sdi ++ &i2s2m0_sdo>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2s3_2ch: i2s@fe430000 { + compatible = "rockchip,rk3568-i2s-tdm"; + reg = <0x0 0xfe430000 0x0 0x1000>; diff --git a/target/linux/rockchip/patches-6.1/213-crypto-rockchip-move-kconfig-to-its-dedicated-direct.patch b/target/linux/rockchip/patches-6.1/213-crypto-rockchip-move-kconfig-to-its-dedicated-direct.patch new file mode 100644 index 000000000..903789cc4 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/213-crypto-rockchip-move-kconfig-to-its-dedicated-direct.patch @@ -0,0 +1,105 @@ +From e8749922cdcddc6e3d3df6a94c530df863073353 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 08:00:44 +0000 +Subject: [PATCH 1/5] crypto: rockchip: move kconfig to its dedicated directory + +Move all rockchip kconfig in its own subdirectory. + +Signed-off-by: Corentin Labbe +--- + drivers/crypto/Kconfig | 32 ++------------------------------ + drivers/crypto/Makefile | 2 +- + drivers/crypto/rockchip/Kconfig | 28 ++++++++++++++++++++++++++++ + 3 files changed, 31 insertions(+), 31 deletions(-) + create mode 100644 drivers/crypto/rockchip/Kconfig + +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -646,6 +646,8 @@ config CRYPTO_DEV_QCOM_RNG + To compile this driver as a module, choose M here. The + module will be called qcom-rng. If unsure, say N. + ++source "drivers/crypto/rockchip/Kconfig" ++ + config CRYPTO_DEV_VMX + bool "Support for VMX cryptographic acceleration instructions" + depends on PPC64 && VSX +@@ -666,36 +668,6 @@ config CRYPTO_DEV_IMGTEC_HASH + hardware hash accelerator. Supporting MD5/SHA1/SHA224/SHA256 + hashing algorithms. + +-config CRYPTO_DEV_ROCKCHIP +- tristate "Rockchip's Cryptographic Engine driver" +- depends on OF && ARCH_ROCKCHIP +- depends on PM +- select CRYPTO_ECB +- select CRYPTO_CBC +- select CRYPTO_DES +- select CRYPTO_AES +- select CRYPTO_ENGINE +- select CRYPTO_LIB_DES +- select CRYPTO_MD5 +- select CRYPTO_SHA1 +- select CRYPTO_SHA256 +- select CRYPTO_HASH +- select CRYPTO_SKCIPHER +- +- help +- This driver interfaces with the hardware crypto accelerator. +- Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. +- +-config CRYPTO_DEV_ROCKCHIP_DEBUG +- bool "Enable Rockchip crypto stats" +- depends on CRYPTO_DEV_ROCKCHIP +- depends on DEBUG_FS +- help +- Say y to enable Rockchip crypto debug stats. +- This will create /sys/kernel/debug/rk3288_crypto/stats for displaying +- the number of requests per algorithm and other internal stats. +- +- + config CRYPTO_DEV_ZYNQMP_AES + tristate "Support for Xilinx ZynqMP AES hw accelerator" + depends on ZYNQMP_FIRMWARE || COMPILE_TEST +--- a/drivers/crypto/Makefile ++++ b/drivers/crypto/Makefile +@@ -36,7 +36,7 @@ obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ + obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/ + obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/ + obj-$(CONFIG_CRYPTO_DEV_QCOM_RNG) += qcom-rng.o +-obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/ ++obj-y += rockchip/ + obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o + obj-$(CONFIG_CRYPTO_DEV_SA2UL) += sa2ul.o + obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o +--- /dev/null ++++ b/drivers/crypto/rockchip/Kconfig +@@ -0,0 +1,28 @@ ++config CRYPTO_DEV_ROCKCHIP ++ tristate "Rockchip's Cryptographic Engine driver" ++ depends on OF && ARCH_ROCKCHIP ++ depends on PM ++ select CRYPTO_ECB ++ select CRYPTO_CBC ++ select CRYPTO_DES ++ select CRYPTO_AES ++ select CRYPTO_ENGINE ++ select CRYPTO_LIB_DES ++ select CRYPTO_MD5 ++ select CRYPTO_SHA1 ++ select CRYPTO_SHA256 ++ select CRYPTO_HASH ++ select CRYPTO_SKCIPHER ++ ++ help ++ This driver interfaces with the hardware crypto accelerator. ++ Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. ++ ++config CRYPTO_DEV_ROCKCHIP_DEBUG ++ bool "Enable Rockchip crypto stats" ++ depends on CRYPTO_DEV_ROCKCHIP ++ depends on DEBUG_FS ++ help ++ Say y to enable Rockchip crypto debug stats. ++ This will create /sys/kernel/debug/rk3288_crypto/stats for displaying ++ the number of requests per algorithm and other internal stats. diff --git a/target/linux/rockchip/patches-6.1/214-dt-bindings-crypto-add-support-for-rockchip-crypto-r.patch b/target/linux/rockchip/patches-6.1/214-dt-bindings-crypto-add-support-for-rockchip-crypto-r.patch new file mode 100644 index 000000000..aa9e35d31 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/214-dt-bindings-crypto-add-support-for-rockchip-crypto-r.patch @@ -0,0 +1,89 @@ +From 03c8a180b9ba57a1bcf658c25a725b063bbade96 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 08:00:45 +0000 +Subject: [PATCH 2/5] dt-bindings: crypto: add support for + rockchip,crypto-rk3588 + +Add device tree binding documentation for the Rockchip cryptographic +offloader V2. + +Signed-off-by: Corentin Labbe +--- + .../crypto/rockchip,rk3588-crypto.yaml | 71 +++++++++++++++++++ + 1 file changed, 71 insertions(+) + create mode 100644 Documentation/devicetree/bindings/crypto/rockchip,rk3588-crypto.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/crypto/rockchip,rk3588-crypto.yaml +@@ -0,0 +1,71 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/crypto/rockchip,rk3588-crypto.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip cryptographic offloader V2 ++ ++maintainers: ++ - Corentin Labbe ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,rk3568-crypto ++ - rockchip,rk3588-crypto ++ ++ reg: ++ maxItems: 1 ++ ++ interrupts: ++ maxItems: 1 ++ ++ clocks: ++ minItems: 4 ++ ++ clock-names: ++ items: ++ - const: aclk ++ - const: hclk ++ - const: sclk ++ - const: pka ++ ++ resets: ++ minItems: 5 ++ ++ reset-names: ++ items: ++ - const: core ++ - const: a ++ - const: h ++ - const: rng ++ - const: pka ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ crypto@fe380000 { ++ compatible = "rockchip,rk3588-crypto"; ++ reg = <0xfe380000 0x4000>; ++ interrupts = ; ++ clocks = <&cru ACLK_CRYPTO_NS>, <&cru HCLK_CRYPTO_NS>, ++ <&cru CLK_CRYPTO_NS_CORE>, <&cru CLK_CRYPTO_NS_PKA>; ++ clock-names = "aclk", "hclk", "sclk", "pka"; ++ resets = <&cru SRST_CRYPTO_NS_CORE>, <&cru SRST_A_CRYPTO_NS>, ++ <&cru SRST_H_CRYPTO_NS>, <&cru SRST_CRYPTO_NS_RNG>, ++ <&cru SRST_CRYPTO_NS_PKA>; ++ reset-names = "core", "a", "h", "rng", "pka"; ++ }; diff --git a/target/linux/rockchip/patches-6.1/215-MAINTAINERS-add-new-dt-binding-doc-to-the-right-entr.patch b/target/linux/rockchip/patches-6.1/215-MAINTAINERS-add-new-dt-binding-doc-to-the-right-entr.patch new file mode 100644 index 000000000..30137d5cf --- /dev/null +++ b/target/linux/rockchip/patches-6.1/215-MAINTAINERS-add-new-dt-binding-doc-to-the-right-entr.patch @@ -0,0 +1,22 @@ +From a091cb568872e3ef2e6a5c6e28e4f43465d46ca2 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 08:00:46 +0000 +Subject: [PATCH 3/5] MAINTAINERS: add new dt-binding doc to the right entry + +Rockchip crypto driver have a new file to be added. + +Signed-off-by: Corentin Labbe +--- + MAINTAINERS | 1 + + 1 file changed, 1 insertion(+) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -17786,6 +17786,7 @@ M: Corentin Labbe + L: linux-crypto@vger.kernel.org + S: Maintained + F: Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml ++F: Documentation/devicetree/bindings/crypto/rockchip,rk3588-crypto.yaml + F: drivers/crypto/rockchip/ + + ROCKCHIP I2S TDM DRIVER diff --git a/target/linux/rockchip/patches-6.1/216-crypto-rockchip-support-the-new-crypto-IP-for-rk3568.patch b/target/linux/rockchip/patches-6.1/216-crypto-rockchip-support-the-new-crypto-IP-for-rk3568.patch new file mode 100644 index 000000000..ecef87107 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/216-crypto-rockchip-support-the-new-crypto-IP-for-rk3568.patch @@ -0,0 +1,1633 @@ +From 06ecfb2f7b3277c4ed1bf0172b14ae7bc0c2d4aa Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 08:00:47 +0000 +Subject: [PATCH 4/5] crypto: rockchip: support the new crypto IP for + rk3568/rk3588 + +Rockchip rk3568 and rk3588 have a common crypto offloader IP. +This driver adds support for it. + +Signed-off-by: Corentin Labbe +--- + drivers/crypto/rockchip/Kconfig | 28 + + drivers/crypto/rockchip/Makefile | 5 + + drivers/crypto/rockchip/rk3588_crypto.c | 646 ++++++++++++++++++ + drivers/crypto/rockchip/rk3588_crypto.h | 221 ++++++ + drivers/crypto/rockchip/rk3588_crypto_ahash.c | 346 ++++++++++ + .../crypto/rockchip/rk3588_crypto_skcipher.c | 340 +++++++++ + 6 files changed, 1586 insertions(+) + create mode 100644 drivers/crypto/rockchip/rk3588_crypto.c + create mode 100644 drivers/crypto/rockchip/rk3588_crypto.h + create mode 100644 drivers/crypto/rockchip/rk3588_crypto_ahash.c + create mode 100644 drivers/crypto/rockchip/rk3588_crypto_skcipher.c + +--- a/drivers/crypto/rockchip/Kconfig ++++ b/drivers/crypto/rockchip/Kconfig +@@ -26,3 +26,31 @@ config CRYPTO_DEV_ROCKCHIP_DEBUG + Say y to enable Rockchip crypto debug stats. + This will create /sys/kernel/debug/rk3288_crypto/stats for displaying + the number of requests per algorithm and other internal stats. ++ ++config CRYPTO_DEV_ROCKCHIP2 ++ tristate "Rockchip's cryptographic offloader V2" ++ depends on OF && ARCH_ROCKCHIP ++ depends on PM ++ select CRYPTO_ECB ++ select CRYPTO_CBC ++ select CRYPTO_AES ++ select CRYPTO_MD5 ++ select CRYPTO_SHA1 ++ select CRYPTO_SHA256 ++ select CRYPTO_SM3 ++ select CRYPTO_HASH ++ select CRYPTO_SKCIPHER ++ select CRYPTO_ENGINE ++ ++ help ++ This driver interfaces with the hardware crypto offloader present ++ on RK3568 and RK3588. ++ ++config CRYPTO_DEV_ROCKCHIP2_DEBUG ++ bool "Enable Rockchip V2 crypto stats" ++ depends on CRYPTO_DEV_ROCKCHIP2 ++ depends on DEBUG_FS ++ help ++ Say y to enable Rockchip crypto debug stats. ++ This will create /sys/kernel/debug/rk3588_crypto/stats for displaying ++ the number of requests per algorithm and other internal stats. +--- a/drivers/crypto/rockchip/Makefile ++++ b/drivers/crypto/rockchip/Makefile +@@ -3,3 +3,8 @@ obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_ + rk_crypto-objs := rk3288_crypto.o \ + rk3288_crypto_skcipher.o \ + rk3288_crypto_ahash.o ++ ++obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP2) += rk_crypto2.o ++rk_crypto2-objs := rk3588_crypto.o \ ++ rk3588_crypto_skcipher.o \ ++ rk3588_crypto_ahash.o +--- /dev/null ++++ b/drivers/crypto/rockchip/rk3588_crypto.c +@@ -0,0 +1,646 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * hardware cryptographic offloader for rk3568/rk3588 SoC ++ * ++ * Copyright (c) 2022, Corentin Labbe ++ */ ++ ++#include "rk3588_crypto.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct rockchip_ip rocklist = { ++ .dev_list = LIST_HEAD_INIT(rocklist.dev_list), ++ .lock = __SPIN_LOCK_UNLOCKED(rocklist.lock), ++}; ++ ++struct rk_crypto_dev *get_rk_crypto(void) ++{ ++ struct rk_crypto_dev *first; ++ ++ spin_lock(&rocklist.lock); ++ first = list_first_entry_or_null(&rocklist.dev_list, ++ struct rk_crypto_dev, list); ++ list_rotate_left(&rocklist.dev_list); ++ spin_unlock(&rocklist.lock); ++ return first; ++} ++ ++static const struct rk_variant rk3568_variant = { ++ .num_clks = 4, ++}; ++ ++static const struct rk_variant rk3588_variant = { ++ .num_clks = 4, ++}; ++ ++static int rk_crypto_get_clks(struct rk_crypto_dev *dev) ++{ ++ int i, j, err; ++ unsigned long cr; ++ ++ dev->num_clks = devm_clk_bulk_get_all(dev->dev, &dev->clks); ++ if (dev->num_clks < dev->variant->num_clks) { ++ dev_err(dev->dev, "Missing clocks, got %d instead of %d\n", ++ dev->num_clks, dev->variant->num_clks); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < dev->num_clks; i++) { ++ cr = clk_get_rate(dev->clks[i].clk); ++ for (j = 0; j < ARRAY_SIZE(dev->variant->rkclks); j++) { ++ if (dev->variant->rkclks[j].max == 0) ++ continue; ++ if (strcmp(dev->variant->rkclks[j].name, dev->clks[i].id)) ++ continue; ++ if (cr > dev->variant->rkclks[j].max) { ++ err = clk_set_rate(dev->clks[i].clk, ++ dev->variant->rkclks[j].max); ++ if (err) ++ dev_err(dev->dev, "Fail downclocking %s from %lu to %lu\n", ++ dev->variant->rkclks[j].name, cr, ++ dev->variant->rkclks[j].max); ++ else ++ dev_info(dev->dev, "Downclocking %s from %lu to %lu\n", ++ dev->variant->rkclks[j].name, cr, ++ dev->variant->rkclks[j].max); ++ } ++ } ++ } ++ return 0; ++} ++ ++static int rk_crypto_enable_clk(struct rk_crypto_dev *dev) ++{ ++ int err; ++ ++ err = clk_bulk_prepare_enable(dev->num_clks, dev->clks); ++ if (err) ++ dev_err(dev->dev, "Could not enable clock clks\n"); ++ ++ return err; ++} ++ ++static void rk_crypto_disable_clk(struct rk_crypto_dev *dev) ++{ ++ clk_bulk_disable_unprepare(dev->num_clks, dev->clks); ++} ++ ++/* ++ * Power management strategy: The device is suspended until a request ++ * is handled. For avoiding suspend/resume yoyo, the autosuspend is set to 2s. ++ */ ++static int rk_crypto_pm_suspend(struct device *dev) ++{ ++ struct rk_crypto_dev *rkdev = dev_get_drvdata(dev); ++ ++ rk_crypto_disable_clk(rkdev); ++ reset_control_assert(rkdev->rst); ++ ++ return 0; ++} ++ ++static int rk_crypto_pm_resume(struct device *dev) ++{ ++ struct rk_crypto_dev *rkdev = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = rk_crypto_enable_clk(rkdev); ++ if (ret) ++ return ret; ++ ++ reset_control_deassert(rkdev->rst); ++ return 0; ++} ++ ++static const struct dev_pm_ops rk_crypto_pm_ops = { ++ SET_RUNTIME_PM_OPS(rk_crypto_pm_suspend, rk_crypto_pm_resume, NULL) ++}; ++ ++static int rk_crypto_pm_init(struct rk_crypto_dev *rkdev) ++{ ++ int err; ++ ++ pm_runtime_use_autosuspend(rkdev->dev); ++ pm_runtime_set_autosuspend_delay(rkdev->dev, 2000); ++ ++ err = pm_runtime_set_suspended(rkdev->dev); ++ if (err) ++ return err; ++ pm_runtime_enable(rkdev->dev); ++ return err; ++} ++ ++static void rk_crypto_pm_exit(struct rk_crypto_dev *rkdev) ++{ ++ pm_runtime_disable(rkdev->dev); ++} ++ ++static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) ++{ ++ struct rk_crypto_dev *rkc = platform_get_drvdata(dev_id); ++ u32 v; ++ ++ v = readl(rkc->reg + RK_CRYPTO_DMA_INT_ST); ++ writel(v, rkc->reg + RK_CRYPTO_DMA_INT_ST); ++ ++ rkc->status = 1; ++ if (v & 0xF8) { ++ dev_warn(rkc->dev, "DMA Error\n"); ++ rkc->status = 0; ++ } ++ complete(&rkc->complete); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct rk_crypto_template rk_cipher_algs[] = { ++ { ++ .type = CRYPTO_ALG_TYPE_SKCIPHER, ++ .alg.skcipher = { ++ .base.cra_name = "ecb(aes)", ++ .base.cra_driver_name = "ecb-aes-rk2", ++ .base.cra_priority = 300, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), ++ .base.cra_alignmask = 0x0f, ++ .base.cra_module = THIS_MODULE, ++ ++ .init = rk_cipher_tfm_init, ++ .exit = rk_cipher_tfm_exit, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .setkey = rk_aes_setkey, ++ .encrypt = rk_aes_ecb_encrypt, ++ .decrypt = rk_aes_ecb_decrypt, ++ } ++ }, ++ { ++ .type = CRYPTO_ALG_TYPE_SKCIPHER, ++ .alg.skcipher = { ++ .base.cra_name = "cbc(aes)", ++ .base.cra_driver_name = "cbc-aes-rk2", ++ .base.cra_priority = 300, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), ++ .base.cra_alignmask = 0x0f, ++ .base.cra_module = THIS_MODULE, ++ ++ .init = rk_cipher_tfm_init, ++ .exit = rk_cipher_tfm_exit, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .ivsize = AES_BLOCK_SIZE, ++ .setkey = rk_aes_setkey, ++ .encrypt = rk_aes_cbc_encrypt, ++ .decrypt = rk_aes_cbc_decrypt, ++ } ++ }, ++ { ++ .type = CRYPTO_ALG_TYPE_AHASH, ++ .rk_mode = RK_CRYPTO_MD5, ++ .alg.hash = { ++ .init = rk_ahash_init, ++ .update = rk_ahash_update, ++ .final = rk_ahash_final, ++ .finup = rk_ahash_finup, ++ .export = rk_ahash_export, ++ .import = rk_ahash_import, ++ .digest = rk_ahash_digest, ++ .halg = { ++ .digestsize = MD5_DIGEST_SIZE, ++ .statesize = sizeof(struct md5_state), ++ .base = { ++ .cra_name = "md5", ++ .cra_driver_name = "rk2-md5", ++ .cra_priority = 300, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA1_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct rk_ahash_ctx), ++ .cra_alignmask = 3, ++ .cra_init = rk_cra_hash_init, ++ .cra_exit = rk_cra_hash_exit, ++ .cra_module = THIS_MODULE, ++ } ++ } ++ } ++ }, ++ { ++ .type = CRYPTO_ALG_TYPE_AHASH, ++ .rk_mode = RK_CRYPTO_SHA1, ++ .alg.hash = { ++ .init = rk_ahash_init, ++ .update = rk_ahash_update, ++ .final = rk_ahash_final, ++ .finup = rk_ahash_finup, ++ .export = rk_ahash_export, ++ .import = rk_ahash_import, ++ .digest = rk_ahash_digest, ++ .halg = { ++ .digestsize = SHA1_DIGEST_SIZE, ++ .statesize = sizeof(struct sha1_state), ++ .base = { ++ .cra_name = "sha1", ++ .cra_driver_name = "rk2-sha1", ++ .cra_priority = 300, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA1_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct rk_ahash_ctx), ++ .cra_alignmask = 3, ++ .cra_init = rk_cra_hash_init, ++ .cra_exit = rk_cra_hash_exit, ++ .cra_module = THIS_MODULE, ++ } ++ } ++ } ++ }, ++ { ++ .type = CRYPTO_ALG_TYPE_AHASH, ++ .rk_mode = RK_CRYPTO_SHA256, ++ .alg.hash = { ++ .init = rk_ahash_init, ++ .update = rk_ahash_update, ++ .final = rk_ahash_final, ++ .finup = rk_ahash_finup, ++ .export = rk_ahash_export, ++ .import = rk_ahash_import, ++ .digest = rk_ahash_digest, ++ .halg = { ++ .digestsize = SHA256_DIGEST_SIZE, ++ .statesize = sizeof(struct sha256_state), ++ .base = { ++ .cra_name = "sha256", ++ .cra_driver_name = "rk2-sha256", ++ .cra_priority = 300, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA256_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct rk_ahash_ctx), ++ .cra_alignmask = 3, ++ .cra_init = rk_cra_hash_init, ++ .cra_exit = rk_cra_hash_exit, ++ .cra_module = THIS_MODULE, ++ } ++ } ++ } ++ }, ++ { ++ .type = CRYPTO_ALG_TYPE_AHASH, ++ .rk_mode = RK_CRYPTO_SHA384, ++ .alg.hash = { ++ .init = rk_ahash_init, ++ .update = rk_ahash_update, ++ .final = rk_ahash_final, ++ .finup = rk_ahash_finup, ++ .export = rk_ahash_export, ++ .import = rk_ahash_import, ++ .digest = rk_ahash_digest, ++ .halg = { ++ .digestsize = SHA384_DIGEST_SIZE, ++ .statesize = sizeof(struct sha512_state), ++ .base = { ++ .cra_name = "sha384", ++ .cra_driver_name = "rk2-sha384", ++ .cra_priority = 300, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA384_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct rk_ahash_ctx), ++ .cra_alignmask = 3, ++ .cra_init = rk_cra_hash_init, ++ .cra_exit = rk_cra_hash_exit, ++ .cra_module = THIS_MODULE, ++ } ++ } ++ } ++ }, ++ { ++ .type = CRYPTO_ALG_TYPE_AHASH, ++ .rk_mode = RK_CRYPTO_SHA512, ++ .alg.hash = { ++ .init = rk_ahash_init, ++ .update = rk_ahash_update, ++ .final = rk_ahash_final, ++ .finup = rk_ahash_finup, ++ .export = rk_ahash_export, ++ .import = rk_ahash_import, ++ .digest = rk_ahash_digest, ++ .halg = { ++ .digestsize = SHA512_DIGEST_SIZE, ++ .statesize = sizeof(struct sha512_state), ++ .base = { ++ .cra_name = "sha512", ++ .cra_driver_name = "rk2-sha512", ++ .cra_priority = 300, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SHA512_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct rk_ahash_ctx), ++ .cra_alignmask = 3, ++ .cra_init = rk_cra_hash_init, ++ .cra_exit = rk_cra_hash_exit, ++ .cra_module = THIS_MODULE, ++ } ++ } ++ } ++ }, ++ { ++ .type = CRYPTO_ALG_TYPE_AHASH, ++ .rk_mode = RK_CRYPTO_SM3, ++ .alg.hash = { ++ .init = rk_ahash_init, ++ .update = rk_ahash_update, ++ .final = rk_ahash_final, ++ .finup = rk_ahash_finup, ++ .export = rk_ahash_export, ++ .import = rk_ahash_import, ++ .digest = rk_ahash_digest, ++ .halg = { ++ .digestsize = SM3_DIGEST_SIZE, ++ .statesize = sizeof(struct sm3_state), ++ .base = { ++ .cra_name = "sm3", ++ .cra_driver_name = "rk2-sm3", ++ .cra_priority = 300, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .cra_blocksize = SM3_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct rk_ahash_ctx), ++ .cra_alignmask = 3, ++ .cra_init = rk_cra_hash_init, ++ .cra_exit = rk_cra_hash_exit, ++ .cra_module = THIS_MODULE, ++ } ++ } ++ } ++ }, ++}; ++ ++#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP2_DEBUG ++static int rk_crypto_debugfs_show(struct seq_file *seq, void *v) ++{ ++ struct rk_crypto_dev *dd; ++ unsigned int i; ++ ++ spin_lock(&rocklist.lock); ++ list_for_each_entry(dd, &rocklist.dev_list, list) { ++ seq_printf(seq, "%s %s requests: %lu\n", ++ dev_driver_string(dd->dev), dev_name(dd->dev), ++ dd->nreq); ++ } ++ spin_unlock(&rocklist.lock); ++ ++ for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) { ++ if (!rk_cipher_algs[i].dev) ++ continue; ++ switch (rk_cipher_algs[i].type) { ++ case CRYPTO_ALG_TYPE_SKCIPHER: ++ seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", ++ rk_cipher_algs[i].alg.skcipher.base.cra_driver_name, ++ rk_cipher_algs[i].alg.skcipher.base.cra_name, ++ rk_cipher_algs[i].stat_req, rk_cipher_algs[i].stat_fb); ++ seq_printf(seq, "\tfallback due to length: %lu\n", ++ rk_cipher_algs[i].stat_fb_len); ++ seq_printf(seq, "\tfallback due to alignment: %lu\n", ++ rk_cipher_algs[i].stat_fb_align); ++ seq_printf(seq, "\tfallback due to SGs: %lu\n", ++ rk_cipher_algs[i].stat_fb_sgdiff); ++ break; ++ case CRYPTO_ALG_TYPE_AHASH: ++ seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", ++ rk_cipher_algs[i].alg.hash.halg.base.cra_driver_name, ++ rk_cipher_algs[i].alg.hash.halg.base.cra_name, ++ rk_cipher_algs[i].stat_req, rk_cipher_algs[i].stat_fb); ++ break; ++ } ++ } ++ return 0; ++} ++ ++DEFINE_SHOW_ATTRIBUTE(rk_crypto_debugfs); ++#endif ++ ++static void register_debugfs(struct rk_crypto_dev *crypto_dev) ++{ ++#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP2_DEBUG ++ /* Ignore error of debugfs */ ++ rocklist.dbgfs_dir = debugfs_create_dir("rk3588_crypto", NULL); ++ rocklist.dbgfs_stats = debugfs_create_file("stats", 0444, ++ rocklist.dbgfs_dir, ++ &rocklist, ++ &rk_crypto_debugfs_fops); ++#endif ++} ++ ++static int rk_crypto_register(struct rk_crypto_dev *rkc) ++{ ++ unsigned int i, k; ++ int err = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) { ++ rk_cipher_algs[i].dev = rkc; ++ switch (rk_cipher_algs[i].type) { ++ case CRYPTO_ALG_TYPE_SKCIPHER: ++ dev_info(rkc->dev, "Register %s as %s\n", ++ rk_cipher_algs[i].alg.skcipher.base.cra_name, ++ rk_cipher_algs[i].alg.skcipher.base.cra_driver_name); ++ err = crypto_register_skcipher(&rk_cipher_algs[i].alg.skcipher); ++ break; ++ case CRYPTO_ALG_TYPE_AHASH: ++ dev_info(rkc->dev, "Register %s as %s\n", ++ rk_cipher_algs[i].alg.hash.halg.base.cra_name, ++ rk_cipher_algs[i].alg.hash.halg.base.cra_driver_name); ++ err = crypto_register_ahash(&rk_cipher_algs[i].alg.hash); ++ break; ++ default: ++ dev_err(rkc->dev, "unknown algorithm\n"); ++ } ++ if (err) ++ goto err_cipher_algs; ++ } ++ return 0; ++ ++err_cipher_algs: ++ for (k = 0; k < i; k++) { ++ if (rk_cipher_algs[i].type == CRYPTO_ALG_TYPE_SKCIPHER) ++ crypto_unregister_skcipher(&rk_cipher_algs[k].alg.skcipher); ++ else ++ crypto_unregister_ahash(&rk_cipher_algs[i].alg.hash); ++ } ++ return err; ++} ++ ++static void rk_crypto_unregister(void) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) { ++ if (rk_cipher_algs[i].type == CRYPTO_ALG_TYPE_SKCIPHER) ++ crypto_unregister_skcipher(&rk_cipher_algs[i].alg.skcipher); ++ else ++ crypto_unregister_ahash(&rk_cipher_algs[i].alg.hash); ++ } ++} ++ ++static const struct of_device_id crypto_of_id_table[] = { ++ { .compatible = "rockchip,rk3568-crypto", ++ .data = &rk3568_variant, ++ }, ++ { .compatible = "rockchip,rk3588-crypto", ++ .data = &rk3588_variant, ++ }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, crypto_of_id_table); ++ ++static int rk_crypto_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct rk_crypto_dev *rkc, *first; ++ int err = 0; ++ ++ rkc = devm_kzalloc(&pdev->dev, sizeof(*rkc), GFP_KERNEL); ++ if (!rkc) { ++ err = -ENOMEM; ++ goto err_crypto; ++ } ++ ++ rkc->dev = &pdev->dev; ++ platform_set_drvdata(pdev, rkc); ++ ++ rkc->variant = of_device_get_match_data(&pdev->dev); ++ if (!rkc->variant) { ++ dev_err(&pdev->dev, "Missing variant\n"); ++ return -EINVAL; ++ } ++ ++ rkc->rst = devm_reset_control_array_get_exclusive(dev); ++ if (IS_ERR(rkc->rst)) { ++ err = PTR_ERR(rkc->rst); ++ goto err_crypto; ++ } ++ ++ rkc->tl = dma_alloc_coherent(rkc->dev, ++ sizeof(struct rk_crypto_lli) * MAX_LLI, ++ &rkc->t_phy, GFP_KERNEL); ++ if (!rkc->tl) { ++ dev_err(rkc->dev, "Cannot get DMA memory for task\n"); ++ err = -ENOMEM; ++ goto err_crypto; ++ } ++ ++ reset_control_assert(rkc->rst); ++ usleep_range(10, 20); ++ reset_control_deassert(rkc->rst); ++ ++ rkc->reg = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(rkc->reg)) { ++ err = PTR_ERR(rkc->reg); ++ goto err_crypto; ++ } ++ ++ err = rk_crypto_get_clks(rkc); ++ if (err) ++ goto err_crypto; ++ ++ rkc->irq = platform_get_irq(pdev, 0); ++ if (rkc->irq < 0) { ++ dev_err(&pdev->dev, "control Interrupt is not available.\n"); ++ err = rkc->irq; ++ goto err_crypto; ++ } ++ ++ err = devm_request_irq(&pdev->dev, rkc->irq, ++ rk_crypto_irq_handle, IRQF_SHARED, ++ "rk-crypto", pdev); ++ ++ if (err) { ++ dev_err(&pdev->dev, "irq request failed.\n"); ++ goto err_crypto; ++ } ++ ++ rkc->engine = crypto_engine_alloc_init(&pdev->dev, true); ++ crypto_engine_start(rkc->engine); ++ init_completion(&rkc->complete); ++ ++ err = rk_crypto_pm_init(rkc); ++ if (err) ++ goto err_pm; ++ ++ err = pm_runtime_resume_and_get(&pdev->dev); ++ ++ spin_lock(&rocklist.lock); ++ first = list_first_entry_or_null(&rocklist.dev_list, ++ struct rk_crypto_dev, list); ++ list_add_tail(&rkc->list, &rocklist.dev_list); ++ spin_unlock(&rocklist.lock); ++ ++ if (!first) { ++ dev_info(dev, "Registers crypto algos\n"); ++ err = rk_crypto_register(rkc); ++ if (err) { ++ dev_err(dev, "Fail to register crypto algorithms"); ++ goto err_register_alg; ++ } ++ ++ register_debugfs(rkc); ++ } ++ ++ return 0; ++ ++err_register_alg: ++ rk_crypto_pm_exit(rkc); ++err_pm: ++ crypto_engine_exit(rkc->engine); ++err_crypto: ++ dev_err(dev, "Crypto Accelerator not successfully registered\n"); ++ return err; ++} ++ ++static int rk_crypto_remove(struct platform_device *pdev) ++{ ++ struct rk_crypto_dev *crypto_tmp = platform_get_drvdata(pdev); ++ struct rk_crypto_dev *first; ++ ++ spin_lock_bh(&rocklist.lock); ++ list_del(&crypto_tmp->list); ++ first = list_first_entry_or_null(&rocklist.dev_list, ++ struct rk_crypto_dev, list); ++ spin_unlock_bh(&rocklist.lock); ++ ++ if (!first) { ++#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP2_DEBUG ++ debugfs_remove_recursive(rocklist.dbgfs_dir); ++#endif ++ rk_crypto_unregister(); ++ } ++ rk_crypto_pm_exit(crypto_tmp); ++ crypto_engine_exit(crypto_tmp->engine); ++ return 0; ++} ++ ++static struct platform_driver crypto_driver = { ++ .probe = rk_crypto_probe, ++ .remove = rk_crypto_remove, ++ .driver = { ++ .name = "rk3588-crypto", ++ .pm = &rk_crypto_pm_ops, ++ .of_match_table = crypto_of_id_table, ++ }, ++}; ++ ++module_platform_driver(crypto_driver); ++ ++MODULE_DESCRIPTION("Rockchip Crypto Engine cryptographic offloader"); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Corentin Labbe "); +--- /dev/null ++++ b/drivers/crypto/rockchip/rk3588_crypto.h +@@ -0,0 +1,221 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define RK_CRYPTO_CLK_CTL 0x0000 ++#define RK_CRYPTO_RST_CTL 0x0004 ++ ++#define RK_CRYPTO_DMA_INT_EN 0x0008 ++/* values for RK_CRYPTO_DMA_INT_EN */ ++#define RK_CRYPTO_DMA_INT_LISTDONE BIT(0) ++ ++#define RK_CRYPTO_DMA_INT_ST 0x000C ++/* values in RK_CRYPTO_DMA_INT_ST are the same than in RK_CRYPTO_DMA_INT_EN */ ++ ++#define RK_CRYPTO_DMA_CTL 0x0010 ++#define RK_CRYPTO_DMA_CTL_START BIT(0) ++ ++#define RK_CRYPTO_DMA_LLI_ADDR 0x0014 ++ ++#define RK_CRYPTO_FIFO_CTL 0x0040 ++ ++#define RK_CRYPTO_BC_CTL 0x0044 ++#define RK_CRYPTO_AES (0 << 8) ++#define RK_CRYPTO_MODE_ECB (0 << 4) ++#define RK_CRYPTO_MODE_CBC (1 << 4) ++ ++#define RK_CRYPTO_HASH_CTL 0x0048 ++#define RK_CRYPTO_HW_PAD BIT(2) ++#define RK_CRYPTO_SHA1 (0 << 4) ++#define RK_CRYPTO_MD5 (1 << 4) ++#define RK_CRYPTO_SHA224 (3 << 4) ++#define RK_CRYPTO_SHA256 (2 << 4) ++#define RK_CRYPTO_SHA384 (9 << 4) ++#define RK_CRYPTO_SHA512 (8 << 4) ++#define RK_CRYPTO_SM3 (4 << 4) ++ ++#define RK_CRYPTO_AES_ECB_MODE (RK_CRYPTO_AES | RK_CRYPTO_MODE_ECB) ++#define RK_CRYPTO_AES_CBC_MODE (RK_CRYPTO_AES | RK_CRYPTO_MODE_CBC) ++#define RK_CRYPTO_AES_CTR_MODE 3 ++#define RK_CRYPTO_AES_128BIT_key (0 << 2) ++#define RK_CRYPTO_AES_192BIT_key (1 << 2) ++#define RK_CRYPTO_AES_256BIT_key (2 << 2) ++ ++#define RK_CRYPTO_DEC BIT(1) ++#define RK_CRYPTO_ENABLE BIT(0) ++ ++#define RK_CRYPTO_CH0_IV_0 0x0100 ++ ++#define RK_CRYPTO_KEY0 0x0180 ++#define RK_CRYPTO_KEY1 0x0184 ++#define RK_CRYPTO_KEY2 0x0188 ++#define RK_CRYPTO_KEY3 0x018C ++#define RK_CRYPTO_KEY4 0x0190 ++#define RK_CRYPTO_KEY5 0x0194 ++#define RK_CRYPTO_KEY6 0x0198 ++#define RK_CRYPTO_KEY7 0x019C ++ ++#define RK_CRYPTO_CH0_PC_LEN_0 0x0280 ++ ++#define RK_CRYPTO_CH0_IV_LEN 0x0300 ++ ++#define RK_CRYPTO_HASH_DOUT_0 0x03A0 ++#define RK_CRYPTO_HASH_VALID 0x03E4 ++ ++#define CRYPTO_AES_VERSION 0x0680 ++#define CRYPTO_DES_VERSION 0x0684 ++#define CRYPTO_SM4_VERSION 0x0688 ++#define CRYPTO_HASH_VERSION 0x068C ++#define CRYPTO_HMAC_VERSION 0x0690 ++#define CRYPTO_RNG_VERSION 0x0694 ++#define CRYPTO_PKA_VERSION 0x0698 ++#define CRYPTO_CRYPTO_VERSION 0x06F0 ++ ++#define RK_LLI_DMA_CTRL_SRC_INT BIT(10) ++#define RK_LLI_DMA_CTRL_DST_INT BIT(9) ++#define RK_LLI_DMA_CTRL_LIST_INT BIT(8) ++#define RK_LLI_DMA_CTRL_LAST BIT(0) ++ ++#define RK_LLI_STRING_LAST BIT(2) ++#define RK_LLI_STRING_FIRST BIT(1) ++#define RK_LLI_CIPHER_START BIT(0) ++ ++#define RK_MAX_CLKS 4 ++ ++/* there are no hw limit, but we need to choose a maximum of descriptor to allocate */ ++#define MAX_LLI 20 ++ ++struct rk_crypto_lli { ++ __le32 src_addr; ++ __le32 src_len; ++ __le32 dst_addr; ++ __le32 dst_len; ++ __le32 user; ++ __le32 iv; ++ __le32 dma_ctrl; ++ __le32 next; ++}; ++ ++/* ++ * struct rockchip_ip - struct for managing a list of RK crypto instance ++ * @dev_list: Used for doing a list of rk_crypto_dev ++ * @lock: Control access to dev_list ++ * @dbgfs_dir: Debugfs dentry for statistic directory ++ * @dbgfs_stats: Debugfs dentry for statistic counters ++ */ ++struct rockchip_ip { ++ struct list_head dev_list; ++ spinlock_t lock; /* Control access to dev_list */ ++ struct dentry *dbgfs_dir; ++ struct dentry *dbgfs_stats; ++}; ++ ++struct rk_clks { ++ const char *name; ++ unsigned long max; ++}; ++ ++struct rk_variant { ++ int num_clks; ++ struct rk_clks rkclks[RK_MAX_CLKS]; ++}; ++ ++struct rk_crypto_dev { ++ struct list_head list; ++ struct device *dev; ++ struct clk_bulk_data *clks; ++ int num_clks; ++ struct reset_control *rst; ++ void __iomem *reg; ++ int irq; ++ const struct rk_variant *variant; ++ unsigned long nreq; ++ struct crypto_engine *engine; ++ struct completion complete; ++ int status; ++ struct rk_crypto_lli *tl; ++ dma_addr_t t_phy; ++}; ++ ++/* the private variable of hash */ ++struct rk_ahash_ctx { ++ struct crypto_engine_ctx enginectx; ++ /* for fallback */ ++ struct crypto_ahash *fallback_tfm; ++}; ++ ++/* the private variable of hash for fallback */ ++struct rk_ahash_rctx { ++ struct rk_crypto_dev *dev; ++ struct ahash_request fallback_req; ++ u32 mode; ++ int nrsgs; ++}; ++ ++/* the private variable of cipher */ ++struct rk_cipher_ctx { ++ struct crypto_engine_ctx enginectx; ++ unsigned int keylen; ++ u8 key[AES_MAX_KEY_SIZE]; ++ u8 iv[AES_BLOCK_SIZE]; ++ struct crypto_skcipher *fallback_tfm; ++}; ++ ++struct rk_cipher_rctx { ++ struct rk_crypto_dev *dev; ++ u8 backup_iv[AES_BLOCK_SIZE]; ++ u32 mode; ++ struct skcipher_request fallback_req; // keep at the end ++}; ++ ++struct rk_crypto_template { ++ u32 type; ++ u32 rk_mode; ++ struct rk_crypto_dev *dev; ++ union { ++ struct skcipher_alg skcipher; ++ struct ahash_alg hash; ++ } alg; ++ unsigned long stat_req; ++ unsigned long stat_fb; ++ unsigned long stat_fb_len; ++ unsigned long stat_fb_sglen; ++ unsigned long stat_fb_align; ++ unsigned long stat_fb_sgdiff; ++}; ++ ++struct rk_crypto_dev *get_rk_crypto(void); ++ ++int rk_cipher_tfm_init(struct crypto_skcipher *tfm); ++void rk_cipher_tfm_exit(struct crypto_skcipher *tfm); ++int rk_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, ++ unsigned int keylen); ++int rk_aes_ecb_encrypt(struct skcipher_request *req); ++int rk_aes_ecb_decrypt(struct skcipher_request *req); ++int rk_aes_cbc_encrypt(struct skcipher_request *req); ++int rk_aes_cbc_decrypt(struct skcipher_request *req); ++ ++int rk_ahash_init(struct ahash_request *req); ++int rk_ahash_update(struct ahash_request *req); ++int rk_ahash_final(struct ahash_request *req); ++int rk_ahash_finup(struct ahash_request *req); ++int rk_ahash_import(struct ahash_request *req, const void *in); ++int rk_ahash_export(struct ahash_request *req, void *out); ++int rk_ahash_digest(struct ahash_request *req); ++int rk_cra_hash_init(struct crypto_tfm *tfm); ++void rk_cra_hash_exit(struct crypto_tfm *tfm); +--- /dev/null ++++ b/drivers/crypto/rockchip/rk3588_crypto_ahash.c +@@ -0,0 +1,346 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Crypto acceleration support for Rockchip RK3588 ++ * ++ * Copyright (c) 2022 Corentin Labbe ++ */ ++#include ++#include ++#include "rk3588_crypto.h" ++ ++static bool rk_ahash_need_fallback(struct ahash_request *areq) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.hash); ++ struct scatterlist *sg; ++ ++ sg = areq->src; ++ while (sg) { ++ if (!IS_ALIGNED(sg->offset, sizeof(u32))) { ++ algt->stat_fb_align++; ++ return true; ++ } ++ if (sg->length % 4) { ++ algt->stat_fb_sglen++; ++ return true; ++ } ++ sg = sg_next(sg); ++ } ++ return false; ++} ++ ++static int rk_ahash_digest_fb(struct ahash_request *areq) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm); ++ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.hash); ++ ++ algt->stat_fb++; ++ ++ ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); ++ rctx->fallback_req.base.flags = areq->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ rctx->fallback_req.nbytes = areq->nbytes; ++ rctx->fallback_req.src = areq->src; ++ rctx->fallback_req.result = areq->result; ++ ++ return crypto_ahash_digest(&rctx->fallback_req); ++} ++ ++static int zero_message_process(struct ahash_request *req) ++{ ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.hash); ++ int digestsize = crypto_ahash_digestsize(tfm); ++ ++ switch (algt->rk_mode) { ++ case RK_CRYPTO_SHA1: ++ memcpy(req->result, sha1_zero_message_hash, digestsize); ++ break; ++ case RK_CRYPTO_SHA256: ++ memcpy(req->result, sha256_zero_message_hash, digestsize); ++ break; ++ case RK_CRYPTO_SHA384: ++ memcpy(req->result, sha384_zero_message_hash, digestsize); ++ break; ++ case RK_CRYPTO_SHA512: ++ memcpy(req->result, sha512_zero_message_hash, digestsize); ++ break; ++ case RK_CRYPTO_MD5: ++ memcpy(req->result, md5_zero_message_hash, digestsize); ++ break; ++ case RK_CRYPTO_SM3: ++ memcpy(req->result, sm3_zero_message_hash, digestsize); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++int rk_ahash_init(struct ahash_request *req) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); ++ rctx->fallback_req.base.flags = req->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ return crypto_ahash_init(&rctx->fallback_req); ++} ++ ++int rk_ahash_update(struct ahash_request *req) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); ++ rctx->fallback_req.base.flags = req->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ rctx->fallback_req.nbytes = req->nbytes; ++ rctx->fallback_req.src = req->src; ++ ++ return crypto_ahash_update(&rctx->fallback_req); ++} ++ ++int rk_ahash_final(struct ahash_request *req) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); ++ rctx->fallback_req.base.flags = req->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ rctx->fallback_req.result = req->result; ++ ++ return crypto_ahash_final(&rctx->fallback_req); ++} ++ ++int rk_ahash_finup(struct ahash_request *req) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); ++ rctx->fallback_req.base.flags = req->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ rctx->fallback_req.nbytes = req->nbytes; ++ rctx->fallback_req.src = req->src; ++ rctx->fallback_req.result = req->result; ++ ++ return crypto_ahash_finup(&rctx->fallback_req); ++} ++ ++int rk_ahash_import(struct ahash_request *req, const void *in) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); ++ rctx->fallback_req.base.flags = req->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ return crypto_ahash_import(&rctx->fallback_req, in); ++} ++ ++int rk_ahash_export(struct ahash_request *req, void *out) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); ++ rctx->fallback_req.base.flags = req->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ return crypto_ahash_export(&rctx->fallback_req, out); ++} ++ ++int rk_ahash_digest(struct ahash_request *req) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct rk_crypto_dev *dev; ++ struct crypto_engine *engine; ++ ++ if (rk_ahash_need_fallback(req)) ++ return rk_ahash_digest_fb(req); ++ ++ if (!req->nbytes) ++ return zero_message_process(req); ++ ++ dev = get_rk_crypto(); ++ ++ rctx->dev = dev; ++ engine = dev->engine; ++ ++ return crypto_transfer_hash_request_to_engine(engine, req); ++} ++ ++static int rk_hash_prepare(struct crypto_engine *engine, void *breq) ++{ ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_crypto_dev *rkc = rctx->dev; ++ int ret; ++ ++ ret = dma_map_sg(rkc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); ++ if (ret <= 0) ++ return -EINVAL; ++ ++ rctx->nrsgs = ret; ++ ++ return 0; ++} ++ ++static int rk_hash_unprepare(struct crypto_engine *engine, void *breq) ++{ ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_crypto_dev *rkc = rctx->dev; ++ ++ dma_unmap_sg(rkc->dev, areq->src, rctx->nrsgs, DMA_TO_DEVICE); ++ return 0; ++} ++ ++static int rk_hash_run(struct crypto_engine *engine, void *breq) ++{ ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.hash); ++ struct scatterlist *sgs = areq->src; ++ struct rk_crypto_dev *rkc = rctx->dev; ++ struct rk_crypto_lli *dd = &rkc->tl[0]; ++ int ddi = 0; ++ int err = 0; ++ unsigned int len = areq->nbytes; ++ unsigned int todo; ++ u32 v; ++ int i; ++ ++ err = pm_runtime_resume_and_get(rkc->dev); ++ if (err) ++ return err; ++ ++ dev_dbg(rkc->dev, "%s %s len=%d\n", __func__, ++ crypto_tfm_alg_name(areq->base.tfm), areq->nbytes); ++ ++ algt->stat_req++; ++ rkc->nreq++; ++ ++ rctx->mode = algt->rk_mode; ++ rctx->mode |= 0xffff0000; ++ rctx->mode |= RK_CRYPTO_ENABLE | RK_CRYPTO_HW_PAD; ++ writel(rctx->mode, rkc->reg + RK_CRYPTO_HASH_CTL); ++ ++ while (sgs && len > 0) { ++ dd = &rkc->tl[ddi]; ++ ++ todo = min(sg_dma_len(sgs), len); ++ dd->src_addr = sg_dma_address(sgs); ++ dd->src_len = todo; ++ dd->dst_addr = 0; ++ dd->dst_len = 0; ++ dd->dma_ctrl = ddi << 24; ++ dd->iv = 0; ++ dd->next = rkc->t_phy + sizeof(struct rk_crypto_lli) * (ddi + 1); ++ ++ if (ddi == 0) ++ dd->user = RK_LLI_CIPHER_START | RK_LLI_STRING_FIRST; ++ else ++ dd->user = 0; ++ ++ len -= todo; ++ dd->dma_ctrl |= RK_LLI_DMA_CTRL_SRC_INT; ++ if (len == 0) { ++ dd->user |= RK_LLI_STRING_LAST; ++ dd->dma_ctrl |= RK_LLI_DMA_CTRL_LAST; ++ } ++ dev_dbg(rkc->dev, "HASH SG %d sglen=%d user=%x dma=%x mode=%x len=%d todo=%d phy=%llx\n", ++ ddi, sgs->length, dd->user, dd->dma_ctrl, rctx->mode, len, todo, rkc->t_phy); ++ ++ sgs = sg_next(sgs); ++ ddi++; ++ } ++ dd->next = 1; ++ writel(RK_CRYPTO_DMA_INT_LISTDONE | 0x7F, rkc->reg + RK_CRYPTO_DMA_INT_EN); ++ ++ writel(rkc->t_phy, rkc->reg + RK_CRYPTO_DMA_LLI_ADDR); ++ ++ reinit_completion(&rkc->complete); ++ rkc->status = 0; ++ ++ writel(RK_CRYPTO_DMA_CTL_START | 1 << 16, rkc->reg + RK_CRYPTO_DMA_CTL); ++ ++ wait_for_completion_interruptible_timeout(&rkc->complete, ++ msecs_to_jiffies(2000)); ++ if (!rkc->status) { ++ dev_err(rkc->dev, "DMA timeout\n"); ++ err = -EFAULT; ++ goto theend; ++ } ++ ++ readl_poll_timeout_atomic(rkc->reg + RK_CRYPTO_HASH_VALID, v, v == 1, ++ 10, 1000); ++ ++ for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) { ++ v = readl(rkc->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4); ++ put_unaligned_le32(be32_to_cpu(v), areq->result + i * 4); ++ } ++ ++theend: ++ pm_runtime_put_autosuspend(rkc->dev); ++ ++ local_bh_disable(); ++ crypto_finalize_hash_request(engine, breq, err); ++ local_bh_enable(); ++ ++ return 0; ++} ++ ++int rk_cra_hash_init(struct crypto_tfm *tfm) ++{ ++ struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); ++ const char *alg_name = crypto_tfm_alg_name(tfm); ++ struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.hash); ++ ++ /* for fallback */ ++ tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0, ++ CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(tctx->fallback_tfm)) { ++ dev_err(algt->dev->dev, "Could not load fallback driver.\n"); ++ return PTR_ERR(tctx->fallback_tfm); ++ } ++ ++ crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), ++ sizeof(struct rk_ahash_rctx) + ++ crypto_ahash_reqsize(tctx->fallback_tfm)); ++ ++ tctx->enginectx.op.do_one_request = rk_hash_run; ++ tctx->enginectx.op.prepare_request = rk_hash_prepare; ++ tctx->enginectx.op.unprepare_request = rk_hash_unprepare; ++ ++ return 0; ++} ++ ++void rk_cra_hash_exit(struct crypto_tfm *tfm) ++{ ++ struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); ++ ++ crypto_free_ahash(tctx->fallback_tfm); ++} +--- /dev/null ++++ b/drivers/crypto/rockchip/rk3588_crypto_skcipher.c +@@ -0,0 +1,340 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * hardware cryptographic offloader for rk3568/rk3588 SoC ++ * ++ * Copyright (c) 2022 Corentin Labbe ++ */ ++#include ++#include "rk3588_crypto.h" ++ ++static int rk_cipher_need_fallback(struct skcipher_request *req) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.skcipher); ++ struct scatterlist *sgs, *sgd; ++ unsigned int stodo, dtodo, len; ++ unsigned int bs = crypto_skcipher_blocksize(tfm); ++ ++ if (!req->cryptlen) ++ return true; ++ ++ len = req->cryptlen; ++ sgs = req->src; ++ sgd = req->dst; ++ while (sgs && sgd) { ++ if (!IS_ALIGNED(sgs->offset, sizeof(u32))) { ++ algt->stat_fb_align++; ++ return true; ++ } ++ if (!IS_ALIGNED(sgd->offset, sizeof(u32))) { ++ algt->stat_fb_align++; ++ return true; ++ } ++ stodo = min(len, sgs->length); ++ if (stodo % bs) { ++ algt->stat_fb_len++; ++ return true; ++ } ++ dtodo = min(len, sgd->length); ++ if (dtodo % bs) { ++ algt->stat_fb_len++; ++ return true; ++ } ++ if (stodo != dtodo) { ++ algt->stat_fb_sgdiff++; ++ return true; ++ } ++ len -= stodo; ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ } ++ return false; ++} ++ ++static int rk_cipher_fallback(struct skcipher_request *areq) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); ++ struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.skcipher); ++ int err; ++ ++ algt->stat_fb++; ++ ++ skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm); ++ skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags, ++ areq->base.complete, areq->base.data); ++ skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst, ++ areq->cryptlen, areq->iv); ++ if (rctx->mode & RK_CRYPTO_DEC) ++ err = crypto_skcipher_decrypt(&rctx->fallback_req); ++ else ++ err = crypto_skcipher_encrypt(&rctx->fallback_req); ++ return err; ++} ++ ++static int rk_cipher_handle_req(struct skcipher_request *req) ++{ ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); ++ struct rk_crypto_dev *rkc; ++ struct crypto_engine *engine; ++ ++ if (rk_cipher_need_fallback(req)) ++ return rk_cipher_fallback(req); ++ ++ rkc = get_rk_crypto(); ++ ++ engine = rkc->engine; ++ rctx->dev = rkc; ++ ++ return crypto_transfer_skcipher_request_to_engine(engine, req); ++} ++ ++int rk_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, ++ unsigned int keylen) ++{ ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); ++ struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 && ++ keylen != AES_KEYSIZE_256) ++ return -EINVAL; ++ ctx->keylen = keylen; ++ memcpy(ctx->key, key, keylen); ++ ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); ++} ++ ++int rk_aes_ecb_encrypt(struct skcipher_request *req) ++{ ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); ++ ++ rctx->mode = RK_CRYPTO_AES_ECB_MODE; ++ return rk_cipher_handle_req(req); ++} ++ ++int rk_aes_ecb_decrypt(struct skcipher_request *req) ++{ ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); ++ ++ rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; ++ return rk_cipher_handle_req(req); ++} ++ ++int rk_aes_cbc_encrypt(struct skcipher_request *req) ++{ ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); ++ ++ rctx->mode = RK_CRYPTO_AES_CBC_MODE; ++ return rk_cipher_handle_req(req); ++} ++ ++int rk_aes_cbc_decrypt(struct skcipher_request *req) ++{ ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); ++ ++ rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; ++ return rk_cipher_handle_req(req); ++} ++ ++static int rk_cipher_run(struct crypto_engine *engine, void *async_req) ++{ ++ struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base); ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct scatterlist *sgs, *sgd; ++ int err = 0; ++ int ivsize = crypto_skcipher_ivsize(tfm); ++ unsigned int len = areq->cryptlen; ++ unsigned int todo; ++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.skcipher); ++ struct rk_crypto_dev *rkc = rctx->dev; ++ struct rk_crypto_lli *dd = &rkc->tl[0]; ++ u32 m, v; ++ u32 *rkey = (u32 *)ctx->key; ++ u32 *riv = (u32 *)areq->iv; ++ int i; ++ unsigned int offset; ++ ++ err = pm_runtime_resume_and_get(rkc->dev); ++ if (err) ++ return err; ++ ++ algt->stat_req++; ++ rkc->nreq++; ++ ++ m = rctx->mode | RK_CRYPTO_ENABLE; ++ switch (ctx->keylen) { ++ case AES_KEYSIZE_128: ++ m |= RK_CRYPTO_AES_128BIT_key; ++ break; ++ case AES_KEYSIZE_192: ++ m |= RK_CRYPTO_AES_192BIT_key; ++ break; ++ case AES_KEYSIZE_256: ++ m |= RK_CRYPTO_AES_256BIT_key; ++ break; ++ } ++ /* the upper bits are a write enable mask, so we need to write 1 to all ++ * upper 16 bits to allow write to the 16 lower bits ++ */ ++ m |= 0xffff0000; ++ ++ dev_dbg(rkc->dev, "%s %s len=%u keylen=%u mode=%x\n", __func__, ++ crypto_tfm_alg_name(areq->base.tfm), ++ areq->cryptlen, ctx->keylen, m); ++ sgs = areq->src; ++ sgd = areq->dst; ++ ++ while (sgs && sgd && len) { ++ ivsize = crypto_skcipher_ivsize(tfm); ++ if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) { ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ offset = sgs->length - ivsize; ++ scatterwalk_map_and_copy(rctx->backup_iv, sgs, ++ offset, ivsize, 0); ++ } ++ } ++ ++ if (sgs == sgd) { ++ err = dma_map_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ if (err != 1) { ++ dev_err(rkc->dev, "Invalid sg number %d\n", err); ++ err = -EINVAL; ++ goto theend; ++ } ++ } else { ++ err = dma_map_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE); ++ if (err != 1) { ++ dev_err(rkc->dev, "Invalid sg number %d\n", err); ++ err = -EINVAL; ++ goto theend; ++ } ++ err = dma_map_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE); ++ if (err != 1) { ++ dev_err(rkc->dev, "Invalid sg number %d\n", err); ++ err = -EINVAL; ++ dma_unmap_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE); ++ goto theend; ++ } ++ } ++ err = 0; ++ writel(m, rkc->reg + RK_CRYPTO_BC_CTL); ++ ++ for (i = 0; i < ctx->keylen / 4; i++) { ++ v = cpu_to_be32(rkey[i]); ++ writel(v, rkc->reg + RK_CRYPTO_KEY0 + i * 4); ++ } ++ ++ if (ivsize) { ++ for (i = 0; i < ivsize / 4; i++) ++ writel(cpu_to_be32(riv[i]), ++ rkc->reg + RK_CRYPTO_CH0_IV_0 + i * 4); ++ writel(ivsize, rkc->reg + RK_CRYPTO_CH0_IV_LEN); ++ } ++ if (!sgs->length) { ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ continue; ++ } ++ ++ /* The hw support multiple descriptor, so why this driver use ++ * only one descritor ? ++ * Using one descriptor per SG seems the way to do and it works ++ * but only when doing encryption. ++ * With decryption it always fail on second descriptor. ++ * Probably the HW dont know how to use IV. ++ */ ++ todo = min(sg_dma_len(sgs), len); ++ len -= todo; ++ dd->src_addr = sg_dma_address(sgs); ++ dd->src_len = todo; ++ dd->dst_addr = sg_dma_address(sgd); ++ dd->dst_len = todo; ++ dd->iv = 0; ++ dd->next = 1; ++ ++ dd->user = RK_LLI_CIPHER_START | RK_LLI_STRING_FIRST | RK_LLI_STRING_LAST; ++ dd->dma_ctrl |= RK_LLI_DMA_CTRL_DST_INT | RK_LLI_DMA_CTRL_LAST; ++ ++ writel(RK_CRYPTO_DMA_INT_LISTDONE | 0x7F, rkc->reg + RK_CRYPTO_DMA_INT_EN); ++ ++ writel(rkc->t_phy, rkc->reg + RK_CRYPTO_DMA_LLI_ADDR); ++ ++ reinit_completion(&rkc->complete); ++ rkc->status = 0; ++ ++ writel(RK_CRYPTO_DMA_CTL_START | 1 << 16, rkc->reg + RK_CRYPTO_DMA_CTL); ++ ++ wait_for_completion_interruptible_timeout(&rkc->complete, ++ msecs_to_jiffies(10000)); ++ if (sgs == sgd) { ++ dma_unmap_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ } else { ++ dma_unmap_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE); ++ } ++ ++ if (!rkc->status) { ++ dev_err(rkc->dev, "DMA timeout\n"); ++ err = -EFAULT; ++ goto theend; ++ } ++ if (areq->iv && ivsize > 0) { ++ offset = sgd->length - ivsize; ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ memcpy(areq->iv, rctx->backup_iv, ivsize); ++ memzero_explicit(rctx->backup_iv, ivsize); ++ } else { ++ scatterwalk_map_and_copy(areq->iv, sgd, offset, ++ ivsize, 0); ++ } ++ } ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ } ++theend: ++ writel(0xffff0000, rkc->reg + RK_CRYPTO_BC_CTL); ++ pm_runtime_put_autosuspend(rkc->dev); ++ ++ local_bh_disable(); ++ crypto_finalize_skcipher_request(engine, areq, err); ++ local_bh_enable(); ++ return 0; ++} ++ ++int rk_cipher_tfm_init(struct crypto_skcipher *tfm) ++{ ++ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ const char *name = crypto_tfm_alg_name(&tfm->base); ++ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ struct rk_crypto_template *algt = container_of(alg, struct rk_crypto_template, alg.skcipher); ++ ++ ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->fallback_tfm)) { ++ dev_err(algt->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n", ++ name, PTR_ERR(ctx->fallback_tfm)); ++ return PTR_ERR(ctx->fallback_tfm); ++ } ++ ++ tfm->reqsize = sizeof(struct rk_cipher_rctx) + ++ crypto_skcipher_reqsize(ctx->fallback_tfm); ++ ++ ctx->enginectx.op.do_one_request = rk_cipher_run; ++ ctx->enginectx.op.prepare_request = NULL; ++ ctx->enginectx.op.unprepare_request = NULL; ++ ++ return 0; ++} ++ ++void rk_cipher_tfm_exit(struct crypto_skcipher *tfm) ++{ ++ struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ ++ memzero_explicit(ctx->key, ctx->keylen); ++ crypto_free_skcipher(ctx->fallback_tfm); ++} diff --git a/target/linux/rockchip/patches-6.1/217-ARM64-dts-rk3568-add-crypto-node.patch b/target/linux/rockchip/patches-6.1/217-ARM64-dts-rk3568-add-crypto-node.patch new file mode 100644 index 000000000..ca2cfbf87 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/217-ARM64-dts-rk3568-add-crypto-node.patch @@ -0,0 +1,36 @@ +From 5055f9e39713f9e5303bbcdc3712909a462dd3c2 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Tue, 27 Sep 2022 08:00:48 +0000 +Subject: [PATCH 5/5] ARM64: dts: rk3568: add crypto node + +The rk3568 has a crypto IP handled by the rk3588 crypto driver so adds a +node for it. + +Signed-off-by: Corentin Labbe +--- + arch/arm64/boot/dts/rockchip/rk3568.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -211,6 +211,20 @@ + }; + }; + ++ crypto: crypto@fe380000 { ++ compatible = "rockchip,rk3568-crypto"; ++ reg = <0x0 0xfe380000 0x0 0x2000>; ++ interrupts = ; ++ clocks = <&cru ACLK_CRYPTO_NS>, <&cru HCLK_CRYPTO_NS>, ++ <&cru CLK_CRYPTO_NS_CORE>, <&cru CLK_CRYPTO_NS_PKA>; ++ clock-names = "aclk", "hclk", "sclk", "pka"; ++ resets = <&cru SRST_CRYPTO_NS_CORE>, <&cru SRST_A_CRYPTO_NS>, ++ <&cru SRST_H_CRYPTO_NS>, <&cru SRST_CRYPTO_NS_RNG>, ++ <&cru SRST_CRYPTO_NS_PKA>; ++ reset-names = "core", "a", "h", "rng,", "pka"; ++ status = "okay"; ++ }; ++ + combphy0: phy@fe820000 { + compatible = "rockchip,rk3568-naneng-combphy"; + reg = <0x0 0xfe820000 0x0 0x100>; diff --git a/target/linux/rockchip/patches-6.1/218-fix-build-crypto.patch b/target/linux/rockchip/patches-6.1/218-fix-build-crypto.patch new file mode 100644 index 000000000..234e69b56 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/218-fix-build-crypto.patch @@ -0,0 +1,21 @@ +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -24,18 +24,6 @@ static struct rockchip_ip rocklist = { + .lock = __SPIN_LOCK_UNLOCKED(rocklist.lock), + }; + +-struct rk_crypto_info *get_rk_crypto(void) +-{ +- struct rk_crypto_info *first; +- +- spin_lock(&rocklist.lock); +- first = list_first_entry_or_null(&rocklist.dev_list, +- struct rk_crypto_info, list); +- list_rotate_left(&rocklist.dev_list); +- spin_unlock(&rocklist.lock); +- return first; +-} +- + static const struct rk_variant rk3288_variant = { + .num_clks = 4, + .rkclks = { diff --git a/target/linux/rockchip/patches-6.1/801-char-add-support-for-rockchip-hardware-random-number.patch b/target/linux/rockchip/patches-6.1/801-char-add-support-for-rockchip-hardware-random-number.patch new file mode 100644 index 000000000..bf479e5f6 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/801-char-add-support-for-rockchip-hardware-random-number.patch @@ -0,0 +1,45 @@ +From e5b5361651940ff5c0c1784dfd0130abec7ab535 Mon Sep 17 00:00:00 2001 +From: wevsty +Date: Mon, 24 Aug 2020 02:27:11 +0800 +Subject: [PATCH] char: add support for rockchip hardware random number + generator + +This patch provides hardware random number generator support for all rockchip SOC. + +rockchip-rng.c from https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/char/hw_random/rockchip-rng.c + +Signed-off-by: wevsty +--- + +--- a/drivers/char/hw_random/Kconfig ++++ b/drivers/char/hw_random/Kconfig +@@ -372,6 +372,19 @@ config HW_RANDOM_STM32 + + If unsure, say N. + ++config HW_RANDOM_ROCKCHIP ++ tristate "Rockchip Random Number Generator support" ++ depends on ARCH_ROCKCHIP ++ default HW_RANDOM ++ help ++ This driver provides kernel-side support for the Random Number ++ Generator hardware found on Rockchip cpus. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called rockchip-rng. ++ ++ If unsure, say Y. ++ + config HW_RANDOM_PIC32 + tristate "Microchip PIC32 Random Number Generator support" + depends on HW_RANDOM && MACH_PIC32 +--- a/drivers/char/hw_random/Makefile ++++ b/drivers/char/hw_random/Makefile +@@ -34,6 +34,7 @@ obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += + obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o + obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o + obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o ++obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o + obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o + obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o + obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o diff --git a/target/linux/rockchip/patches-6.1/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch b/target/linux/rockchip/patches-6.1/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch new file mode 100644 index 000000000..555182f60 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch @@ -0,0 +1,69 @@ +From e5b5361651940ff5c0c1784dfd0130abec7ab535 Mon Sep 17 00:00:00 2001 +From: wevsty +Date: Mon, 24 Aug 2020 02:27:11 +0800 +Subject: [PATCH] arm64: dts: rockchip: add hardware random number generator + for RK3328 and RK3399 + +Adding Hardware Random Number Generator Resources to the RK3328 and RK3399. + +Signed-off-by: wevsty +--- + +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -279,6 +279,17 @@ + status = "disabled"; + }; + ++ rng: rng@ff060000 { ++ compatible = "rockchip,cryptov1-rng"; ++ reg = <0x0 0xff060000 0x0 0x4000>; ++ ++ clocks = <&cru SCLK_CRYPTO>, <&cru HCLK_CRYPTO_SLV>; ++ clock-names = "clk_crypto", "hclk_crypto"; ++ assigned-clocks = <&cru SCLK_CRYPTO>, <&cru HCLK_CRYPTO_SLV>; ++ assigned-clock-rates = <150000000>, <100000000>; ++ status = "disabled"; ++ }; ++ + grf: syscon@ff100000 { + compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd"; + reg = <0x0 0xff100000 0x0 0x1000>; +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -2043,6 +2043,16 @@ + }; + }; + ++ rng: rng@ff8b8000 { ++ compatible = "rockchip,cryptov1-rng"; ++ reg = <0x0 0xff8b8000 0x0 0x1000>; ++ clocks = <&cru SCLK_CRYPTO1>, <&cru HCLK_S_CRYPTO1>; ++ clock-names = "clk_crypto", "hclk_crypto"; ++ assigned-clocks = <&cru SCLK_CRYPTO1>, <&cru HCLK_S_CRYPTO1>; ++ assigned-clock-rates = <150000000>, <100000000>; ++ status = "okay"; ++ }; ++ + gpu: gpu@ff9a0000 { + compatible = "rockchip,rk3399-mali", "arm,mali-t860"; + reg = <0x0 0xff9a0000 0x0 0x10000>; +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -211,6 +211,16 @@ + }; + }; + ++ rng: rng@fe388000 { ++ compatible = "rockchip,cryptov2-rng"; ++ reg = <0x0 0xfe388000 0x0 0x2000>; ++ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>; ++ clock-names = "clk_trng", "hclk_trng"; ++ resets = <&cru SRST_TRNG_NS>; ++ reset-names = "reset"; ++ status = "disabled"; ++ }; ++ + combphy0: phy@fe820000 { + compatible = "rockchip,rk3568-naneng-combphy"; + reg = <0x0 0xfe820000 0x0 0x100>; diff --git a/target/linux/rockchip/patches-6.1/803-PM-devfreq-rockchip-add-devfreq-driver-for-rk3328-dmc.patch b/target/linux/rockchip/patches-6.1/803-PM-devfreq-rockchip-add-devfreq-driver-for-rk3328-dmc.patch new file mode 100644 index 000000000..d85cd1ce3 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/803-PM-devfreq-rockchip-add-devfreq-driver-for-rk3328-dmc.patch @@ -0,0 +1,44 @@ +From fcd9629c05f373771e85920e1c1d0ab252617878 Mon Sep 17 00:00:00 2001 +From: hmz007 +Date: Tue, 19 Nov 2019 13:53:25 +0800 +Subject: [PATCH] PM / devfreq: rockchip: add devfreq driver for rk3328 dmc + +Signed-off-by: hmz007 +--- + drivers/devfreq/Kconfig | 18 +- + drivers/devfreq/Makefile | 1 + + drivers/devfreq/rk3328_dmc.c | 846 +++++++++++++++++++++++++++++++++++ + 3 files changed, 862 insertions(+), 3 deletions(-) + create mode 100644 drivers/devfreq/rk3328_dmc.c + +--- a/drivers/devfreq/Kconfig ++++ b/drivers/devfreq/Kconfig +@@ -130,6 +130,18 @@ config ARM_MEDIATEK_CCI_DEVFREQ + buck voltages and update a proper CCI frequency. Use the notification + to get the regulator status. + ++config ARM_RK3328_DMC_DEVFREQ ++ tristate "ARM RK3328 DMC DEVFREQ Driver" ++ depends on ARCH_ROCKCHIP ++ select DEVFREQ_EVENT_ROCKCHIP_DFI ++ select DEVFREQ_GOV_SIMPLE_ONDEMAND ++ select PM_DEVFREQ_EVENT ++ select PM_OPP ++ help ++ This adds the DEVFREQ driver for the RK3328 DMC(Dynamic Memory Controller). ++ It sets the frequency for the memory controller and reads the usage counts ++ from hardware. ++ + config ARM_RK3399_DMC_DEVFREQ + tristate "ARM RK3399 DMC DEVFREQ Driver" + depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \ +--- a/drivers/devfreq/Makefile ++++ b/drivers/devfreq/Makefile +@@ -12,6 +12,7 @@ obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += + obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o + obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o + obj-$(CONFIG_ARM_MEDIATEK_CCI_DEVFREQ) += mtk-cci-devfreq.o ++obj-$(CONFIG_ARM_RK3328_DMC_DEVFREQ) += rk3328_dmc.o + obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o + obj-$(CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ) += sun8i-a33-mbus.o + obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-devfreq.o diff --git a/target/linux/rockchip/patches-6.1/804-clk-rockchip-support-setting-ddr-clock-via-SIP-Version-2-.patch b/target/linux/rockchip/patches-6.1/804-clk-rockchip-support-setting-ddr-clock-via-SIP-Version-2-.patch new file mode 100644 index 000000000..14f69157b --- /dev/null +++ b/target/linux/rockchip/patches-6.1/804-clk-rockchip-support-setting-ddr-clock-via-SIP-Version-2-.patch @@ -0,0 +1,210 @@ +From ce6d3614888e6358466f0e84e248177a6bca5258 Mon Sep 17 00:00:00 2001 +From: Tang Yun ping +Date: Thu, 4 May 2017 20:49:58 +0800 +Subject: [PATCH] clk: rockchip: support setting ddr clock via SIP Version 2 + APIs + +commit 764e893ee82321938fc6f4349e9e7caf06a04410 rockchip. + +Signed-off-by: Tang Yun ping +Signed-off-by: hmz007 +--- + drivers/clk/rockchip/clk-ddr.c | 130 ++++++++++++++++++++++++++++ + drivers/clk/rockchip/clk-rk3328.c | 7 +- + drivers/clk/rockchip/clk.h | 3 +- + include/soc/rockchip/rockchip_sip.h | 11 +++ + 4 files changed, 147 insertions(+), 4 deletions(-) + +--- a/drivers/clk/rockchip/clk-ddr.c ++++ b/drivers/clk/rockchip/clk-ddr.c +@@ -87,6 +87,133 @@ static const struct clk_ops rockchip_ddr + .get_parent = rockchip_ddrclk_get_parent, + }; + ++/* See v4.4/include/dt-bindings/display/rk_fb.h */ ++#define SCREEN_NULL 0 ++#define SCREEN_HDMI 6 ++ ++static inline int rk_drm_get_lcdc_type(void) ++{ ++ return SCREEN_NULL; ++} ++ ++struct share_params { ++ u32 hz; ++ u32 lcdc_type; ++ u32 vop; ++ u32 vop_dclk_mode; ++ u32 sr_idle_en; ++ u32 addr_mcu_el3; ++ /* ++ * 1: need to wait flag1 ++ * 0: never wait flag1 ++ */ ++ u32 wait_flag1; ++ /* ++ * 1: need to wait flag1 ++ * 0: never wait flag1 ++ */ ++ u32 wait_flag0; ++ u32 complt_hwirq; ++ /* if need, add parameter after */ ++}; ++ ++struct rockchip_ddrclk_data { ++ u32 inited_flag; ++ void __iomem *share_memory; ++}; ++ ++static struct rockchip_ddrclk_data ddr_data; ++ ++static void rockchip_ddrclk_data_init(void) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_SHARE_MEM, ++ 1, SHARE_PAGE_TYPE_DDR, 0, ++ 0, 0, 0, 0, &res); ++ ++ if (!res.a0) { ++ ddr_data.share_memory = (void __iomem *)ioremap(res.a1, 1<<12); ++ ddr_data.inited_flag = 1; ++ } ++} ++ ++static int rockchip_ddrclk_sip_set_rate_v2(struct clk_hw *hw, ++ unsigned long drate, ++ unsigned long prate) ++{ ++ struct share_params *p; ++ struct arm_smccc_res res; ++ ++ if (!ddr_data.inited_flag) ++ rockchip_ddrclk_data_init(); ++ ++ p = (struct share_params *)ddr_data.share_memory; ++ ++ p->hz = drate; ++ p->lcdc_type = rk_drm_get_lcdc_type(); ++ p->wait_flag1 = 1; ++ p->wait_flag0 = 1; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ SHARE_PAGE_TYPE_DDR, 0, ++ ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE, ++ 0, 0, 0, 0, &res); ++ ++ if ((int)res.a1 == -6) { ++ pr_err("%s: timeout, drate = %lumhz\n", __func__, drate/1000000); ++ /* TODO: rockchip_dmcfreq_wait_complete(); */ ++ } ++ ++ return res.a0; ++} ++ ++static unsigned long rockchip_ddrclk_sip_recalc_rate_v2 ++ (struct clk_hw *hw, unsigned long parent_rate) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ SHARE_PAGE_TYPE_DDR, 0, ++ ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE, ++ 0, 0, 0, 0, &res); ++ if (!res.a0) ++ return res.a1; ++ else ++ return 0; ++} ++ ++static long rockchip_ddrclk_sip_round_rate_v2(struct clk_hw *hw, ++ unsigned long rate, ++ unsigned long *prate) ++{ ++ struct share_params *p; ++ struct arm_smccc_res res; ++ ++ if (!ddr_data.inited_flag) ++ rockchip_ddrclk_data_init(); ++ ++ p = (struct share_params *)ddr_data.share_memory; ++ ++ p->hz = rate; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ SHARE_PAGE_TYPE_DDR, 0, ++ ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE, ++ 0, 0, 0, 0, &res); ++ if (!res.a0) ++ return res.a1; ++ else ++ return 0; ++} ++ ++static const struct clk_ops rockchip_ddrclk_sip_ops_v2 = { ++ .recalc_rate = rockchip_ddrclk_sip_recalc_rate_v2, ++ .set_rate = rockchip_ddrclk_sip_set_rate_v2, ++ .round_rate = rockchip_ddrclk_sip_round_rate_v2, ++ .get_parent = rockchip_ddrclk_get_parent, ++}; ++ + struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, + const char *const *parent_names, + u8 num_parents, int mux_offset, +@@ -114,6 +241,9 @@ struct clk *rockchip_clk_register_ddrclk + case ROCKCHIP_DDRCLK_SIP: + init.ops = &rockchip_ddrclk_sip_ops; + break; ++ case ROCKCHIP_DDRCLK_SIP_V2: ++ init.ops = &rockchip_ddrclk_sip_ops_v2; ++ break; + default: + pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag); + kfree(ddrclk); +--- a/drivers/clk/rockchip/clk-rk3328.c ++++ b/drivers/clk/rockchip/clk-rk3328.c +@@ -315,9 +315,10 @@ static struct rockchip_clk_branch rk3328 + RK3328_CLKGATE_CON(14), 1, GFLAGS), + + /* PD_DDR */ +- COMPOSITE(0, "clk_ddr", mux_ddrphy_p, CLK_IGNORE_UNUSED, +- RK3328_CLKSEL_CON(3), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, +- RK3328_CLKGATE_CON(0), 4, GFLAGS), ++ COMPOSITE_DDRCLK(SCLK_DDRCLK, "sclk_ddrc", mux_ddrphy_p, 0, ++ RK3328_CLKSEL_CON(3), 8, 2, 0, 3, ++ ROCKCHIP_DDRCLK_SIP_V2), ++ + GATE(0, "clk_ddrmsch", "clk_ddr", CLK_IGNORE_UNUSED, + RK3328_CLKGATE_CON(18), 6, GFLAGS), + GATE(0, "clk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED, +--- a/drivers/clk/rockchip/clk.h ++++ b/drivers/clk/rockchip/clk.h +@@ -418,7 +418,8 @@ struct clk *rockchip_clk_register_mmc(co + * DDRCLK flags, including method of setting the rate + * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. + */ +-#define ROCKCHIP_DDRCLK_SIP BIT(0) ++#define ROCKCHIP_DDRCLK_SIP 0x01 ++#define ROCKCHIP_DDRCLK_SIP_V2 0x03 + + struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, + const char *const *parent_names, +--- a/include/soc/rockchip/rockchip_sip.h ++++ b/include/soc/rockchip/rockchip_sip.h +@@ -16,5 +16,16 @@ + #define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06 + #define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07 + #define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08 ++#define ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION 0x08 ++ ++#define ROCKCHIP_SIP_SHARE_MEM 0x82000009 ++ ++/* Share mem page types */ ++typedef enum { ++ SHARE_PAGE_TYPE_INVALID = 0, ++ SHARE_PAGE_TYPE_UARTDBG, ++ SHARE_PAGE_TYPE_DDR, ++ SHARE_PAGE_TYPE_MAX, ++} share_page_type_t; + + #endif diff --git a/target/linux/rockchip/patches-6.1/805-PM-devfreq-rockchip-dfi-add-more-soc-support.patch b/target/linux/rockchip/patches-6.1/805-PM-devfreq-rockchip-dfi-add-more-soc-support.patch new file mode 100644 index 000000000..0bde4e1c2 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/805-PM-devfreq-rockchip-dfi-add-more-soc-support.patch @@ -0,0 +1,662 @@ +From 4db93c6dad0c71750b86163df2fdb21c35f00d9a Mon Sep 17 00:00:00 2001 +From: hmz007 +Date: Tue, 19 Nov 2019 12:49:48 +0800 +Subject: [PATCH] PM / devfreq: rockchip-dfi: add more soc support + +Signed-off-by: hmz007 +--- + drivers/devfreq/event/rockchip-dfi.c | 554 ++++++++++++++++++++++++--- + 1 file changed, 505 insertions(+), 49 deletions(-) + +--- a/drivers/devfreq/event/rockchip-dfi.c ++++ b/drivers/devfreq/event/rockchip-dfi.c +@@ -18,25 +18,66 @@ + #include + #include + +-#include +- +-#define RK3399_DMC_NUM_CH 2 ++#define PX30_PMUGRF_OS_REG2 0x208 + ++#define RK3128_GRF_SOC_CON0 0x140 ++#define RK3128_GRF_OS_REG1 0x1cc ++#define RK3128_GRF_DFI_WRNUM 0x220 ++#define RK3128_GRF_DFI_RDNUM 0x224 ++#define RK3128_GRF_DFI_TIMERVAL 0x22c ++#define RK3128_DDR_MONITOR_EN ((1 << (16 + 6)) + (1 << 6)) ++#define RK3128_DDR_MONITOR_DISB ((1 << (16 + 6)) + (0 << 6)) ++ ++#define RK3288_PMU_SYS_REG2 0x9c ++#define RK3288_GRF_SOC_CON4 0x254 ++#define RK3288_GRF_SOC_STATUS(n) (0x280 + (n) * 4) ++#define RK3288_DFI_EN (0x30003 << 14) ++#define RK3288_DFI_DIS (0x30000 << 14) ++#define RK3288_LPDDR_SEL (0x10001 << 13) ++#define RK3288_DDR3_SEL (0x10000 << 13) ++ ++#define RK3328_GRF_OS_REG2 0x5d0 ++ ++#define RK3368_GRF_DDRC0_CON0 0x600 ++#define RK3368_GRF_SOC_STATUS5 0x494 ++#define RK3368_GRF_SOC_STATUS6 0x498 ++#define RK3368_GRF_SOC_STATUS8 0x4a0 ++#define RK3368_GRF_SOC_STATUS9 0x4a4 ++#define RK3368_GRF_SOC_STATUS10 0x4a8 ++#define RK3368_DFI_EN (0x30003 << 5) ++#define RK3368_DFI_DIS (0x30000 << 5) ++ ++#define MAX_DMC_NUM_CH 2 ++#define READ_DRAMTYPE_INFO(n) (((n) >> 13) & 0x7) ++#define READ_CH_INFO(n) (((n) >> 28) & 0x3) + /* DDRMON_CTRL */ +-#define DDRMON_CTRL 0x04 +-#define CLR_DDRMON_CTRL (0x1f0000 << 0) +-#define LPDDR4_EN (0x10001 << 4) +-#define HARDWARE_EN (0x10001 << 3) +-#define LPDDR3_EN (0x10001 << 2) +-#define SOFTWARE_EN (0x10001 << 1) +-#define SOFTWARE_DIS (0x10000 << 1) +-#define TIME_CNT_EN (0x10001 << 0) ++#define DDRMON_CTRL 0x04 ++#define CLR_DDRMON_CTRL (0x3f0000 << 0) ++#define DDR4_EN (0x10001 << 5) ++#define LPDDR4_EN (0x10001 << 4) ++#define HARDWARE_EN (0x10001 << 3) ++#define LPDDR2_3_EN (0x10001 << 2) ++#define SOFTWARE_EN (0x10001 << 1) ++#define SOFTWARE_DIS (0x10000 << 1) ++#define TIME_CNT_EN (0x10001 << 0) + + #define DDRMON_CH0_COUNT_NUM 0x28 + #define DDRMON_CH0_DFI_ACCESS_NUM 0x2c + #define DDRMON_CH1_COUNT_NUM 0x3c + #define DDRMON_CH1_DFI_ACCESS_NUM 0x40 + ++/* pmu grf */ ++#define PMUGRF_OS_REG2 0x308 ++ ++enum { ++ DDR4 = 0, ++ DDR3 = 3, ++ LPDDR2 = 5, ++ LPDDR3 = 6, ++ LPDDR4 = 7, ++ UNUSED = 0xFF ++}; ++ + struct dmc_usage { + u32 access; + u32 total; +@@ -50,33 +91,261 @@ struct dmc_usage { + struct rockchip_dfi { + struct devfreq_event_dev *edev; + struct devfreq_event_desc *desc; +- struct dmc_usage ch_usage[RK3399_DMC_NUM_CH]; ++ struct dmc_usage ch_usage[MAX_DMC_NUM_CH]; + struct device *dev; + void __iomem *regs; + struct regmap *regmap_pmu; ++ struct regmap *regmap_grf; ++ struct regmap *regmap_pmugrf; + struct clk *clk; ++ u32 dram_type; ++ /* ++ * available mask, 1: available, 0: not available ++ * each bit represent a channel ++ */ ++ u32 ch_msk; ++}; ++ ++static void rk3128_dfi_start_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, ++ RK3128_GRF_SOC_CON0, ++ RK3128_DDR_MONITOR_EN); ++} ++ ++static void rk3128_dfi_stop_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, ++ RK3128_GRF_SOC_CON0, ++ RK3128_DDR_MONITOR_DISB); ++} ++ ++static int rk3128_dfi_disable(struct devfreq_event_dev *edev) ++{ ++ rk3128_dfi_stop_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3128_dfi_enable(struct devfreq_event_dev *edev) ++{ ++ rk3128_dfi_start_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3128_dfi_set_event(struct devfreq_event_dev *edev) ++{ ++ return 0; ++} ++ ++static int rk3128_dfi_get_event(struct devfreq_event_dev *edev, ++ struct devfreq_event_data *edata) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ unsigned long flags; ++ u32 dfi_wr, dfi_rd, dfi_timer; ++ ++ local_irq_save(flags); ++ ++ rk3128_dfi_stop_hardware_counter(edev); ++ ++ regmap_read(info->regmap_grf, RK3128_GRF_DFI_WRNUM, &dfi_wr); ++ regmap_read(info->regmap_grf, RK3128_GRF_DFI_RDNUM, &dfi_rd); ++ regmap_read(info->regmap_grf, RK3128_GRF_DFI_TIMERVAL, &dfi_timer); ++ ++ edata->load_count = (dfi_wr + dfi_rd) * 4; ++ edata->total_count = dfi_timer; ++ ++ rk3128_dfi_start_hardware_counter(edev); ++ ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static const struct devfreq_event_ops rk3128_dfi_ops = { ++ .disable = rk3128_dfi_disable, ++ .enable = rk3128_dfi_enable, ++ .get_event = rk3128_dfi_get_event, ++ .set_event = rk3128_dfi_set_event, ++}; ++ ++static void rk3288_dfi_start_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_EN); ++} ++ ++static void rk3288_dfi_stop_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_DIS); ++} ++ ++static int rk3288_dfi_disable(struct devfreq_event_dev *edev) ++{ ++ rk3288_dfi_stop_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3288_dfi_enable(struct devfreq_event_dev *edev) ++{ ++ rk3288_dfi_start_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3288_dfi_set_event(struct devfreq_event_dev *edev) ++{ ++ return 0; ++} ++ ++static int rk3288_dfi_get_busier_ch(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ u32 tmp, max = 0; ++ u32 i, busier_ch = 0; ++ u32 rd_count, wr_count, total_count; ++ ++ rk3288_dfi_stop_hardware_counter(edev); ++ ++ /* Find out which channel is busier */ ++ for (i = 0; i < MAX_DMC_NUM_CH; i++) { ++ if (!(info->ch_msk & BIT(i))) ++ continue; ++ regmap_read(info->regmap_grf, ++ RK3288_GRF_SOC_STATUS(11 + i * 4), &wr_count); ++ regmap_read(info->regmap_grf, ++ RK3288_GRF_SOC_STATUS(12 + i * 4), &rd_count); ++ regmap_read(info->regmap_grf, ++ RK3288_GRF_SOC_STATUS(14 + i * 4), &total_count); ++ info->ch_usage[i].access = (wr_count + rd_count) * 4; ++ info->ch_usage[i].total = total_count; ++ tmp = info->ch_usage[i].access; ++ if (tmp > max) { ++ busier_ch = i; ++ max = tmp; ++ } ++ } ++ rk3288_dfi_start_hardware_counter(edev); ++ ++ return busier_ch; ++} ++ ++static int rk3288_dfi_get_event(struct devfreq_event_dev *edev, ++ struct devfreq_event_data *edata) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ int busier_ch; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ busier_ch = rk3288_dfi_get_busier_ch(edev); ++ local_irq_restore(flags); ++ ++ edata->load_count = info->ch_usage[busier_ch].access; ++ edata->total_count = info->ch_usage[busier_ch].total; ++ ++ return 0; ++} ++ ++static const struct devfreq_event_ops rk3288_dfi_ops = { ++ .disable = rk3288_dfi_disable, ++ .enable = rk3288_dfi_enable, ++ .get_event = rk3288_dfi_get_event, ++ .set_event = rk3288_dfi_set_event, ++}; ++ ++static void rk3368_dfi_start_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_EN); ++} ++ ++static void rk3368_dfi_stop_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_DIS); ++} ++ ++static int rk3368_dfi_disable(struct devfreq_event_dev *edev) ++{ ++ rk3368_dfi_stop_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3368_dfi_enable(struct devfreq_event_dev *edev) ++{ ++ rk3368_dfi_start_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3368_dfi_set_event(struct devfreq_event_dev *edev) ++{ ++ return 0; ++} ++ ++static int rk3368_dfi_get_event(struct devfreq_event_dev *edev, ++ struct devfreq_event_data *edata) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ unsigned long flags; ++ u32 dfi0_wr, dfi0_rd, dfi1_wr, dfi1_rd, dfi_timer; ++ ++ local_irq_save(flags); ++ ++ rk3368_dfi_stop_hardware_counter(edev); ++ ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS5, &dfi0_wr); ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS6, &dfi0_rd); ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS9, &dfi1_wr); ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS10, &dfi1_rd); ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS8, &dfi_timer); ++ ++ edata->load_count = (dfi0_wr + dfi0_rd + dfi1_wr + dfi1_rd) * 2; ++ edata->total_count = dfi_timer; ++ ++ rk3368_dfi_start_hardware_counter(edev); ++ ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static const struct devfreq_event_ops rk3368_dfi_ops = { ++ .disable = rk3368_dfi_disable, ++ .enable = rk3368_dfi_enable, ++ .get_event = rk3368_dfi_get_event, ++ .set_event = rk3368_dfi_set_event, + }; + + static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev) + { + struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); + void __iomem *dfi_regs = info->regs; +- u32 val; +- u32 ddr_type; +- +- /* get ddr type */ +- regmap_read(info->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val); +- ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) & +- RK3399_PMUGRF_DDRTYPE_MASK; + + /* clear DDRMON_CTRL setting */ + writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL); + + /* set ddr type to dfi */ +- if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3) +- writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL); +- else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4) ++ if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2) ++ writel_relaxed(LPDDR2_3_EN, dfi_regs + DDRMON_CTRL); ++ else if (info->dram_type == LPDDR4) + writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL); ++ else if (info->dram_type == DDR4) ++ writel_relaxed(DDR4_EN, dfi_regs + DDRMON_CTRL); + + /* enable count, use software mode */ + writel_relaxed(SOFTWARE_EN, dfi_regs + DDRMON_CTRL); +@@ -100,12 +369,22 @@ static int rockchip_dfi_get_busier_ch(st + rockchip_dfi_stop_hardware_counter(edev); + + /* Find out which channel is busier */ +- for (i = 0; i < RK3399_DMC_NUM_CH; i++) { +- info->ch_usage[i].access = readl_relaxed(dfi_regs + +- DDRMON_CH0_DFI_ACCESS_NUM + i * 20) * 4; ++ for (i = 0; i < MAX_DMC_NUM_CH; i++) { ++ if (!(info->ch_msk & BIT(i))) ++ continue; ++ + info->ch_usage[i].total = readl_relaxed(dfi_regs + + DDRMON_CH0_COUNT_NUM + i * 20); +- tmp = info->ch_usage[i].access; ++ ++ /* LPDDR4 BL = 16,other DDR type BL = 8 */ ++ tmp = readl_relaxed(dfi_regs + ++ DDRMON_CH0_DFI_ACCESS_NUM + i * 20); ++ if (info->dram_type == LPDDR4) ++ tmp *= 8; ++ else ++ tmp *= 4; ++ info->ch_usage[i].access = tmp; ++ + if (tmp > max) { + busier_ch = i; + max = tmp; +@@ -121,7 +400,8 @@ static int rockchip_dfi_disable(struct d + struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); + + rockchip_dfi_stop_hardware_counter(edev); +- clk_disable_unprepare(info->clk); ++ if (info->clk) ++ clk_disable_unprepare(info->clk); + + return 0; + } +@@ -131,10 +411,13 @@ static int rockchip_dfi_enable(struct de + struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); + int ret; + +- ret = clk_prepare_enable(info->clk); +- if (ret) { +- dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret); +- return ret; ++ if (info->clk) { ++ ret = clk_prepare_enable(info->clk); ++ if (ret) { ++ dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ++ ret); ++ return ret; ++ } + } + + rockchip_dfi_start_hardware_counter(edev); +@@ -151,8 +434,11 @@ static int rockchip_dfi_get_event(struct + { + struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); + int busier_ch; ++ unsigned long flags; + ++ local_irq_save(flags); + busier_ch = rockchip_dfi_get_busier_ch(edev); ++ local_irq_restore(flags); + + edata->load_count = info->ch_usage[busier_ch].access; + edata->total_count = info->ch_usage[busier_ch].total; +@@ -167,22 +453,116 @@ static const struct devfreq_event_ops ro + .set_event = rockchip_dfi_set_event, + }; + +-static const struct of_device_id rockchip_dfi_id_match[] = { +- { .compatible = "rockchip,rk3399-dfi" }, +- { }, +-}; +-MODULE_DEVICE_TABLE(of, rockchip_dfi_id_match); ++static __init int px30_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device_node *np = pdev->dev.of_node, *node; ++ struct resource *res; ++ u32 val; + +-static int rockchip_dfi_probe(struct platform_device *pdev) ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ data->regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(data->regs)) ++ return PTR_ERR(data->regs); ++ ++ node = of_parse_phandle(np, "rockchip,pmugrf", 0); ++ if (node) { ++ data->regmap_pmugrf = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_pmugrf)) ++ return PTR_ERR(data->regmap_pmugrf); ++ } ++ ++ regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG2, &val); ++ data->dram_type = READ_DRAMTYPE_INFO(val); ++ data->ch_msk = 1; ++ data->clk = NULL; ++ ++ desc->ops = &rockchip_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rk3128_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) + { +- struct device *dev = &pdev->dev; +- struct rockchip_dfi *data; +- struct devfreq_event_desc *desc; + struct device_node *np = pdev->dev.of_node, *node; + +- data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ node = of_parse_phandle(np, "rockchip,grf", 0); ++ if (node) { ++ data->regmap_grf = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_grf)) ++ return PTR_ERR(data->regmap_grf); ++ } ++ ++ desc->ops = &rk3128_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rk3288_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device_node *np = pdev->dev.of_node, *node; ++ u32 val; ++ ++ node = of_parse_phandle(np, "rockchip,pmu", 0); ++ if (node) { ++ data->regmap_pmu = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_pmu)) ++ return PTR_ERR(data->regmap_pmu); ++ } ++ ++ node = of_parse_phandle(np, "rockchip,grf", 0); ++ if (node) { ++ data->regmap_grf = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_grf)) ++ return PTR_ERR(data->regmap_grf); ++ } ++ ++ regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &val); ++ data->dram_type = READ_DRAMTYPE_INFO(val); ++ data->ch_msk = READ_CH_INFO(val); ++ ++ if (data->dram_type == DDR3) ++ regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4, ++ RK3288_DDR3_SEL); ++ else ++ regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4, ++ RK3288_LPDDR_SEL); ++ ++ desc->ops = &rk3288_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rk3368_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device *dev = &pdev->dev; ++ ++ if (!dev->parent || !dev->parent->of_node) ++ return -EINVAL; ++ ++ data->regmap_grf = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(data->regmap_grf)) ++ return PTR_ERR(data->regmap_grf); ++ ++ desc->ops = &rk3368_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rockchip_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = pdev->dev.of_node, *node; ++ u32 val; + + data->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(data->regs)) +@@ -201,21 +581,97 @@ static int rockchip_dfi_probe(struct pla + if (IS_ERR(data->regmap_pmu)) + return PTR_ERR(data->regmap_pmu); + } +- data->dev = dev; ++ ++ regmap_read(data->regmap_pmu, PMUGRF_OS_REG2, &val); ++ data->dram_type = READ_DRAMTYPE_INFO(val); ++ data->ch_msk = READ_CH_INFO(val); ++ ++ desc->ops = &rockchip_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rk3328_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device_node *np = pdev->dev.of_node, *node; ++ struct resource *res; ++ u32 val; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ data->regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(data->regs)) ++ return PTR_ERR(data->regs); ++ ++ node = of_parse_phandle(np, "rockchip,grf", 0); ++ if (node) { ++ data->regmap_grf = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_grf)) ++ return PTR_ERR(data->regmap_grf); ++ } ++ ++ regmap_read(data->regmap_grf, RK3328_GRF_OS_REG2, &val); ++ data->dram_type = READ_DRAMTYPE_INFO(val); ++ data->ch_msk = 1; ++ data->clk = NULL; ++ ++ desc->ops = &rockchip_dfi_ops; ++ ++ return 0; ++} ++ ++static const struct of_device_id rockchip_dfi_id_match[] = { ++ { .compatible = "rockchip,px30-dfi", .data = px30_dfi_init }, ++ { .compatible = "rockchip,rk1808-dfi", .data = px30_dfi_init }, ++ { .compatible = "rockchip,rk3128-dfi", .data = rk3128_dfi_init }, ++ { .compatible = "rockchip,rk3288-dfi", .data = rk3288_dfi_init }, ++ { .compatible = "rockchip,rk3328-dfi", .data = rk3328_dfi_init }, ++ { .compatible = "rockchip,rk3368-dfi", .data = rk3368_dfi_init }, ++ { .compatible = "rockchip,rk3399-dfi", .data = rockchip_dfi_init }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, rockchip_dfi_id_match); ++ ++static int rockchip_dfi_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct rockchip_dfi *data; ++ struct devfreq_event_desc *desc; ++ struct device_node *np = pdev->dev.of_node; ++ const struct of_device_id *match; ++ int (*init)(struct platform_device *pdev, struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc); ++ ++ data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + +- desc->ops = &rockchip_dfi_ops; ++ match = of_match_node(rockchip_dfi_id_match, pdev->dev.of_node); ++ if (match) { ++ init = match->data; ++ if (init) { ++ if (init(pdev, data, desc)) ++ return -EINVAL; ++ } else { ++ return 0; ++ } ++ } else { ++ return 0; ++ } ++ + desc->driver_data = data; + desc->name = np->name; + data->desc = desc; ++ data->dev = dev; + +- data->edev = devm_devfreq_event_add_edev(&pdev->dev, desc); ++ data->edev = devm_devfreq_event_add_edev(dev, desc); + if (IS_ERR(data->edev)) { +- dev_err(&pdev->dev, +- "failed to add devfreq-event device\n"); ++ dev_err(dev, "failed to add devfreq-event device\n"); + return PTR_ERR(data->edev); + } + diff --git a/target/linux/rockchip/patches-6.1/806-arm64-dts-rockchip-rk3328-add-dfi-node.patch b/target/linux/rockchip/patches-6.1/806-arm64-dts-rockchip-rk3328-add-dfi-node.patch new file mode 100644 index 000000000..6d8ce8da4 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/806-arm64-dts-rockchip-rk3328-add-dfi-node.patch @@ -0,0 +1,27 @@ +From f9ae6e992d3d9e80357fee7d65ba0fe2dd37ae1f Mon Sep 17 00:00:00 2001 +From: hmz007 +Date: Tue, 19 Nov 2019 14:21:51 +0800 +Subject: [PATCH] arm64: dts: rockchip: rk3328: add dfi node + +Signed-off-by: hmz007 +[adjusted commit title] +Signed-off-by: Tianling Shen +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 7 +++++++ + +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -1023,6 +1023,13 @@ + status = "disabled"; + }; + ++ dfi: dfi@ff790000 { ++ reg = <0x00 0xff790000 0x00 0x400>; ++ compatible = "rockchip,rk3328-dfi"; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; diff --git a/target/linux/rockchip/patches-6.1/807-arm64-dts-nanopi-r2s-add-rk3328-dmc-relate-node.patch b/target/linux/rockchip/patches-6.1/807-arm64-dts-nanopi-r2s-add-rk3328-dmc-relate-node.patch new file mode 100644 index 000000000..981bc70fb --- /dev/null +++ b/target/linux/rockchip/patches-6.1/807-arm64-dts-nanopi-r2s-add-rk3328-dmc-relate-node.patch @@ -0,0 +1,126 @@ +From f9ae6e992d3d9e80357fee7d65ba0fe2dd37ae1f Mon Sep 17 00:00:00 2001 +From: hmz007 +Date: Tue, 19 Nov 2019 14:21:51 +0800 +Subject: [PATCH] arm64: dts: nanopi-r2: add rk3328-dmc relate node + +Signed-off-by: hmz007 +--- + .../rockchip/rk3328-dram-default-timing.dtsi | 311 ++++++++++++++++++ + .../dts/rockchip/rk3328-nanopi-r2-common.dtsi | 85 ++++- + include/dt-bindings/clock/rockchip-ddr.h | 63 ++++ + include/dt-bindings/memory/rk3328-dram.h | 159 +++++++++ + 4 files changed, 617 insertions(+), 1 deletion(-) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-dram-default-timing.dtsi + create mode 100644 include/dt-bindings/clock/rockchip-ddr.h + create mode 100644 include/dt-bindings/memory/rk3328-dram.h + +--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +@@ -7,6 +7,7 @@ + + #include + #include ++#include "rk3328-dram-default-timing.dtsi" + #include "rk3328.dtsi" + + / { +@@ -121,6 +122,72 @@ + regulator-boot-on; + vin-supply = <&vdd_5v>; + }; ++ ++ dmc: dmc { ++ compatible = "rockchip,rk3328-dmc"; ++ devfreq-events = <&dfi>; ++ center-supply = <&vdd_log>; ++ clocks = <&cru SCLK_DDRCLK>; ++ clock-names = "dmc_clk"; ++ operating-points-v2 = <&dmc_opp_table>; ++ ddr_timing = <&ddr_timing>; ++ upthreshold = <40>; ++ downdifferential = <20>; ++ auto-min-freq = <786000>; ++ auto-freq-en = <0>; ++ #cooling-cells = <2>; ++ status = "okay"; ++ ++ ddr_power_model: ddr_power_model { ++ compatible = "ddr_power_model"; ++ dynamic-power-coefficient = <120>; ++ static-power-coefficient = <200>; ++ ts = <32000 4700 (-80) 2>; ++ thermal-zone = "soc-thermal"; ++ }; ++ }; ++ ++ dmc_opp_table: dmc-opp-table { ++ compatible = "operating-points-v2"; ++ ++ rockchip,leakage-voltage-sel = < ++ 1 10 0 ++ 11 254 1 ++ >; ++ nvmem-cells = <&logic_leakage>; ++ nvmem-cell-names = "ddr_leakage"; ++ ++ opp-786000000 { ++ opp-hz = /bits/ 64 <786000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-798000000 { ++ opp-hz = /bits/ 64 <798000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-840000000 { ++ opp-hz = /bits/ 64 <840000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-924000000 { ++ opp-hz = /bits/ 64 <924000000>; ++ opp-microvolt = <1100000>; ++ opp-microvolt-L0 = <1100000>; ++ opp-microvolt-L1 = <1075000>; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-microvolt = <1175000>; ++ opp-microvolt-L0 = <1175000>; ++ opp-microvolt-L1 = <1150000>; ++ }; ++ }; + }; + + &cpu0 { +@@ -139,6 +206,10 @@ + cpu-supply = <&vdd_arm>; + }; + ++&dfi { ++ status = "okay"; ++}; ++ + &display_subsystem { + status = "disabled"; + }; +@@ -206,6 +277,7 @@ + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; ++ regulator-init-microvolt = <1075000>; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; +@@ -220,6 +292,7 @@ + regulator-name = "vdd_arm"; + regulator-always-on; + regulator-boot-on; ++ regulator-init-microvolt = <1225000>; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; diff --git a/target/linux/rockchip/patches-6.1/808-drv-net-phy-add-JLSemi-jl2xxx-driver.patch b/target/linux/rockchip/patches-6.1/808-drv-net-phy-add-JLSemi-jl2xxx-driver.patch new file mode 100644 index 000000000..a04af45e7 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/808-drv-net-phy-add-JLSemi-jl2xxx-driver.patch @@ -0,0 +1,702 @@ +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -272,6 +272,11 @@ config INTEL_XWAY_PHY + PEF 7061, PEF 7071 and PEF 7072 or integrated into the Intel + SoCs xRX200, xRX300, xRX330, xRX350 and xRX550. + ++config JLSEMI_JL2XX1_PHY ++ tristate "JLSemi JL2XX1 PHYs" ++ help ++ Currently supports the JLSemi jl2xx1 PHYs. ++ + config LSI_ET1011C_PHY + tristate "LSI ET1011C PHY" + help +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -75,6 +75,8 @@ obj-$(CONFIG_DP83TD510_PHY) += dp83td510 + obj-$(CONFIG_FIXED_PHY) += fixed_phy.o + obj-$(CONFIG_ICPLUS_PHY) += icplus.o + obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o ++obj-$(CONFIG_JLSEMI_JL2XX1_PHY) += jl2xx1.o ++jl2xx1-objs := jl2xxx.o jl2xxx-core.o + obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o + obj-$(CONFIG_LXT_PHY) += lxt.o + obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o +--- /dev/null ++++ b/drivers/net/phy/jl2xxx-core.c +@@ -0,0 +1,438 @@ ++/* ++ * Copyright (C) 2021 JLSemi Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++#include "jl2xxx-core.h" ++#include ++#include ++#include ++#include ++ ++#define RGMII_CTRL_PAGE 171 ++#define RGMII_CTRL_REG 17 ++#define RGMII_TX_SW_RSTN BIT(14) ++#define RGMII_ERR_STAS BIT(3) ++#define RGMII_TX_CTR_EN BIT(1) ++ ++#define RGMII_STATUS_PAGE 166 ++#define RGMII_STATUS_REG 18 ++ ++#define BASIC_PAGE 0 ++#define BMCR_REG 0 ++#define SOFT_RESET BIT(15) ++#define SPEED_LSB BIT(13) ++#define AUTONEG_EN BIT(12) ++#define SPEED_MSB BIT(6) ++ ++#define DIG_PAGE 201 ++#define DIG_REG 17 ++#define CLK_10M_EN BIT(15) ++#define DAC_OUT_SEL_MSB BIT(1) ++#define DAC_OUT_SEL_LSB BIT(0) ++ ++/************************* Configuration section *************************/ ++ ++ ++/************************* JLSemi iteration code *************************/ ++ ++/* Patch for version: def2 */ ++uint32_t init_data[] = { ++ 0x1f00a0, 0x1903f3, 0x1f0012, 0x150100, 0x1f00ad, 0x100000, 0x11e0c6, 0x1f00a0, 0x1903fb, 0x1903fb, ++ 0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb, 0x1903fb, 0x1f00ad, 0x110000, 0x120400, 0x130093, ++ 0x140000, 0x150193, 0x160000, 0x170213, 0x180000, 0x12040c, 0x130293, 0x140000, 0x150313, 0x160000, ++ 0x170393, 0x180000, 0x120418, 0x130413, 0x140000, 0x150493, 0x160000, 0x170513, 0x180000, 0x120424, ++ 0x130593, 0x140000, 0x150613, 0x160000, 0x170693, 0x180000, 0x120430, 0x130713, 0x140000, 0x150793, ++ 0x160000, 0x171137, 0x180000, 0x12043c, 0x13006f, 0x140060, 0x15a001, 0x160113, 0x17fd41, 0x18d026, ++ 0x120448, 0x13d406, 0x14d222, 0x1517b7, 0x160800, 0x17aa23, 0x189407, 0x120454, 0x130713, 0x1430f0, ++ 0x1567b7, 0x160800, 0x17a423, 0x1846e7, 0x120460, 0x13a703, 0x14a587, 0x156685, 0x168f55, 0x17ac23, ++ 0x18a4e7, 0x12046c, 0x1367b9, 0x145737, 0x150800, 0x168793, 0x17ef27, 0x182023, 0x120478, 0x1374f7, ++ 0x1407b7, 0x150800, 0x165bfc, 0x17d493, 0x180037, 0x120484, 0x13f493, 0x141f04, 0x15f793, 0x1607f7, ++ 0x178fc5, 0x18c03e, 0x120490, 0x134702, 0x140793, 0x150210, 0x160763, 0x1700f7, 0x180793, 0x12049c, ++ 0x130270, 0x140c63, 0x1530f7, 0x16a001, 0x1707b7, 0x180002, 0x1204a8, 0x138793, 0x146967, 0x15c83e, ++ 0x1617b7, 0x170002, 0x188793, 0x1204b4, 0x13e567, 0x14c43e, 0x1537b7, 0x160002, 0x178793, 0x186867, ++ 0x1204c0, 0x13c23e, 0x1447b7, 0x150002, 0x168793, 0x17e9a7, 0x1866b7, 0x1204cc, 0x130800, 0x14ca3e, ++ 0x15a783, 0x166d86, 0x1775c1, 0x188713, 0x1204d8, 0x130ff5, 0x148ff9, 0x156735, 0x160713, 0x178007, ++ 0x188fd9, 0x1204e4, 0x13ac23, 0x146cf6, 0x15a783, 0x1665c6, 0x175737, 0x180800, 0x1204f0, 0x136611, ++ 0x14f793, 0x15f0f7, 0x16e793, 0x170807, 0x18ae23, 0x1204fc, 0x1364f6, 0x142783, 0x155c47, 0x169bf5, ++ 0x172223, 0x185cf7, 0x120508, 0x13a703, 0x14f5c6, 0x158f51, 0x16ae23, 0x17f4e6, 0x180737, 0x120514, ++ 0x130809, 0x14433c, 0x158fd1, 0x16c33c, 0x170637, 0x180800, 0x120520, 0x134a74, 0x14679d, 0x158793, ++ 0x160e07, 0x179ae1, 0x18e693, 0x12052c, 0x130036, 0x14ca74, 0x154678, 0x1676e1, 0x178693, 0x185006, ++ 0x120538, 0x138ff9, 0x148fd5, 0x1507c2, 0x168f6d, 0x1783c1, 0x188fd9, 0x120544, 0x13c67c, 0x140713, ++ 0x151000, 0x160793, 0x170000, 0x189c23, 0x120550, 0x1324e7, 0x140713, 0x151010, 0x169123, 0x1726e7, ++ 0x18470d, 0x12055c, 0x13c63a, 0x144702, 0x158d23, 0x162407, 0x17a223, 0x182607, 0x120568, 0x130793, ++ 0x140270, 0x150413, 0x160000, 0x171463, 0x1800f7, 0x120574, 0x134789, 0x14c63e, 0x154709, 0x16cc3a, ++ 0x174702, 0x180793, 0x120580, 0x130270, 0x141463, 0x1500f7, 0x16478d, 0x17cc3e, 0x180513, 0x12058c, ++ 0x130000, 0x144792, 0x154581, 0x164485, 0x179782, 0x184018, 0x120598, 0x131775, 0x14e563, 0x1502e4, ++ 0x162703, 0x170a04, 0x181163, 0x1205a4, 0x130297, 0x144818, 0x150563, 0x160097, 0x1747a2, 0x18c804, ++ 0x1205b0, 0x139782, 0x1466b7, 0x150800, 0x16a703, 0x174c46, 0x189b71, 0x1205bc, 0x136713, 0x140027, ++ 0x15a223, 0x164ce6, 0x174783, 0x180fd4, 0x1205c8, 0x13c7b9, 0x142683, 0x151004, 0x164745, 0x179763, ++ 0x1820e6, 0x1205d4, 0x133737, 0x140822, 0x152683, 0x163007, 0x177645, 0x18167d, 0x1205e0, 0x138ef1, ++ 0x142023, 0x1530d7, 0x162683, 0x172807, 0x18e693, 0x1205ec, 0x131006, 0x142023, 0x1528d7, 0x162683, ++ 0x173807, 0x18e693, 0x1205f8, 0x131006, 0x142023, 0x1538d7, 0x162683, 0x174007, 0x18e693, 0x120604, ++ 0x131006, 0x142023, 0x1540d7, 0x162683, 0x174807, 0x18e693, 0x120610, 0x131006, 0x142023, 0x1548d7, ++ 0x1656b7, 0x170800, 0x18a703, 0x12061c, 0x133486, 0x14830d, 0x158b05, 0x16cf01, 0x17a703, 0x185c46, ++ 0x120628, 0x137671, 0x14167d, 0x158f71, 0x166611, 0x17a223, 0x185ce6, 0x120634, 0x138f51, 0x14a223, ++ 0x155ce6, 0x162703, 0x171084, 0x1846b2, 0x120640, 0x131c63, 0x1402d7, 0x153737, 0x160822, 0x172683, ++ 0x182807, 0x12064c, 0x13e693, 0x140016, 0x152023, 0x1628d7, 0x172683, 0x183807, 0x120658, 0x13e693, ++ 0x140016, 0x152023, 0x1638d7, 0x172683, 0x184007, 0x120664, 0x13e693, 0x140016, 0x152023, 0x1640d7, ++ 0x172683, 0x184807, 0x120670, 0x13e693, 0x140016, 0x152023, 0x1648d7, 0x172703, 0x181004, 0x12067c, ++ 0x1346b2, 0x149c63, 0x151ae6, 0x160737, 0x170800, 0x184b78, 0x120688, 0x130693, 0x140ff0, 0x15463d, ++ 0x168b1d, 0x17ce3a, 0x1852b7, 0x120694, 0x130800, 0x144701, 0x154389, 0x16408d, 0x174311, 0x180537, ++ 0x1206a0, 0x130820, 0x141593, 0x150077, 0x1695aa, 0x17418c, 0x184572, 0x1206ac, 0x1305c2, 0x1481c1, ++ 0x1581a9, 0x167763, 0x1700b5, 0x189533, 0x1206b8, 0x1300e4, 0x144513, 0x15fff5, 0x168e69, 0x170537, ++ 0x180800, 0x1206c4, 0x134568, 0x148121, 0x15893d, 0x167463, 0x1702b5, 0x18a583, 0x1206d0, 0x1306c2, ++ 0x140763, 0x151277, 0x160a63, 0x171217, 0x1805c2, 0x1206dc, 0x1381c1, 0x14818d, 0x150d63, 0x161097, ++ 0x178985, 0x180586, 0x1206e8, 0x1395b3, 0x1400b4, 0x15c593, 0x16fff5, 0x178eed, 0x180705, 0x1206f4, ++ 0x1315e3, 0x14fa67, 0x1535b7, 0x160822, 0x17a703, 0x183005, 0x120700, 0x13757d, 0x148a3d, 0x150513, ++ 0x160ff5, 0x178f69, 0x180622, 0x12070c, 0x138e59, 0x14a023, 0x1530c5, 0x168637, 0x170800, 0x185a38, ++ 0x120718, 0x1375c1, 0x14f693, 0x150ff6, 0x168593, 0x170ff5, 0x188f6d, 0x120724, 0x1306a2, 0x148ed9, ++ 0x15da34, 0x164682, 0x170713, 0x180210, 0x120730, 0x139163, 0x140ee6, 0x154711, 0x16e391, 0x17471d, ++ 0x182023, 0x12073c, 0x1310e4, 0x142683, 0x150a04, 0x16471d, 0x179e63, 0x1800e6, 0x120748, 0x136737, ++ 0x140800, 0x152703, 0x164cc7, 0x170693, 0x184000, 0x120754, 0x137713, 0x144807, 0x151463, 0x1600d7, ++ 0x172223, 0x180e04, 0x120760, 0x134018, 0x141163, 0x150497, 0x165703, 0x1700c4, 0x181793, 0x12076c, ++ 0x130117, 0x14db63, 0x150207, 0x168737, 0x170800, 0x184778, 0x120778, 0x137713, 0x140807, 0x15e705, ++ 0x160513, 0x170000, 0x184792, 0x120784, 0x134581, 0x149782, 0x1547a2, 0x164711, 0x17c818, 0x18c004, ++ 0x120790, 0x130d23, 0x140094, 0x150ca3, 0x160004, 0x179782, 0x1856b7, 0x12079c, 0x130800, 0x1442b8, ++ 0x159b71, 0x16c2b8, 0x170513, 0x180000, 0x1207a8, 0x1347d2, 0x149782, 0x154703, 0x162684, 0x1703e3, ++ 0x18de07, 0x1207b4, 0x13bbd9, 0x1407b7, 0x150002, 0x168793, 0x1765c7, 0x18c83e, 0x1207c0, 0x1327b7, ++ 0x140002, 0x158793, 0x16dae7, 0x17c43e, 0x1847b7, 0x1207cc, 0x130002, 0x148793, 0x151427, 0x16c23e, ++ 0x1757b7, 0x180002, 0x1207d8, 0x138793, 0x149867, 0x15b1fd, 0x162683, 0x171504, 0x184709, 0x1207e4, ++ 0x1399e3, 0x14e2e6, 0x1536b7, 0x160822, 0x17a703, 0x183006, 0x1207f0, 0x13663d, 0x148f51, 0x15a023, ++ 0x1630e6, 0x17bd39, 0x18c593, 0x1207fc, 0x130015, 0x14b5dd, 0x158991, 0x1635b3, 0x1700b0, 0x180589, ++ 0x120808, 0x13bdf9, 0x148991, 0x15b593, 0x160015, 0x17bfdd, 0x180737, 0x120814, 0x130800, 0x144f28, ++ 0x15cf89, 0x1647c2, 0x17893d, 0x189782, 0x120820, 0x1347e2, 0x140713, 0x151000, 0x162223, 0x1710e4, ++ 0x182423, 0x12082c, 0x1310f4, 0x14474d, 0x15b729, 0x168111, 0x17b7dd, 0x1814e3, 0x120838, 0x13f097, ++ 0x140737, 0x150800, 0x164770, 0x171713, 0x180106, 0x120844, 0x135d63, 0x140607, 0x1585b7, 0x160800, ++ 0x17a683, 0x180d05, 0x120850, 0x1372c5, 0x147313, 0x1500f6, 0x1612fd, 0x17a703, 0x180d45, 0x12085c, ++ 0x131513, 0x1400c3, 0x15f6b3, 0x160056, 0x178ec9, 0x18757d, 0x120868, 0x130393, 0x140ff5, 0x151293, ++ 0x160083, 0x17f6b3, 0x180076, 0x120874, 0x139b41, 0x148211, 0x15e2b3, 0x160056, 0x171093, 0x180043, ++ 0x120880, 0x137693, 0x140016, 0x156333, 0x160067, 0x170613, 0x187ff5, 0x12088c, 0x139713, 0x1400b6, ++ 0x157633, 0x1600c3, 0x178e59, 0x189513, 0x120898, 0x1300a6, 0x147613, 0x159ff6, 0x169713, 0x170096, ++ 0x188e49, 0x1208a4, 0x13f293, 0x14f0f2, 0x158e59, 0x16e2b3, 0x170012, 0x1806a2, 0x1208b0, 0x137613, ++ 0x14eff6, 0x158e55, 0x16a823, 0x170c55, 0x18aa23, 0x1208bc, 0x130cc5, 0x1480e3, 0x15e807, 0x1646b7, ++ 0x170822, 0x18a703, 0x1208c8, 0x13f006, 0x149b61, 0x156713, 0x160027, 0x17a023, 0x18f0e6, 0x1208d4, ++ 0x13b5ad, 0x140000, 0x150000, 0x160000, 0x170000, 0x180000, 0x110000, 0x120400, 0x104000, 0x1f0000, ++}; ++ ++int jl2xxx_pre_init(struct phy_device *phydev) ++{ ++ int i, j; ++ int regaddr, val; ++ int length = sizeof(init_data)/sizeof(init_data[0]); ++ ++ for (i = 0; i < length; i++) { ++ regaddr = ((init_data[i] >> 16) & 0xff); ++ val = (init_data[i] & 0xffff); ++ phy_write(phydev, regaddr, val); ++ if (regaddr == 0x18) { ++ phy_write(phydev, 0x10, 0x8006); ++ for (j = 0; j < 8; j++) { ++ if (phy_read(phydev, 0x10) == 0) { ++ break; ++ } ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++int enable_wol(struct phy_device *phydev) ++{ ++ jlsemi_set_bits(phydev, WOL_CTL_PAGE, ++ WOL_CTL_REG, WOL_EN); ++ ++ jlsemi_clear_bits(phydev, WOL_CTL_STAS_PAGE, ++ WOL_CTL_STAS_REG, WOL_CTL_EN); ++ ++ return 0; ++} ++ ++int disable_wol(struct phy_device *phydev) ++{ ++ jlsemi_clear_bits(phydev, WOL_CTL_PAGE, ++ WOL_CTL_REG, WOL_EN); ++ ++ jlsemi_set_bits(phydev, BASIC_PAGE, BMCR_REG, SOFT_RESET); ++ /* wait soft reset complete*/ ++ msleep(20); ++ ++ return 0; ++} ++ ++int setup_wol_low_polarity(struct phy_device *phydev) ++{ ++ jlsemi_clear_bits(phydev, WOL_CTL_STAS_PAGE, ++ WOL_CTL_STAS_REG, WOL_POLARITY); ++ return 0; ++} ++ ++int setup_wol_high_polarity(struct phy_device *phydev) ++{ ++ jlsemi_set_bits(phydev, WOL_CTL_STAS_PAGE, ++ WOL_CTL_STAS_REG, WOL_POLARITY); ++ return 0; ++} ++ ++int clear_wol_event(struct phy_device *phydev) ++{ ++ jlsemi_set_bits(phydev, WOL_CTL_STAS_PAGE, ++ WOL_CTL_STAS_REG, WOL_EVENT); ++ ++ jlsemi_clear_bits(phydev, WOL_CTL_STAS_PAGE, ++ WOL_CTL_STAS_REG, WOL_EVENT); ++ return 0; ++} ++ ++int store_mac_addr(struct phy_device *phydev) ++{ ++ int err; ++ ++ jlsemi_write_page(phydev, WOL_CTL_STAS_PAGE); ++ ++ /* Store the device address for the magic packet */ ++ err = phy_write(phydev, WOL_MAC_ADDR2_REG, ++ ((phydev->attached_dev->dev_addr[0] << 8) | ++ phydev->attached_dev->dev_addr[1])); ++ if (err < 0) ++ return err; ++ err = phy_write(phydev, WOL_MAC_ADDR1_REG, ++ ((phydev->attached_dev->dev_addr[2] << 8) | ++ phydev->attached_dev->dev_addr[3])); ++ if (err < 0) ++ return err; ++ err = phy_write(phydev, WOL_MAC_ADDR0_REG, ++ ((phydev->attached_dev->dev_addr[4] << 8) | ++ phydev->attached_dev->dev_addr[5])); ++ if (err < 0) ++ return err; ++ ++ /* change page to 0 */ ++ jlsemi_write_page(phydev, BASIC_PAGE); ++ ++ return 0; ++} ++ ++int config_phy_info(struct phy_device *phydev, ++ struct jl2xx1_priv *jl2xx1) ++{ ++ int val, major, minor; ++ ++ val = phy_read(phydev, 29); ++ if (val < 0) ++ return val; ++ ++ major = (val >> 7) & 0x1f; ++ minor = (val >> 0) & 0x7f; ++ /* major enlarge 10 */ ++ jl2xx1->sw_info = major * 10 + minor; ++ ++ return 0; ++} ++ ++/********************** Convenience function for phy **********************/ ++ ++/** ++ * jlsemi_write_page() - write the page register ++ * @phydev: a pointer to a &struct phy_device ++ * @page: page values ++ */ ++int jlsemi_write_page(struct phy_device *phydev, int page) ++{ ++ return phy_write(phydev, MII_JLSEMI_PHY_PAGE, page); ++} ++ ++/** ++ * jlsemi_read_page() - write the page register ++ * @phydev: a pointer to a &struct phy_device ++ * ++ * Return: get page values at present ++ */ ++int jlsemi_read_page(struct phy_device *phydev) ++{ ++ return phy_read(phydev, MII_JLSEMI_PHY_PAGE); ++} ++ ++/** ++ * __jlsemi_save_page() - save the page value ++ *@phydev: a pointer to a &struct phy_device ++ * ++ * Return: save page value ++ */ ++static inline int __jlsemi_save_page(struct phy_device *phydev) ++{ ++ return jlsemi_read_page(phydev); ++} ++ ++/** ++ * __jlsemi_select_page() - restore the page register ++ * @phydev: a pointer to a &struct phy_device ++ * @page: the page ++ * ++ * Return: ++ * @oldpgae: this is last page value ++ * @ret: if page is change it will return new page value ++ */ ++static inline int __jlsemi_select_page(struct phy_device *phydev, int page) ++{ ++ int ret, oldpage; ++ ++ oldpage = ret = __jlsemi_save_page(phydev); ++ if (ret < 0) ++ return ret; ++ ++ if (oldpage != page) { ++ ret = jlsemi_write_page(phydev, page); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return oldpage; ++} ++ ++/** ++ * __jlsemi_restore_page() - restore the page register ++ * @phydev: a pointer to a &struct phy_device ++ * @oldpage: the old page, return value from __jlsemi_save_page() or ++ * __jlsemi_select_page() ++ * @ret: operation's return code ++ * ++ * Returns: ++ * @oldpage if it was a negative value, otherwise ++ * @ret if it was a negative errno value, otherwise ++ * phy_write_page()'s negative value if it were in error, otherwise ++ * @ret ++ */ ++static inline int __jlsemi_restore_page(struct phy_device *phydev, ++ int oldpage, int ret) ++{ ++ int r; ++ ++ if (oldpage >= 0) { ++ r = jlsemi_write_page(phydev, oldpage); ++ ++ /* Propagate the operation return code if the page write ++ * was successful. ++ */ ++ if (ret >= 0 && r < 0) ++ ret = r; ++ } else { ++ /* Propagate the phy page selection error code */ ++ ret = oldpage; ++ } ++ ++ return ret; ++} ++ ++/** ++ * __jlsemi_modify_reg() - Convenience function for modifying a PHY register ++ * @phydev: a pointer to a &struct phy_device ++ * @regnum: register number ++ * @mask: bit mask of bits to clear ++ * @set: bit mask of bits to set ++ * ++ * Returns negative errno, 0 if there was no change, and 1 in case of change ++ */ ++static inline int __jlsemi_modify_reg(struct phy_device *phydev, ++ u32 regnum, u16 mask, u16 set) ++{ ++ int newval, ret; ++ ++ ret = phy_read(phydev, regnum); ++ if (ret < 0) ++ return ret; ++ ++ newval = (ret & ~mask) | set; ++ if (newval == ret) ++ return 0; ++ ++ ret = phy_write(phydev, regnum, newval); ++ ++ return ret < 0 ? ret : 1; ++} ++ ++/** ++ * jlsemi_modify_paged_reg() - Function for modifying a paged register ++ * @phydev: a pointer to a &struct phy_device ++ * @page: the page for the phy ++ * @regnum: register number ++ * @mask: bit mask of bits to clear ++ * @set: bit mask of bits to set ++ * ++ * Returns negative errno, 0 if there was no change, and 1 in case of change ++ */ ++int jlsemi_modify_paged_reg(struct phy_device *phydev, ++ int page, u32 regnum, ++ u16 mask, u16 set) ++{ ++ int ret = 0, oldpage; ++ ++ oldpage = __jlsemi_select_page(phydev, page); ++ if (oldpage >= 0) ++ ret = __jlsemi_modify_reg(phydev, regnum, mask, set); ++ ++ return __jlsemi_restore_page(phydev, oldpage, ret); ++} ++ ++/** ++ * jlsemi_set_bits() - Convenience function for setting bits in a PHY register ++ * @phydev: a pointer to a &struct phy_device ++ * @page: the page for the phy ++ * @regnum: register number to write ++ * @val: bits to set ++ */ ++int jlsemi_set_bits(struct phy_device *phydev, ++ int page, u32 regnum, u16 val) ++{ ++ return jlsemi_modify_paged_reg(phydev, page, regnum, 0, val); ++} ++ ++/** ++ * jlsemi_clear_bits - Convenience function for clearing bits in a PHY register ++ * @phydev: the phy_device struct ++ * @page: the page for the phy ++ * @regnum: register number to write ++ * @val: bits to clear ++ */ ++int jlsemi_clear_bits(struct phy_device *phydev, ++ int page, u32 regnum, u16 val) ++{ ++ return jlsemi_modify_paged_reg(phydev, page, regnum, val, 0); ++} ++ ++/** ++ * jlsemi_get_bit() - Convenience function for setting bits in a PHY register ++ * @phydev: a pointer to a &struct phy_device ++ * @page: the page for the phy ++ * @regnum: register number to write ++ * @val: bit to get ++ * ++ * Note: ++ * you only get one bit at meanwhile ++ * ++ */ ++int jlsemi_get_bit(struct phy_device *phydev, ++ int page, u32 regnum, u16 val) ++{ ++ int ret = 0, oldpage; ++ ++ oldpage = __jlsemi_select_page(phydev, page); ++ if (oldpage >= 0) ++ { ++ ret = phy_read(phydev, regnum); ++ if (ret < 0) ++ return ret; ++ ret = ((ret & val) == val) ? 1 : 0; ++ } ++ ++ return __jlsemi_restore_page(phydev, oldpage, ret); ++} +--- /dev/null ++++ b/drivers/net/phy/jl2xxx-core.h +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2021 JLSemi Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++#ifndef _JLSEMI_CORE_H ++#define _JLSEMI_CORE_H ++ ++#include ++#include ++#include ++ ++#define JL2XX1_PHY_ID 0x937c4030 ++#define JLSEMI_PHY_ID_MASK 0xfffffff0 ++ ++#define JL2101_PHY_ID 0x937c4032 ++ ++#define MII_JLSEMI_PHY_PAGE 0x1f ++ ++#define WOL_CTL_PAGE 18 ++#define WOL_CTL_REG 21 ++#define WOL_CTL_STAS_PAGE 4608 ++#define WOL_CTL_STAS_REG 16 ++#define WOL_MAC_ADDR2_REG 17 ++#define WOL_MAC_ADDR1_REG 18 ++#define WOL_MAC_ADDR0_REG 19 ++#define WOL_EVENT BIT(1) ++#define WOL_POLARITY BIT(14) ++#define WOL_EN BIT(6) ++#define WOL_CTL_EN BIT(15) ++ ++ ++/************************* Configuration section *************************/ ++ ++#define JLSEMI_WOL_EN 0 ++ ++ ++/************************* JLSemi iteration code *************************/ ++struct jl2xx1_priv { ++ u16 sw_info; ++}; ++ ++int jl2xxx_pre_init(struct phy_device *phydev); ++ ++int config_phy_info(struct phy_device *phydev, ++ struct jl2xx1_priv *jl2xx1); ++ ++int check_rgmii(struct phy_device *phydev); ++ ++int dis_rgmii_tx_ctrl(struct phy_device *phydev); ++ ++int config_suspend(struct phy_device *phydev); ++ ++int config_resume(struct phy_device *phydev); ++ ++int enable_wol(struct phy_device *phydev); ++ ++int disable_wol(struct phy_device *phydev); ++ ++int setup_wol_low_polarity(struct phy_device *phydev); ++ ++int setup_wol_high_polarity(struct phy_device *phydev); ++ ++int clear_wol_event(struct phy_device *phydev); ++ ++int store_mac_addr(struct phy_device *phydev); ++ ++int software_version(struct phy_device *phydev); ++ ++ ++/********************** Convenience function for phy **********************/ ++ ++/* Notice: You should change page 0 when you When you call it after*/ ++int jlsemi_write_page(struct phy_device *phydev, int page); ++ ++int jlsemi_read_page(struct phy_device *phydev); ++ ++int jlsemi_modify_paged_reg(struct phy_device *phydev, ++ int page, u32 regnum, ++ u16 mask, u16 set); ++ ++int jlsemi_set_bits(struct phy_device *phydev, ++ int page, u32 regnum, u16 val); ++ ++int jlsemi_clear_bits(struct phy_device *phydev, ++ int page, u32 regnum, u16 val); ++ ++int jlsemi_get_bit(struct phy_device *phydev, ++ int page, u32 regnum, u16 val); ++ ++int jlsemi_drivers_register(struct phy_driver *phydrvs, int size); ++ ++void jlsemi_drivers_unregister(struct phy_driver *phydrvs, int size); ++ ++#endif /* _JLSEMI_CORE_H */ ++ +--- /dev/null ++++ b/drivers/net/phy/jl2xxx.c +@@ -0,0 +1,126 @@ ++/* ++ * drivers/net/phy/jlsemi.c ++ * ++ * Driver for JLSemi PHYs ++ * ++ * Author: Gangqiao Kuang ++ * ++ * Copyright (c) 2021 JingLue Semiconductor, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ */ ++#include "jl2xxx-core.h" ++#include ++#include ++#include ++ ++ ++MODULE_DESCRIPTION("JLSemi PHY driver"); ++MODULE_AUTHOR("Gangqiao Kuang"); ++MODULE_LICENSE("GPL"); ++ ++static int jlsemi_probe(struct phy_device *phydev) ++{ ++ int err; ++ ++ err = jl2xxx_pre_init(phydev); ++ ++ /* wait load complete*/ ++ msleep(20); ++ ++ return (err < 0) ? err : 0; ++} ++ ++#if JLSEMI_WOL_EN ++static void jlsemi_get_wol(struct phy_device *phydev, ++ struct ethtool_wolinfo *wol) ++{ ++ int wol_en; ++ ++ wol->supported = WAKE_MAGIC; ++ wol->wolopts = 0; ++ ++ wol_en = jlsemi_get_bit(phydev, WOL_CTL_PAGE, ++ WOL_CTL_REG, WOL_EN); ++ ++ if (wol_en) ++ wol->wolopts |= WAKE_MAGIC; ++} ++ ++static int jlsemi_set_wol(struct phy_device *phydev, ++ struct ethtool_wolinfo *wol) ++{ ++ int err; ++ ++ if (wol->wolopts & WAKE_MAGIC) { ++ err = enable_wol(phydev); ++ if (err < 0) ++ return err; ++ ++ err = clear_wol_event(phydev); ++ if (err < 0) ++ return err; ++ ++ err = setup_wol_high_polarity(phydev); ++ if (err < 0) ++ return err; ++ ++ err = store_mac_addr(phydev); ++ if (err < 0) ++ return err; ++ } else { ++ err = disable_wol(phydev); ++ if (err < 0) ++ return err; ++ ++ err = setup_wol_high_polarity(phydev); ++ if (err < 0) ++ return err; ++ ++ err = clear_wol_event(phydev); ++ if (err < 0) ++ return err; ++ } ++ ++ return 0; ++} ++#endif ++ ++static struct phy_driver jlsemi_driver[] = { ++ { ++ PHY_ID_MATCH_EXACT(JL2101_PHY_ID), ++ .name = "JL2101 Gigabit Ethernet", ++ /* PHY_BASIC_FEATURES */ ++ .features = PHY_GBIT_FEATURES, ++ .probe = jlsemi_probe, ++ #if JLSEMI_WOL_EN ++ .get_wol = jlsemi_get_wol, ++ .set_wol = jlsemi_set_wol, ++ #endif ++ }, ++ { ++ PHY_ID_MATCH_MODEL(JL2XX1_PHY_ID), ++ .name = "JL2xx1 Gigabit Ethernet", ++ /* PHY_BASIC_FEATURES */ ++ .features = PHY_GBIT_FEATURES, ++ .probe = jlsemi_probe, ++ #if JLSEMI_WOL_EN ++ .get_wol = jlsemi_get_wol, ++ .set_wol = jlsemi_set_wol, ++ #endif ++ }, ++}; ++ ++module_phy_driver(jlsemi_driver); ++ ++static struct mdio_device_id __maybe_unused jlsemi_tbl[] = { ++ { PHY_ID_MATCH_EXACT(JL2101_PHY_ID) }, ++ { PHY_ID_MATCH_MODEL(JL2XX1_PHY_ID) }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(mdio, jlsemi_tbl); diff --git a/target/linux/rockchip/patches-6.1/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch b/target/linux/rockchip/patches-6.1/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch new file mode 100644 index 000000000..315ac0e34 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Leonidas P. Papadakos +Date: Fri, 1 Mar 2019 21:55:53 +0200 +Subject: [PATCH v2] arm64: dts: rockchip: add more cpu operating points for + RK3328 + +This allows for greater max frequency on rk3328 boards, +increasing performance. + +It has been included in Armbian (a linux distibution for ARM boards) +for a while now without any reported issues + +https://github.com/armbian/build/blob/master/patch/kernel/rockchip64-default/enable-1392mhz-opp.patch +https://github.com/armbian/build/blob/master/patch/kernel/rockchip64-default/enable-1512mhz-opp.patch + +Signed-off-by: Leonidas P. Papadakos +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 15 +++++++++++++++ + 1 files changed, 15 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -140,6 +140,21 @@ + opp-microvolt = <1300000>; + clock-latency-ns = <40000>; + }; ++ opp-1392000000 { ++ opp-hz = /bits/ 64 <1392000000>; ++ opp-microvolt = <1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1512000000 { ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt = <1400000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1608000000 { ++ opp-hz = /bits/ 64 <1608000000>; ++ opp-microvolt = <1450000>; ++ clock-latency-ns = <40000>; ++ }; + }; + + analog_sound: analog-sound { diff --git a/target/linux/rockchip/patches-6.1/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz.patch b/target/linux/rockchip/patches-6.1/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz.patch new file mode 100644 index 000000000..ee8527a2f --- /dev/null +++ b/target/linux/rockchip/patches-6.1/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz.patch @@ -0,0 +1,46 @@ +From 04202df5cb497b1934c95211cf43784ef62245a4 Mon Sep 17 00:00:00 2001 +From: Tianling Shen +Date: Mon, 18 Oct 2021 12:47:30 +0800 +Subject: [PATCH] rockchip: rk3399: overclock to 2.2/1.8 GHz + +It's stable enough to overclock cpu frequency to 2.2/1.8 GHz, +and for better performance. + +Co-development-by: gzelvis +Signed-off-by: Tianling Shen +--- + arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi +@@ -33,6 +33,14 @@ + opp-hz = /bits/ 64 <1416000000>; + opp-microvolt = <1125000 1125000 1250000>; + }; ++ opp06 { ++ opp-hz = /bits/ 64 <1608000000>; ++ opp-microvolt = <1225000>; ++ }; ++ opp07 { ++ opp-hz = /bits/ 64 <1800000000>; ++ opp-microvolt = <1275000>; ++ }; + }; + + cluster1_opp: opp-table-1 { +@@ -72,6 +80,14 @@ + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1200000 1200000 1250000>; + }; ++ opp08 { ++ opp-hz = /bits/ 64 <2016000000>; ++ opp-microvolt = <1250000>; ++ }; ++ opp09 { ++ opp-hz = /bits/ 64 <2208000000>; ++ opp-microvolt = <1325000>; ++ }; + }; + + gpu_opp_table: opp-table-2 {