From 398eece1d6c3bc6c849d30cac58f1c368f26f62d Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Thu, 25 May 2023 20:19:18 +0800 Subject: [PATCH] generic: sync 6.1 patches from official source Closed: #11208 --- include/kernel-6.1 | 4 +- ...i-gen-LRU-rename-lru_gen_struct-to-l.patch | 352 +++ ...i-gen-LRU-rename-lrugen-lists-to-lru.patch | 197 ++ ...i-gen-LRU-remove-eviction-fairness-s.patch | 192 ++ ...i-gen-LRU-remove-aging-fairness-safe.patch | 294 +++ ...lti-gen-LRU-shuffle-should_run_aging.patch | 166 ++ ...i-gen-LRU-per-node-lru_gen_folio-lis.patch | 876 +++++++ ...i-gen-LRU-clarify-scan_control-flags.patch | 202 ++ ...i-gen-LRU-simplify-arch_has_hw_pte_y.patch | 38 + ...m-multi-gen-LRU-avoid-futile-retries.patch | 92 + ...3-10-UPSTREAM-mm-add-vma_has_recency.patch | 191 ++ ...STREAM-mm-support-POSIX_FADV_NOREUSE.patch | 129 ++ ...i-gen-LRU-section-for-working-set-pr.patch | 67 + ...i-gen-LRU-section-for-rmap-PT-walk-f.patch | 57 + ...ti-gen-LRU-section-for-Bloom-filters.patch | 243 ++ ...-multi-gen-LRU-section-for-memcg-LRU.patch | 427 ++++ ...i-gen-LRU-improve-lru_gen_exit_memcg.patch | 40 + ...multi-gen-LRU-improve-walk_pmd_range.patch | 135 ++ ...i-gen-LRU-simplify-lru_gen_look_arou.patch | 148 ++ ...i-gen-LRU-remove-wait_event_killable.patch | 273 +++ ...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 - ...-some-linker-warnings-in-recent-link.patch | 63 + ...onix-use-scratch-buffer-for-DMA-oper.patch | 35 + ...-mtd_otp_nvmem_add-to-handle-EPROBE_.patch | 47 + ...611-v6.3-net-add-helper-eth_addr_add.patch | 41 + ...add-phylink_get_link_timer_ns-helper.patch | 48 + ...cs-add-driver-for-MediaTek-SGMII-PCS.patch | 394 ++++ ...t-mtk_wed-introduce-wed-mcu-support.patch} | 0 ...et-mtk_wed-introduce-wed-wo-support.patch} | 0 ...wed-rename-tx_wdma-array-in-rx_wdma.patch} | 0 ...tk_wed-add-configure-wed-wo-support.patch} | 0 ...thernet-mtk_wed-add-rx-mib-counters.patch} | 0 ..._eth_soc-remove-cpu_relax-in-mtk_pen.patch | 36 + ..._wed-add-wcid-overwritten-support-fo.patch | 80 + ..._wed-return-status-value-in-mtk_wdma.patch | 85 + ..._wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch | 52 + ...ethernet-mtk_wed-update-mtk_wed_stop.patch | 98 + ...mtk_wed-add-mtk_wed_rx_reset-routine.patch | 309 +++ ..._wed-add-reset-to-tx_ring_setup-call.patch | 103 + ..._wed-fix-sleep-while-atomic-in-mtk_w.patch | 103 + ..._wed-get-rid-of-queue-lock-for-rx-qu.patch | 52 + ..._wed-get-rid-of-queue-lock-for-tx-qu.patch | 75 + ..._eth_soc-introduce-mtk_hw_reset-util.patch | 70 + ..._eth_soc-introduce-mtk_hw_warm_reset.patch | 107 + ..._eth_soc-align-reset-procedure-to-ve.patch | 262 +++ ..._eth_soc-add-dma-checks-to-mtk_hw_re.patch | 249 ++ ..._wed-add-reset-reset_complete-callba.patch | 124 + ..._wed-add-reset-to-rx_ring_setup-call.patch | 106 + ...eth_soc-account-for-vlan-in-rx-head.patch} | 0 ...eth_soc-increase-tx-ring-side-for-Q.patch} | 14 +- ...eth_soc-avoid-port_mg-assignment-on.patch} | 4 +- ...eth_soc-implement-multi-queue-suppo.patch} | 84 +- ...-dsa-tag_mtk-assign-per-port-queues.patch} | 6 +- ...atek-ppe-assign-per-port-queues-for.patch} | 2 +- ...eth_soc-compile-out-netsys-v2-code-.patch} | 2 +- ...rt-for-DSA-rx-offloading-via-metada.patch} | 0 ...eth_soc-fix-VLAN-rx-hardware-accele.patch} | 14 +- ..._eth_soc-disable-hardware-DSA-untagg.patch | 42 + ..._eth_soc-enable-special-tag-when-any.patch | 54 + ..._eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch | 129 ++ ..._wed-No-need-to-clear-memory-after-a.patch | 26 + ..._wed-fix-some-possible-NULL-pointer-.patch | 61 + ..._wed-fix-possible-deadlock-if-mtk_we.patch | 58 + ..._eth_soc-fix-tx-throughput-regressio.patch | 31 + ...-mtk_eth_soc-add-definitions-for-PCS.patch | 55 + ...eliminate-unnecessary-error-handling.patch | 74 + ...soc-add-pcs_get_state-implementation.patch | 46 + ...convert-mtk_sgmii-to-use-regmap_upda.patch | 130 ++ ...add-out-of-band-forcing-of-speed-and.patch | 52 + ...07-net-mtk_eth_soc-move-PHY-power-up.patch | 48 + ...h_soc-move-interface-speed-selection.patch | 48 + ...th_soc-add-advertisement-programming.patch | 52 + ...move-and-correct-link-timer-programm.patch | 63 + ...add-support-for-in-band-802.3z-negot.patch | 132 ++ ...ii-ensure-the-SGMII-PHY-is-powered-d.patch | 119 + ...iatek-sgmii-fix-duplex-configuration.patch | 52 + ...enable-PCS-polling-to-allow-SFP-work.patch | 33 + ...ethernet-mtk_eth_soc-reset-PCS-state.patch | 48 + ..._eth_soc-only-write-values-if-needed.patch | 103 + ...t-mtk_eth_soc-add-support-for-MT7981.patch | 200 ++ ..._eth_soc-set-MDIO-bus-clock-frequenc.patch | 76 + ..._eth_soc-switch-to-external-PCS-driv.patch | 512 +++++ ...k_eth_soc-use-WO-firmware-for-MT7981.patch | 46 + ..._eth_soc-fix-NULL-pointer-dereferenc.patch | 28 + ...ntroduce-single-mii-read-write-lo-hi.patch | 150 ++ ...prove-mdio-master-read-write-by-usin.patch | 73 + ...t-dsa-mt7530-use-external-PCS-driver.patch | 514 +++++ ...e-STM32MP15_BSEC_NUM_LOWER-in-config.patch | 82 + ...-warning-when-upper-OTPs-are-updated.patch | 34 + ...nvmem-stm32-add-nvmem-type-attribute.patch | 26 + ...m-stm32-fix-spelling-typo-in-comment.patch | 27 + ...x-spelling-mistake-controlls-control.patch | 27 + ...boot-env-add-Broadcom-format-support.patch | 67 + ...mem-core-remove-spurious-white-space.patch | 26 + ...e-add-an-index-parameter-to-the-cell.patch | 180 ++ ...struct-nvmem_cell_info-to-nvmem-prov.patch | 78 + ...the-removal-of-the-cells-in-nvmem_ad.patch | 65 + ...05-nvmem-core-add-nvmem_add_one_cell.patch | 122 + ...vmem_add_one_cell-in-nvmem_add_cells.patch | 93 + ...32-add-OP-TEE-support-for-STM32MP13x.patch | 562 +++++ ...ect-bsec-pta-presence-for-STM32MP15x.patch | 85 + ...eprm-fix-kernel-doc-bad-line-warning.patch | 32 + ...mi-sdam-register-at-device-init-time.patch | 43 + ...011-nvmem-stm32-fix-OPTEE-dependency.patch | 46 + ...001-nvmem-xilinx-zynqmp-make-modular.patch | 35 + ...2-nvmem-core-introduce-NVMEM-layouts.patch | 387 ++++ ...ndle-the-absence-of-expected-layouts.patch | 61 + ...-core-request-layout-modules-loading.patch | 52 + ...em-core-add-per-cell-post-processing.patch | 86 + ...ow-to-modify-a-cell-before-adding-it.patch | 59 + ...replace-global-post-processing-with-.patch | 81 + ...m-cell-drop-global-cell_post_process.patch | 68 + ...de-own-priv-pointer-in-post-process-.patch | 76 + ...ayouts-sl28vpd-Add-new-layout-driver.patch | 215 ++ ...youts-onie-tlv-Add-new-layout-driver.patch | 306 +++ ...m-mark-OF-related-data-as-maybe-unus.patch | 32 + ...Support-postprocessing-for-GPU-speed.patch | 120 + ...p-Use-devm_platform_ioremap_resource.patch | 39 + ...tp-Use-devm_platform_ioremap_resourc.patch | 39 + ...p-Use-devm_platform_get_and_ioremap_.patch | 32 + ...rt-specifying-both-cell-raw-data-pos.patch | 115 + ...nv-post-process-ethaddr-env-variable.patch | 81 + ...cro-to-register-nvmem-layout-drivers.patch | 42 + ...28vpd-Use-module_nvmem_layout_driver.patch | 39 + ...ie-tlv-Use-module_nvmem_layout_drive.patch | 39 + ...uts-onie-tlv-Drop-wrong-module-alias.patch | 24 + ...28vpd-set-varaiable-sl28vpd_layout-s.patch | 31 + ...-bcm47xx-support-init-from-IO-memory.patch | 100 + ...set-varaiable-imx_ocotp_layout-stora.patch | 31 + ...Reverse-MAC-addresses-on-all-i.MX-de.patch | 71 + ...vram-add-.read_post_process-for-MACs.patch | 81 + ...tp-Add-clks-and-reg_read-to-rockchip.patch | 166 ++ ...tp-Generalize-rockchip_otp_wait_stat.patch | 62 + ...tp-Use-devm_reset_control_array_get_.patch | 31 + ...hip-otp-Improve-probe-error-handling.patch | 71 + ...-rockchip-otp-Add-support-for-RK3588.patch | 129 ++ ...-Switch-xilinx.com-emails-to-amd.com.patch | 26 + ...-0010-nvmem-imx-support-i.MX93-OCOTP.patch | 230 ++ ...e-add-support-for-fixed-cells-layout.patch | 96 + ...-of_parse_phandle_with_optional_args.patch | 58 + ...ke-.-cells-optional-for-simple-props.patch | 34 + ...operty-add-nvmem-cell-cells-property.patch | 30 + ...vice-Ignore-modalias-of-reused-nodes.patch | 37 + ...-ignore-error-code-in-of_device_ueve.patch | 29 + ...002-of-Update-of_device_get_modalias.patch | 103 + ...v6.4-0003-of-Rename-of_modalias_node.patch | 173 ++ ...0004-of-Move-of_modalias-to-module.c.patch | 160 ++ ...uest-module-helper-logic-to-module.c.patch | 131 ++ ...qcom-document-qcom-msm-id-and-qcom-b.patch | 207 ++ ...-move-SMEM-item-struct-and-defines-t.patch | 171 ++ ...com-smem-Switch-to-EXPORT_SYMBOL_GPL.patch | 55 + ...-smem-introduce-qcom_smem_get_soc_id.patch | 70 + ...com-nvmem-use-SoC-ID-s-from-bindings.patch | 51 + ...-nvmem-use-helper-to-get-SMEM-SoC-ID.patch | 109 + target/linux/generic/config-6.1 | 245 +- .../linux/generic/hack-6.1/251-kconfig.patch | 11 + ...rans-call-add-disks-after-mtd-device.patch | 2 +- .../420-mtd-set-rootfs-to-be-root-dev.patch | 39 - ...upport-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch | 24 + ...lter-connmark-introduce-set-dscpmark.patch | 15 +- ...-netfilter-add-xt_FLOWOFFLOAD-target.patch | 5 +- .../hack-6.1/651-wireless_mesh_header.patch | 2 +- .../700-swconfig_switch_drivers.patch | 2 +- ...mtk-lynxi-workaround-2500BaseX-no-an.patch | 53 + .../765-mxl-gpy-control-LED-reg-from-DT.patch | 101 + ...k-ge-add-LED-configuration-interface.patch | 72 + .../780-usb-net-MeigLink_modem_support.patch | 2 +- .../810-bcma-ssb-fallback-sprom.patch | 187 ++ .../hack-6.1/901-debloat_sock_diag.patch | 11 - .../970-export-efivarfs-function.patch | 205 -- ...ilicon-Labs-EM3581-device-compatible.patch | 32 + ...ilicon-Labs-SI3210-device-compatible.patch | 32 + ..._wdt-Add-support-for-specifying-WDI-.patch | 75 + ...0-add-linux-spidev-compatible-si3210.patch | 18 - ...ck-usage-in-jffs2_build_xattr_subsys.patch | 121 + ...0-workqueue-fix-enum-type-for-gcc-13.patch | 44 + .../300-mips_expose_boot_raw.patch | 4 +- ...rriers-between-dcache-icache-flushes.patch | 71 + ...ip-bcm-6345-l1-request-memory-region.patch | 113 + .../400-mtd-mtdsplit-support.patch | 11 +- .../477-mtd-spi-nor-add-eon-en25qx128a.patch | 21 + .../488-mtd-spi-nor-add-xmc-xm25qh64c.patch | 23 + ...cat-add-dt-driver-for-concat-devices.patch | 2 +- ...T-skip-GRO-for-foreign-MAC-addresses.patch | 2 +- ...net-mtk_eth_soc-enable-threaded-NAPI.patch | 6 +- ...detach-callback-to-struct-phy_driver.patch | 4 +- ...a-tag_mtk-add-padding-for-tx-packets.patch | 9 +- ...rtl8221-allow-to-configure-SERDES-mo.patch | 43 +- ...support-switching-between-SGMII-and-.patch | 45 + ...e-all-MACs-are-powered-down-before-r.patch | 2 +- ...-net-mtk_sgmii-implement-mtk_pcs_ops.patch | 46 - ...-use-genphy_soft_reset-for-2.5G-PHYs.patch | 65 + ..._sgmii-fix-powering-up-the-SGMII-phy.patch | 39 - ...sable-SGMII-in-band-AN-for-2-5G-PHYs.patch | 42 + ...sure-the-SGMII-PHY-is-powered-down-o.patch | 65 - ...make-sure-paged-read-is-protected-by.patch | 35 + ...k_pcs_setup_mode_an-don-t-rely-on-re.patch | 31 - ...use-inline-functions-for-10GbE-adver.patch | 60 + ...t-the-speed-according-to-the-phy-int.patch | 47 - ...check-validity-of-10GbE-link-partner.patch | 28 + .../729-net-mtk_eth_soc-improve-comment.patch | 22 - ...-phy-realtek-introduce-rtl822x_probe.patch | 100 + ...enable-PCS-polling-to-allow-SFP-work.patch | 23 - ...tek-detect-early-version-of-RTL8221B.patch | 63 + ...iatek-ppe-add-support-for-flow-accou.patch | 428 ++++ ...0211_ptr-even-with-no-CFG82111-suppo.patch | 2 +- ...eth_soc-drop-generic-vlan-rx-offloa.patch} | 60 +- ...eth_soc-work-around-issue-with-send.patch} | 42 +- ...net-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch} | 4 +- ..._eth_soc-fix-remaining-throughput-re.patch | 42 + ..._eth_soc-fix-flow_offload-related-re.patch | 52 - ..._eth_soc-ppe-fix-L2-offloading-with-.patch | 33 + ..._eth_soc-add-code-for-offloading-flo.patch | 266 +++ ...iatek-mtk_ppe-prefer-newly-added-l2-.patch | 37 + ..._eth_soc-improve-keeping-track-of-of.patch | 331 +++ ...iatek-fix-ppe-flow-accounting-for-L2.patch | 333 +++ ...iatek-fix-ppe-flow-accounting-for-v1.patch | 51 + ...ional-threading-for-backlog-processi.patch | 227 ++ ...a-b53-add-support-for-BCM63xx-RGMIIs.patch | 174 ++ ...-net-dsa-b53-mmap-add-more-63xx-SoCs.patch | 108 + ...dsa-b53-mmap-allow-passing-a-chip-ID.patch | 195 ++ ...b53-add-BCM63268-RGMII-configuration.patch | 123 + ...sa-b53-mdio-add-support-for-BCM53134.patch | 189 ++ ...gister-OF-node-for-internal-MDIO-bus.patch | 43 + ...env-align-endianness-of-crc32-values.patch | 47 + ...add-BCM63268-timer-clock-definitions.patch | 114 + ...add-BCM63268-timer-reset-definitions.patch | 107 + ...CM63268-timer-clock-and-reset-driver.patch | 345 +++ .../pending-6.1/930-qcom-qmi-helpers.patch | 11 - 233 files changed, 20771 insertions(+), 3130 deletions(-) create mode 100644 target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-02-UPSTREAM-mm-multi-gen-LRU-rename-lrugen-lists-to-lru.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch create mode 100644 target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch delete mode 100644 target/linux/generic/backport-6.1/100-net-add-netdev_sw_irq_coalesce_default_on.patch delete mode 100644 target/linux/generic/backport-6.1/101-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch delete mode 100644 target/linux/generic/backport-6.1/102-drivers-net-convert-to-boolean-for-the-mac_managed_p.patch delete mode 100644 target/linux/generic/backport-6.1/103-r8169-use-tp_to_dev-instead-of-open-code.patch delete 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/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch create mode 100644 target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch create mode 100644 target/linux/generic/backport-6.1/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch create mode 100644 target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch create mode 100644 target/linux/generic/backport-6.1/700-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch create mode 100644 target/linux/generic/backport-6.1/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch rename target/linux/generic/{pending-6.1/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch => backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch} (100%) rename target/linux/generic/{pending-6.1/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch => backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch} (100%) rename target/linux/generic/{pending-6.1/733-03-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch => backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch} (100%) rename target/linux/generic/{pending-6.1/733-04-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch => backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch} (100%) rename target/linux/generic/{pending-6.1/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch => backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch} (100%) create mode 100644 target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch create mode 100644 target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch create mode 100644 target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch create mode 100644 target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch create mode 100644 target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch create mode 100644 target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch create mode 100644 target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch create mode 100644 target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch create mode 100644 target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch create mode 100644 target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch create mode 100644 target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch create mode 100644 target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch create mode 100644 target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch create mode 100644 target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch create mode 100644 target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch create mode 100644 target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch rename target/linux/generic/{pending-6.1/732-01-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch => backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch} (100%) rename target/linux/generic/{pending-6.1/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch => backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch} (90%) rename target/linux/generic/{pending-6.1/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch => backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch} (93%) rename target/linux/generic/{pending-6.1/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch => backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch} (88%) rename target/linux/generic/{pending-6.1/732-05-net-dsa-tag_mtk-assign-per-port-queues.patch => backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch} (80%) rename target/linux/generic/{pending-6.1/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch => backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch} (97%) rename target/linux/generic/{pending-6.1/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch => backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch} (94%) rename target/linux/generic/{pending-6.1/732-08-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch => backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch} (100%) rename target/linux/generic/{pending-6.1/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch => backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch} (93%) create mode 100644 target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch create mode 100644 target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch create mode 100644 target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch create mode 100644 target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch create mode 100644 target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch create mode 100644 target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch create mode 100644 target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch create mode 100644 target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch create mode 100644 target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch create mode 100644 target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch create mode 100644 target/linux/generic/backport-6.1/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch create mode 100644 target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch create mode 100644 target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch create mode 100644 target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch create mode 100644 target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch create mode 100644 target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch create mode 100644 target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch create mode 100644 target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch create mode 100644 target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch create mode 100644 target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch create mode 100644 target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch create mode 100644 target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch create mode 100644 target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch create mode 100644 target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch create mode 100644 target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch create mode 100644 target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch create mode 100644 target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch create mode 100644 target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch create mode 100644 target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch create mode 100644 target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch create mode 100644 target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch create mode 100644 target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch create mode 100644 target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch create mode 100644 target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch create mode 100644 target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch create mode 100644 target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch delete mode 100644 target/linux/generic/hack-6.1/420-mtd-set-rootfs-to-be-root-dev.patch create mode 100644 target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch create mode 100644 target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch create mode 100644 target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch create mode 100644 target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch create mode 100644 target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch delete mode 100644 target/linux/generic/hack-6.1/970-export-efivarfs-function.patch create mode 100644 target/linux/generic/pending-6.1/110-v6.3-0001-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch create mode 100644 target/linux/generic/pending-6.1/110-v6.3-0002-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch create mode 100644 target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch delete mode 100644 target/linux/generic/pending-6.1/130-add-linux-spidev-compatible-si3210.patch create mode 100644 target/linux/generic/pending-6.1/143-jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsys.patch create mode 100644 target/linux/generic/pending-6.1/160-workqueue-fix-enum-type-for-gcc-13.patch create mode 100644 target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch create mode 100644 target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch create mode 100644 target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch create mode 100644 target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch create mode 100644 target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch delete mode 100644 target/linux/generic/pending-6.1/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch create mode 100644 target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch delete mode 100644 target/linux/generic/pending-6.1/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch create mode 100644 target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch delete mode 100644 target/linux/generic/pending-6.1/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch create mode 100644 target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch delete mode 100644 target/linux/generic/pending-6.1/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch create mode 100644 target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch delete mode 100644 target/linux/generic/pending-6.1/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch create mode 100644 target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch delete mode 100644 target/linux/generic/pending-6.1/729-net-mtk_eth_soc-improve-comment.patch create mode 100644 target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch delete mode 100644 target/linux/generic/pending-6.1/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch create mode 100644 target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch create mode 100644 target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch rename target/linux/generic/pending-6.1/{732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch => 732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch} (75%) rename target/linux/generic/pending-6.1/{732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch => 732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch} (54%) rename target/linux/generic/pending-6.1/{732-11-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch => 732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch} (90%) create mode 100644 target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch delete 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/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch create mode 100644 target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch create mode 100644 target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch create mode 100644 target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch create mode 100644 target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch create mode 100644 target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch create mode 100644 target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch create mode 100644 target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch create mode 100644 target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch create mode 100644 target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch create mode 100644 target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch create mode 100644 target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch create mode 100644 target/linux/generic/pending-6.1/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch create mode 100644 target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch create mode 100644 target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch create mode 100644 target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch create mode 100644 target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch delete mode 100644 target/linux/generic/pending-6.1/930-qcom-qmi-helpers.patch diff --git a/include/kernel-6.1 b/include/kernel-6.1 index 81fb77fc9..95683962f 100644 --- a/include/kernel-6.1 +++ b/include/kernel-6.1 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.1 = .34 -LINUX_KERNEL_HASH-6.1.34 = b26f7cbcbf8031efc49f11f236f372fc34a4fd5fc6ad3151b893d1aa038ed603 +LINUX_VERSION-6.1 = .35 +LINUX_KERNEL_HASH-6.1.35 = be368143bc5d0dc73dd3e8c6191630c1620520379baf6f47c16116b2c0bc26ac diff --git a/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch b/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch new file mode 100644 index 000000000..9d21f8de2 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch @@ -0,0 +1,352 @@ +From 8c20e2eb5f2a0175b774134685e4d7bd93e85ff8 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 21 Dec 2022 21:18:59 -0700 +Subject: [PATCH 01/19] UPSTREAM: mm: multi-gen LRU: rename lru_gen_struct to + lru_gen_folio + +Patch series "mm: multi-gen LRU: memcg LRU", v3. + +Overview +======== + +An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs, +since each node and memcg combination has an LRU of folios (see +mem_cgroup_lruvec()). + +Its goal is to improve the scalability of global reclaim, which is +critical to system-wide memory overcommit in data centers. Note that +memcg reclaim is currently out of scope. + +Its memory bloat is a pointer to each lruvec and negligible to each +pglist_data. In terms of traversing memcgs during global reclaim, it +improves the best-case complexity from O(n) to O(1) and does not affect +the worst-case complexity O(n). Therefore, on average, it has a sublinear +complexity in contrast to the current linear complexity. + +The basic structure of an memcg LRU can be understood by an analogy to +the active/inactive LRU (of folios): +1. It has the young and the old (generations), i.e., the counterparts + to the active and the inactive; +2. The increment of max_seq triggers promotion, i.e., the counterpart + to activation; +3. Other events trigger similar operations, e.g., offlining an memcg + triggers demotion, i.e., the counterpart to deactivation. + +In terms of global reclaim, it has two distinct features: +1. Sharding, which allows each thread to start at a random memcg (in + the old generation) and improves parallelism; +2. Eventual fairness, which allows direct reclaim to bail out at will + and reduces latency without affecting fairness over some time. + +The commit message in patch 6 details the workflow: +https://lore.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com/ + +The following is a simple test to quickly verify its effectiveness. + + Test design: + 1. Create multiple memcgs. + 2. Each memcg contains a job (fio). + 3. All jobs access the same amount of memory randomly. + 4. The system does not experience global memory pressure. + 5. Periodically write to the root memory.reclaim. + + Desired outcome: + 1. All memcgs have similar pgsteal counts, i.e., stddev(pgsteal) + over mean(pgsteal) is close to 0%. + 2. The total pgsteal is close to the total requested through + memory.reclaim, i.e., sum(pgsteal) over sum(requested) is close + to 100%. + + Actual outcome [1]: + MGLRU off MGLRU on + stddev(pgsteal) / mean(pgsteal) 75% 20% + sum(pgsteal) / sum(requested) 425% 95% + + #################################################################### + MEMCGS=128 + + for ((memcg = 0; memcg < $MEMCGS; memcg++)); do + mkdir /sys/fs/cgroup/memcg$memcg + done + + start() { + echo $BASHPID > /sys/fs/cgroup/memcg$memcg/cgroup.procs + + fio -name=memcg$memcg --numjobs=1 --ioengine=mmap \ + --filename=/dev/zero --size=1920M --rw=randrw \ + --rate=64m,64m --random_distribution=random \ + --fadvise_hint=0 --time_based --runtime=10h \ + --group_reporting --minimal + } + + for ((memcg = 0; memcg < $MEMCGS; memcg++)); do + start & + done + + sleep 600 + + for ((i = 0; i < 600; i++)); do + echo 256m >/sys/fs/cgroup/memory.reclaim + sleep 6 + done + + for ((memcg = 0; memcg < $MEMCGS; memcg++)); do + grep "pgsteal " /sys/fs/cgroup/memcg$memcg/memory.stat + done + #################################################################### + +[1]: This was obtained from running the above script (touches less + than 256GB memory) on an EPYC 7B13 with 512GB DRAM for over an + hour. + +This patch (of 8): + +The new name lru_gen_folio will be more distinct from the coming +lru_gen_memcg. + +Link: https://lkml.kernel.org/r/20221222041905.2431096-1-yuzhao@google.com +Link: https://lkml.kernel.org/r/20221222041905.2431096-2-yuzhao@google.com +Signed-off-by: Yu Zhao +Cc: Johannes Weiner +Cc: Jonathan Corbet +Cc: Michael Larabel +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Roman Gushchin +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit 391655fe08d1f942359a11148aa9aaf3f99d6d6f) +Change-Id: I7df67e0e2435ba28f10eaa57d28d98b61a9210a6 +Signed-off-by: T.J. Mercier +--- + include/linux/mm_inline.h | 4 ++-- + include/linux/mmzone.h | 6 +++--- + mm/vmscan.c | 34 +++++++++++++++++----------------- + mm/workingset.c | 4 ++-- + 4 files changed, 24 insertions(+), 24 deletions(-) + +--- a/include/linux/mm_inline.h ++++ b/include/linux/mm_inline.h +@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(s + 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; ++ struct lru_gen_folio *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); +@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(str + 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; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + + VM_WARN_ON_ONCE_FOLIO(gen != -1, folio); + +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -404,7 +404,7 @@ enum { + * The number of pages in each generation is eventually consistent and therefore + * can be transiently negative when reset_batch_size() is pending. + */ +-struct lru_gen_struct { ++struct lru_gen_folio { + /* the aging increments the youngest generation number */ + unsigned long max_seq; + /* the eviction increments the oldest generation numbers */ +@@ -461,7 +461,7 @@ struct lru_gen_mm_state { + struct lru_gen_mm_walk { + /* the lruvec under reclaim */ + struct lruvec *lruvec; +- /* unstable max_seq from lru_gen_struct */ ++ /* unstable max_seq from lru_gen_folio */ + unsigned long max_seq; + /* the next address within an mm to scan */ + unsigned long next_addr; +@@ -524,7 +524,7 @@ struct lruvec { + unsigned long flags; + #ifdef CONFIG_LRU_GEN + /* evictable pages divided into generations */ +- struct lru_gen_struct lrugen; ++ struct lru_gen_folio lrugen; + /* to concurrently iterate lru_gen_mm_list */ + struct lru_gen_mm_state mm_state; + #endif +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lr + + static bool __maybe_unused seq_is_valid(struct lruvec *lruvec) + { +- /* see the comment on lru_gen_struct */ ++ /* see the comment on lru_gen_folio */ + 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; +@@ -3596,7 +3596,7 @@ struct ctrl_pos { + static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain, + struct ctrl_pos *pos) + { +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + int hist = lru_hist_from_seq(lrugen->min_seq[type]); + + pos->refaulted = lrugen->avg_refaulted[type][tier] + +@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec + static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover) + { + int hist, tier; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *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; + +@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio + 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; ++ struct lru_gen_folio *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); + +@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru + 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; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + + walk->batched = 0; + +@@ -4250,7 +4250,7 @@ static bool inc_min_seq(struct lruvec *l + { + int zone; + int remaining = MAX_LRU_BATCH; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); + + if (type == LRU_GEN_ANON && !can_swap) +@@ -4286,7 +4286,7 @@ static bool try_to_inc_min_seq(struct lr + { + int gen, type, zone; + bool success = false; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + DEFINE_MIN_SEQ(lruvec); + + VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); +@@ -4307,7 +4307,7 @@ next: + ; + } + +- /* see the comment on lru_gen_struct */ ++ /* see the comment on lru_gen_folio */ + 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]); +@@ -4329,7 +4329,7 @@ static void inc_max_seq(struct lruvec *l + { + int prev, next; + int type, zone; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + + spin_lock_irq(&lruvec->lru_lock); + +@@ -4387,7 +4387,7 @@ static bool try_to_inc_max_seq(struct lr + bool success; + struct lru_gen_mm_walk *walk; + struct mm_struct *mm = NULL; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + + VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq)); + +@@ -4452,7 +4452,7 @@ static bool should_run_aging(struct lruv + unsigned long old = 0; + unsigned long young = 0; + unsigned long total = 0; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + + for (type = !can_swap; type < ANON_AND_FILE; type++) { +@@ -4737,7 +4737,7 @@ static bool sort_folio(struct lruvec *lr + 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; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + + VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio); + +@@ -4837,7 +4837,7 @@ static int scan_folios(struct lruvec *lr + int scanned = 0; + int isolated = 0; + int remaining = MAX_LRU_BATCH; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + + VM_WARN_ON_ONCE(!list_empty(list)); +@@ -5237,7 +5237,7 @@ done: + + static bool __maybe_unused state_is_valid(struct lruvec *lruvec) + { +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + + if (lrugen->enabled) { + enum lru_list lru; +@@ -5519,7 +5519,7 @@ static void lru_gen_seq_show_full(struct + int i; + int type, tier; + int hist = lru_hist_from_seq(seq); +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + + for (tier = 0; tier < MAX_NR_TIERS; tier++) { + seq_printf(m, " %10d", tier); +@@ -5569,7 +5569,7 @@ static int lru_gen_seq_show(struct seq_f + unsigned long seq; + bool full = !debugfs_real_fops(m->file)->write; + struct lruvec *lruvec = v; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + int nid = lruvec_pgdat(lruvec)->node_id; + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + DEFINE_MAX_SEQ(lruvec); +@@ -5823,7 +5823,7 @@ void lru_gen_init_lruvec(struct lruvec * + { + int i; + int gen, type, zone; +- struct lru_gen_struct *lrugen = &lruvec->lrugen; ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + + lrugen->max_seq = MIN_NR_GENS + 1; + lrugen->enabled = lru_gen_enabled(); +--- a/mm/workingset.c ++++ b/mm/workingset.c +@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct fol + unsigned long token; + unsigned long min_seq; + struct lruvec *lruvec; +- struct lru_gen_struct *lrugen; ++ struct lru_gen_folio *lrugen; + int type = folio_is_file_lru(folio); + int delta = folio_nr_pages(folio); + int refs = folio_lru_refs(folio); +@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio + unsigned long token; + unsigned long min_seq; + struct lruvec *lruvec; +- struct lru_gen_struct *lrugen; ++ struct lru_gen_folio *lrugen; + struct mem_cgroup *memcg; + struct pglist_data *pgdat; + int type = folio_is_file_lru(folio); diff --git a/target/linux/generic/backport-6.1/020-v6.3-02-UPSTREAM-mm-multi-gen-LRU-rename-lrugen-lists-to-lru.patch b/target/linux/generic/backport-6.1/020-v6.3-02-UPSTREAM-mm-multi-gen-LRU-rename-lrugen-lists-to-lru.patch new file mode 100644 index 000000000..97ea33c52 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-02-UPSTREAM-mm-multi-gen-LRU-rename-lrugen-lists-to-lru.patch @@ -0,0 +1,197 @@ +From 656287d55d9cfc72a4bcd4d9bd098570f12ce409 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 21 Dec 2022 21:19:00 -0700 +Subject: [PATCH 02/19] UPSTREAM: mm: multi-gen LRU: rename lrugen->lists[] to + lrugen->folios[] + +lru_gen_folio will be chained into per-node lists by the coming +lrugen->list. + +Link: https://lkml.kernel.org/r/20221222041905.2431096-3-yuzhao@google.com +Signed-off-by: Yu Zhao +Cc: Johannes Weiner +Cc: Jonathan Corbet +Cc: Michael Larabel +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Roman Gushchin +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit 6df1b2212950aae2b2188c6645ea18e2a9e3fdd5) +Change-Id: I09f53e0fb2cd6b8b3adbb8a80b15dc5efbeae857 +Signed-off-by: T.J. Mercier +--- + Documentation/mm/multigen_lru.rst | 8 ++++---- + include/linux/mm_inline.h | 4 ++-- + include/linux/mmzone.h | 8 ++++---- + mm/vmscan.c | 20 ++++++++++---------- + 4 files changed, 20 insertions(+), 20 deletions(-) + +--- a/Documentation/mm/multigen_lru.rst ++++ b/Documentation/mm/multigen_lru.rst +@@ -89,15 +89,15 @@ 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 ++truncated generation number is an index to ``lrugen->folios[]``. 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. ++``lrugen->folios[]``; 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 ++generations, tiers do not have dedicated ``lrugen->folios[]``. 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 +@@ -127,7 +127,7 @@ page mapped by this PTE to ``(max_seq%MA + Eviction + -------- + The eviction consumes old generations. Given an ``lruvec``, it +-increments ``min_seq`` when ``lrugen->lists[]`` indexed by ++increments ``min_seq`` when ``lrugen->folios[]`` 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/include/linux/mm_inline.h ++++ b/include/linux/mm_inline.h +@@ -256,9 +256,9 @@ static inline bool lru_gen_add_folio(str + lru_gen_update_size(lruvec, folio, -1, gen); + /* for folio_rotate_reclaimable() */ + if (reclaiming) +- list_add_tail(&folio->lru, &lrugen->lists[gen][type][zone]); ++ list_add_tail(&folio->lru, &lrugen->folios[gen][type][zone]); + else +- list_add(&folio->lru, &lrugen->lists[gen][type][zone]); ++ list_add(&folio->lru, &lrugen->folios[gen][type][zone]); + + return true; + } +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -312,7 +312,7 @@ enum lruvec_flags { + * 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 on one of lrugen->folios[]. 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 +@@ -324,8 +324,8 @@ enum lruvec_flags { + * 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 ++ * PG_active is always cleared while a page is on one of lrugen->folios[] 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(). + * +@@ -412,7 +412,7 @@ struct lru_gen_folio { + /* 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]; ++ struct list_head folios[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 */ +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4258,7 +4258,7 @@ static bool inc_min_seq(struct lruvec *l + + /* 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]; ++ struct list_head *head = &lrugen->folios[old_gen][type][zone]; + + while (!list_empty(head)) { + struct folio *folio = lru_to_folio(head); +@@ -4269,7 +4269,7 @@ static bool inc_min_seq(struct lruvec *l + 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]); ++ list_move_tail(&folio->lru, &lrugen->folios[new_gen][type][zone]); + + if (!--remaining) + return false; +@@ -4297,7 +4297,7 @@ static bool try_to_inc_min_seq(struct lr + gen = lru_gen_from_seq(min_seq[type]); + + for (zone = 0; zone < MAX_NR_ZONES; zone++) { +- if (!list_empty(&lrugen->lists[gen][type][zone])) ++ if (!list_empty(&lrugen->folios[gen][type][zone])) + goto next; + } + +@@ -4762,7 +4762,7 @@ static bool sort_folio(struct lruvec *lr + + /* promoted */ + if (gen != lru_gen_from_seq(lrugen->min_seq[type])) { +- list_move(&folio->lru, &lrugen->lists[gen][type][zone]); ++ list_move(&folio->lru, &lrugen->folios[gen][type][zone]); + return true; + } + +@@ -4771,7 +4771,7 @@ static bool sort_folio(struct lruvec *lr + 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]); ++ list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); + + WRITE_ONCE(lrugen->protected[hist][type][tier - 1], + lrugen->protected[hist][type][tier - 1] + delta); +@@ -4783,7 +4783,7 @@ static bool sort_folio(struct lruvec *lr + 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]); ++ list_move(&folio->lru, &lrugen->folios[gen][type][zone]); + return true; + } + +@@ -4850,7 +4850,7 @@ static int scan_folios(struct lruvec *lr + for (zone = sc->reclaim_idx; zone >= 0; zone--) { + LIST_HEAD(moved); + int skipped = 0; +- struct list_head *head = &lrugen->lists[gen][type][zone]; ++ struct list_head *head = &lrugen->folios[gen][type][zone]; + + while (!list_empty(head)) { + struct folio *folio = lru_to_folio(head); +@@ -5250,7 +5250,7 @@ static bool __maybe_unused state_is_vali + int gen, type, zone; + + for_each_gen_type_zone(gen, type, zone) { +- if (!list_empty(&lrugen->lists[gen][type][zone])) ++ if (!list_empty(&lrugen->folios[gen][type][zone])) + return false; + } + } +@@ -5295,7 +5295,7 @@ static bool drain_evictable(struct lruve + int remaining = MAX_LRU_BATCH; + + for_each_gen_type_zone(gen, type, zone) { +- struct list_head *head = &lruvec->lrugen.lists[gen][type][zone]; ++ struct list_head *head = &lruvec->lrugen.folios[gen][type][zone]; + + while (!list_empty(head)) { + bool success; +@@ -5832,7 +5832,7 @@ void lru_gen_init_lruvec(struct lruvec * + lrugen->timestamps[i] = jiffies; + + for_each_gen_type_zone(gen, type, zone) +- INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); ++ INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]); + + lruvec->mm_state.seq = MIN_NR_GENS; + init_waitqueue_head(&lruvec->mm_state.wait); diff --git a/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch b/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch new file mode 100644 index 000000000..a5e4ad557 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch @@ -0,0 +1,192 @@ +From 14f9a7a15f3d1af351f30e0438fd747b7ac253b0 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 21 Dec 2022 21:19:01 -0700 +Subject: [PATCH 03/19] UPSTREAM: mm: multi-gen LRU: remove eviction fairness + safeguard + +Recall that the eviction consumes the oldest generation: first it +bucket-sorts folios whose gen counters were updated by the aging and +reclaims the rest; then it increments lrugen->min_seq. + +The current eviction fairness safeguard for global reclaim has a +dilemma: when there are multiple eligible memcgs, should it continue +or stop upon meeting the reclaim goal? If it continues, it overshoots +and increases direct reclaim latency; if it stops, it loses fairness +between memcgs it has taken memory away from and those it has yet to. + +With memcg LRU, the eviction, while ensuring eventual fairness, will +stop upon meeting its goal. Therefore the current eviction fairness +safeguard for global reclaim will not be needed. + +Note that memcg LRU only applies to global reclaim. For memcg reclaim, +the eviction will continue, even if it is overshooting. This becomes +unconditional due to code simplification. + +Link: https://lkml.kernel.org/r/20221222041905.2431096-4-yuzhao@google.com +Signed-off-by: Yu Zhao +Cc: Johannes Weiner +Cc: Jonathan Corbet +Cc: Michael Larabel +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Roman Gushchin +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit a579086c99ed70cc4bfc104348dbe3dd8f2787e6) +Change-Id: I08ac1b3c90e29cafd0566785aaa4bcdb5db7d22c +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 81 +++++++++++++++-------------------------------------- + 1 file changed, 23 insertions(+), 58 deletions(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_c + return sc->target_mem_cgroup; + } + ++static bool global_reclaim(struct scan_control *sc) ++{ ++ return !sc->target_mem_cgroup || mem_cgroup_is_root(sc->target_mem_cgroup); ++} ++ + /** + * writeback_throttling_sane - is the usual dirty throttling mechanism available? + * @sc: scan_control in question +@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_c + return false; + } + ++static bool global_reclaim(struct scan_control *sc) ++{ ++ return true; ++} ++ + static bool writeback_throttling_sane(struct scan_control *sc) + { + return true; +@@ -4993,8 +5003,7 @@ static int isolate_folios(struct lruvec + return scanned; + } + +-static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness, +- bool *need_swapping) ++static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness) + { + int type; + int scanned; +@@ -5083,9 +5092,6 @@ retry: + goto retry; + } + +- if (need_swapping && type == LRU_GEN_ANON) +- *need_swapping = true; +- + return scanned; + } + +@@ -5124,67 +5130,26 @@ 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) ++static unsigned long get_nr_to_reclaim(struct scan_control *sc) + { +- 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; +- } ++ /* don't abort memcg reclaim to ensure fairness */ ++ if (!global_reclaim(sc)) ++ return -1; + +- sc->nr_reclaimed += MIN_LRU_BATCH; ++ /* discount the previous progress for kswapd */ ++ if (current_is_kswapd()) ++ return sc->nr_to_reclaim + sc->last_reclaimed; + +- return true; ++ return max(sc->nr_to_reclaim, compact_gap(sc->order)); + } + + 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); ++ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); + + lru_add_drain(); + +@@ -5208,7 +5173,7 @@ static void lru_gen_shrink_lruvec(struct + if (!nr_to_scan) + goto done; + +- delta = evict_folios(lruvec, sc, swappiness, &need_swapping); ++ delta = evict_folios(lruvec, sc, swappiness); + if (!delta) + goto done; + +@@ -5216,7 +5181,7 @@ static void lru_gen_shrink_lruvec(struct + if (scanned >= nr_to_scan) + break; + +- if (should_abort_scan(lruvec, max_seq, sc, need_swapping)) ++ if (sc->nr_reclaimed >= nr_to_reclaim) + break; + + cond_resched(); +@@ -5666,7 +5631,7 @@ static int run_eviction(struct lruvec *l + if (sc->nr_reclaimed >= nr_to_reclaim) + return 0; + +- if (!evict_folios(lruvec, sc, swappiness, NULL)) ++ if (!evict_folios(lruvec, sc, swappiness)) + return 0; + + cond_resched(); diff --git a/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch b/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch new file mode 100644 index 000000000..87ed87a52 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch @@ -0,0 +1,294 @@ +From f3c93d2e37a3c56593d7ccf4f4bcf1b58426fdd8 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 21 Dec 2022 21:19:02 -0700 +Subject: [PATCH 04/19] BACKPORT: mm: multi-gen LRU: remove aging fairness + safeguard + +Recall that the aging produces the youngest generation: first it scans +for accessed folios and updates their gen counters; then it increments +lrugen->max_seq. + +The current aging fairness safeguard for kswapd uses two passes to +ensure the fairness to multiple eligible memcgs. On the first pass, +which is shared with the eviction, it checks whether all eligible +memcgs are low on cold folios. If so, it requires a second pass, on +which it ages all those memcgs at the same time. + +With memcg LRU, the aging, while ensuring eventual fairness, will run +when necessary. Therefore the current aging fairness safeguard for +kswapd will not be needed. + +Note that memcg LRU only applies to global reclaim. For memcg reclaim, +the aging can be unfair to different memcgs, i.e., their +lrugen->max_seq can be incremented at different paces. + +Link: https://lkml.kernel.org/r/20221222041905.2431096-5-yuzhao@google.com +Signed-off-by: Yu Zhao +Cc: Johannes Weiner +Cc: Jonathan Corbet +Cc: Michael Larabel +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Roman Gushchin +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit 7348cc91821b0cb24dfb00e578047f68299a50ab) +[TJ: Resolved conflicts with older function signatures for +min_cgroup_below_min / min_cgroup_below_low] +Change-Id: I6e36ecfbaaefbc0a56d9a9d5d7cbe404ed7f57a5 +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 126 ++++++++++++++++++++++++---------------------------- + 1 file changed, 59 insertions(+), 67 deletions(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -136,7 +136,6 @@ struct scan_control { + + #ifdef CONFIG_LRU_GEN + /* help kswapd make better choices among multiple memcgs */ +- unsigned int memcgs_need_aging:1; + unsigned long last_reclaimed; + #endif + +@@ -4455,7 +4454,7 @@ done: + return true; + } + +-static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq, ++static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, + struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) + { + int gen, type, zone; +@@ -4464,6 +4463,13 @@ static bool should_run_aging(struct lruv + unsigned long total = 0; + struct lru_gen_folio *lrugen = &lruvec->lrugen; + struct mem_cgroup *memcg = lruvec_memcg(lruvec); ++ DEFINE_MIN_SEQ(lruvec); ++ ++ /* whether this lruvec is completely out of cold folios */ ++ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { ++ *nr_to_scan = 0; ++ return true; ++ } + + for (type = !can_swap; type < ANON_AND_FILE; type++) { + unsigned long seq; +@@ -4492,8 +4498,6 @@ static bool should_run_aging(struct lruv + * 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; + +@@ -4512,40 +4516,54 @@ static bool should_run_aging(struct lruv + return false; + } + +-static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned long min_ttl) ++static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) + { +- bool need_aging; +- unsigned long nr_to_scan; +- int swappiness = get_swappiness(lruvec, sc); ++ int gen, type, zone; ++ unsigned long total = 0; ++ bool can_swap = get_swappiness(lruvec, sc); ++ struct lru_gen_folio *lrugen = &lruvec->lrugen; + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + DEFINE_MAX_SEQ(lruvec); + DEFINE_MIN_SEQ(lruvec); + +- VM_WARN_ON_ONCE(sc->memcg_low_reclaim); ++ for (type = !can_swap; type < ANON_AND_FILE; type++) { ++ unsigned long seq; + +- mem_cgroup_calculate_protection(NULL, memcg); ++ for (seq = min_seq[type]; seq <= max_seq; seq++) { ++ gen = lru_gen_from_seq(seq); + +- if (mem_cgroup_below_min(memcg)) +- return false; ++ for (zone = 0; zone < MAX_NR_ZONES; zone++) ++ total += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); ++ } ++ } + +- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); ++ /* whether the size is big enough to be helpful */ ++ return mem_cgroup_online(memcg) ? (total >> sc->priority) : total; ++} + +- if (min_ttl) { +- int gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); +- unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); ++static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc, ++ unsigned long min_ttl) ++{ ++ int gen; ++ unsigned long birth; ++ struct mem_cgroup *memcg = lruvec_memcg(lruvec); ++ DEFINE_MIN_SEQ(lruvec); + +- if (time_is_after_jiffies(birth + min_ttl)) +- return false; ++ VM_WARN_ON_ONCE(sc->memcg_low_reclaim); + +- /* the size is likely too small to be helpful */ +- if (!nr_to_scan && sc->priority != DEF_PRIORITY) +- return false; +- } ++ /* see the comment on lru_gen_folio */ ++ gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); ++ birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); + +- if (need_aging) +- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false); ++ if (time_is_after_jiffies(birth + min_ttl)) ++ return false; + +- return true; ++ if (!lruvec_is_sizable(lruvec, sc)) ++ return false; ++ ++ mem_cgroup_calculate_protection(NULL, memcg); ++ ++ return !mem_cgroup_below_min(memcg); + } + + /* to protect the working set of the last N jiffies */ +@@ -4554,46 +4572,32 @@ static unsigned long lru_gen_min_ttl __r + 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()); + + 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; ++ /* check the order to exclude compaction-induced reclaim */ ++ if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY) + return; +- } +- +- set_mm_walk(pgdat); + + memcg = mem_cgroup_iter(NULL, NULL, NULL); + do { + struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); + +- if (age_lruvec(lruvec, sc, min_ttl)) +- success = true; ++ if (lruvec_is_reclaimable(lruvec, sc, min_ttl)) { ++ mem_cgroup_iter_break(NULL, memcg); ++ return; ++ } + + 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. ++ * either too small or below min. + */ + if (mutex_trylock(&oom_lock)) { + struct oom_control oc = { +@@ -5101,33 +5105,27 @@ retry: + * reclaim. + */ + static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, +- bool can_swap, bool *need_aging) ++ bool can_swap) + { + 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) ++ if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan)) + return nr_to_scan; + + /* skip the aging path at the default priority */ + if (sc->priority == DEF_PRIORITY) +- goto done; ++ return nr_to_scan; + +- /* leave the work to lru_gen_age_node() */ +- if (current_is_kswapd()) +- return 0; ++ try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false); + +- 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; ++ /* skip this lruvec as it's low on cold folios */ ++ return 0; + } + + static unsigned long get_nr_to_reclaim(struct scan_control *sc) +@@ -5146,9 +5144,7 @@ static unsigned long get_nr_to_reclaim(s + static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) + { + struct blk_plug plug; +- bool need_aging = false; + unsigned long scanned = 0; +- unsigned long reclaimed = sc->nr_reclaimed; + unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); + + lru_add_drain(); +@@ -5169,13 +5165,13 @@ static void lru_gen_shrink_lruvec(struct + else + swappiness = 0; + +- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness, &need_aging); ++ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); + if (!nr_to_scan) +- goto done; ++ break; + + delta = evict_folios(lruvec, sc, swappiness); + if (!delta) +- goto done; ++ break; + + scanned += delta; + if (scanned >= nr_to_scan) +@@ -5187,10 +5183,6 @@ static void lru_gen_shrink_lruvec(struct + 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.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch b/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch new file mode 100644 index 000000000..857072296 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch @@ -0,0 +1,166 @@ +From eca3858631e0cbad2ca6e40f788892749428e4cb Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 21 Dec 2022 21:19:03 -0700 +Subject: [PATCH 05/19] UPSTREAM: mm: multi-gen LRU: shuffle should_run_aging() + +Move should_run_aging() next to its only caller left. + +Link: https://lkml.kernel.org/r/20221222041905.2431096-6-yuzhao@google.com +Cc: Johannes Weiner +Cc: Jonathan Corbet +Cc: Michael Larabel +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Roman Gushchin +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit 77d4459a4a1a472b7309e475f962dda87d950abd) +Signed-off-by: T.J. Mercier +Change-Id: I3b0383fe16b93a783b4d8c0b3a0b325160392576 +Signed-off-by: Yu Zhao +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 124 ++++++++++++++++++++++++++-------------------------- + 1 file changed, 62 insertions(+), 62 deletions(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4454,68 +4454,6 @@ done: + return true; + } + +-static bool should_run_aging(struct lruvec *lruvec, unsigned long max_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_folio *lrugen = &lruvec->lrugen; +- struct mem_cgroup *memcg = lruvec_memcg(lruvec); +- DEFINE_MIN_SEQ(lruvec); +- +- /* whether this lruvec is completely out of cold folios */ +- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { +- *nr_to_scan = 0; +- return true; +- } +- +- 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 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 bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) + { + int gen, type, zone; +@@ -5099,6 +5037,68 @@ retry: + return scanned; + } + ++static bool should_run_aging(struct lruvec *lruvec, unsigned long max_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_folio *lrugen = &lruvec->lrugen; ++ struct mem_cgroup *memcg = lruvec_memcg(lruvec); ++ DEFINE_MIN_SEQ(lruvec); ++ ++ /* whether this lruvec is completely out of cold folios */ ++ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { ++ *nr_to_scan = 0; ++ return true; ++ } ++ ++ 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 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; ++} ++ + /* + * For future optimizations: + * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg diff --git a/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch b/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch new file mode 100644 index 000000000..7a4d17512 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch @@ -0,0 +1,876 @@ +From 8ee8571e47aa75221e5fbd4c9c7802fc4244c346 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 21 Dec 2022 21:19:04 -0700 +Subject: [PATCH 06/19] BACKPORT: mm: multi-gen LRU: per-node lru_gen_folio + lists + +For each node, memcgs are divided into two generations: the old and +the young. For each generation, memcgs are randomly sharded into +multiple bins to improve scalability. For each bin, an RCU hlist_nulls +is virtually divided into three segments: the head, the tail and the +default. + +An onlining memcg is added to the tail of a random bin in the old +generation. The eviction starts at the head of a random bin in the old +generation. The per-node memcg generation counter, whose reminder (mod +2) indexes the old generation, is incremented when all its bins become +empty. + +There are four operations: +1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in + its current generation (old or young) and updates its "seg" to + "head"; +2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in + its current generation (old or young) and updates its "seg" to + "tail"; +3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in + the old generation, updates its "gen" to "old" and resets its "seg" + to "default"; +4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin + in the young generation, updates its "gen" to "young" and resets + its "seg" to "default". + +The events that trigger the above operations are: +1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD; +2. The first attempt to reclaim an memcg below low, which triggers + MEMCG_LRU_TAIL; +3. The first attempt to reclaim an memcg below reclaimable size + threshold, which triggers MEMCG_LRU_TAIL; +4. The second attempt to reclaim an memcg below reclaimable size + threshold, which triggers MEMCG_LRU_YOUNG; +5. Attempting to reclaim an memcg below min, which triggers + MEMCG_LRU_YOUNG; +6. Finishing the aging on the eviction path, which triggers + MEMCG_LRU_YOUNG; +7. Offlining an memcg, which triggers MEMCG_LRU_OLD. + +Note that memcg LRU only applies to global reclaim, and the +round-robin incrementing of their max_seq counters ensures the +eventual fairness to all eligible memcgs. For memcg reclaim, it still +relies on mem_cgroup_iter(). + +Link: https://lkml.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com +Signed-off-by: Yu Zhao +Cc: Johannes Weiner +Cc: Jonathan Corbet +Cc: Michael Larabel +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Roman Gushchin +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit e4dde56cd208674ce899b47589f263499e5b8cdc) +[TJ: Resolved conflicts with older function signatures for +min_cgroup_below_min / min_cgroup_below_low and includes] +Change-Id: Idc8a0f635e035d72dd911f807d1224cb47cbd655 +Signed-off-by: T.J. Mercier +--- + include/linux/memcontrol.h | 10 + + include/linux/mm_inline.h | 17 ++ + include/linux/mmzone.h | 117 +++++++++++- + mm/memcontrol.c | 16 ++ + mm/page_alloc.c | 1 + + mm/vmscan.c | 374 +++++++++++++++++++++++++++++++++---- + 6 files changed, 500 insertions(+), 35 deletions(-) + +--- a/include/linux/memcontrol.h ++++ b/include/linux/memcontrol.h +@@ -790,6 +790,11 @@ static inline void obj_cgroup_put(struct + percpu_ref_put(&objcg->refcnt); + } + ++static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg) ++{ ++ return !memcg || css_tryget(&memcg->css); ++} ++ + static inline void mem_cgroup_put(struct mem_cgroup *memcg) + { + if (memcg) +@@ -1290,6 +1295,11 @@ static inline void obj_cgroup_put(struct + { + } + ++static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg) ++{ ++ return true; ++} ++ + static inline void mem_cgroup_put(struct mem_cgroup *memcg) + { + } +--- a/include/linux/mm_inline.h ++++ b/include/linux/mm_inline.h +@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void + return current->in_lru_fault; + } + ++#ifdef CONFIG_MEMCG ++static inline int lru_gen_memcg_seg(struct lruvec *lruvec) ++{ ++ return READ_ONCE(lruvec->lrugen.seg); ++} ++#else ++static inline int lru_gen_memcg_seg(struct lruvec *lruvec) ++{ ++ return 0; ++} ++#endif ++ + static inline int lru_gen_from_seq(unsigned long seq) + { + return seq % MAX_NR_GENS; +@@ -297,6 +309,11 @@ static inline bool lru_gen_in_fault(void + return false; + } + ++static inline int lru_gen_memcg_seg(struct lruvec *lruvec) ++{ ++ return 0; ++} ++ + static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) + { + return false; +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -7,6 +7,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -367,6 +368,15 @@ 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) + ++/* see the comment on MEMCG_NR_GENS */ ++enum { ++ MEMCG_LRU_NOP, ++ MEMCG_LRU_HEAD, ++ MEMCG_LRU_TAIL, ++ MEMCG_LRU_OLD, ++ MEMCG_LRU_YOUNG, ++}; ++ + #ifdef CONFIG_LRU_GEN + + enum { +@@ -426,6 +436,14 @@ struct lru_gen_folio { + atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; + /* whether the multi-gen LRU is enabled */ + bool enabled; ++#ifdef CONFIG_MEMCG ++ /* the memcg generation this lru_gen_folio belongs to */ ++ u8 gen; ++ /* the list segment this lru_gen_folio belongs to */ ++ u8 seg; ++ /* per-node lru_gen_folio list for global reclaim */ ++ struct hlist_nulls_node list; ++#endif + }; + + enum { +@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec * + void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); + + #ifdef CONFIG_MEMCG ++ ++/* ++ * For each node, memcgs are divided into two generations: the old and the ++ * young. For each generation, memcgs are randomly sharded into multiple bins ++ * to improve scalability. For each bin, the hlist_nulls is virtually divided ++ * into three segments: the head, the tail and the default. ++ * ++ * An onlining memcg is added to the tail of a random bin in the old generation. ++ * The eviction starts at the head of a random bin in the old generation. The ++ * per-node memcg generation counter, whose reminder (mod MEMCG_NR_GENS) indexes ++ * the old generation, is incremented when all its bins become empty. ++ * ++ * There are four operations: ++ * 1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in its ++ * current generation (old or young) and updates its "seg" to "head"; ++ * 2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in its ++ * current generation (old or young) and updates its "seg" to "tail"; ++ * 3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in the old ++ * generation, updates its "gen" to "old" and resets its "seg" to "default"; ++ * 4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin in the ++ * young generation, updates its "gen" to "young" and resets its "seg" to ++ * "default". ++ * ++ * The events that trigger the above operations are: ++ * 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD; ++ * 2. The first attempt to reclaim an memcg below low, which triggers ++ * MEMCG_LRU_TAIL; ++ * 3. The first attempt to reclaim an memcg below reclaimable size threshold, ++ * which triggers MEMCG_LRU_TAIL; ++ * 4. The second attempt to reclaim an memcg below reclaimable size threshold, ++ * which triggers MEMCG_LRU_YOUNG; ++ * 5. Attempting to reclaim an memcg below min, which triggers MEMCG_LRU_YOUNG; ++ * 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG; ++ * 7. Offlining an memcg, which triggers MEMCG_LRU_OLD. ++ * ++ * Note that memcg LRU only applies to global reclaim, and the round-robin ++ * incrementing of their max_seq counters ensures the eventual fairness to all ++ * eligible memcgs. For memcg reclaim, it still relies on mem_cgroup_iter(). ++ */ ++#define MEMCG_NR_GENS 2 ++#define MEMCG_NR_BINS 8 ++ ++struct lru_gen_memcg { ++ /* the per-node memcg generation counter */ ++ unsigned long seq; ++ /* each memcg has one lru_gen_folio per node */ ++ unsigned long nr_memcgs[MEMCG_NR_GENS]; ++ /* per-node lru_gen_folio list for global reclaim */ ++ struct hlist_nulls_head fifo[MEMCG_NR_GENS][MEMCG_NR_BINS]; ++ /* protects the above */ ++ spinlock_t lock; ++}; ++ ++void lru_gen_init_pgdat(struct pglist_data *pgdat); ++ + void lru_gen_init_memcg(struct mem_cgroup *memcg); + void lru_gen_exit_memcg(struct mem_cgroup *memcg); +-#endif ++void lru_gen_online_memcg(struct mem_cgroup *memcg); ++void lru_gen_offline_memcg(struct mem_cgroup *memcg); ++void lru_gen_release_memcg(struct mem_cgroup *memcg); ++void lru_gen_rotate_memcg(struct lruvec *lruvec, int op); ++ ++#else /* !CONFIG_MEMCG */ ++ ++#define MEMCG_NR_GENS 1 ++ ++struct lru_gen_memcg { ++}; ++ ++static inline void lru_gen_init_pgdat(struct pglist_data *pgdat) ++{ ++} ++ ++#endif /* CONFIG_MEMCG */ + + #else /* !CONFIG_LRU_GEN */ + ++static inline void lru_gen_init_pgdat(struct pglist_data *pgdat) ++{ ++} ++ + static inline void lru_gen_init_lruvec(struct lruvec *lruvec) + { + } +@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(s + } + + #ifdef CONFIG_MEMCG ++ + static inline void lru_gen_init_memcg(struct mem_cgroup *memcg) + { + } +@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(st + static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg) + { + } +-#endif ++ ++static inline void lru_gen_online_memcg(struct mem_cgroup *memcg) ++{ ++} ++ ++static inline void lru_gen_offline_memcg(struct mem_cgroup *memcg) ++{ ++} ++ ++static inline void lru_gen_release_memcg(struct mem_cgroup *memcg) ++{ ++} ++ ++static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) ++{ ++} ++ ++#endif /* CONFIG_MEMCG */ + + #endif /* CONFIG_LRU_GEN */ + +@@ -1219,6 +1330,8 @@ typedef struct pglist_data { + #ifdef CONFIG_LRU_GEN + /* kswap mm walk data */ + struct lru_gen_mm_walk mm_walk; ++ /* lru_gen_folio list */ ++ struct lru_gen_memcg memcg_lru; + #endif + + CACHELINE_PADDING(_pad2_); +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struc + struct mem_cgroup_per_node *mz; + struct mem_cgroup_tree_per_node *mctz; + ++ if (lru_gen_enabled()) { ++ struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec; ++ ++ /* see the comment on MEMCG_NR_GENS */ ++ if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD) ++ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD); ++ ++ return; ++ } ++ + mctz = soft_limit_tree.rb_tree_per_node[nid]; + if (!mctz) + return; +@@ -3522,6 +3532,9 @@ unsigned long mem_cgroup_soft_limit_recl + struct mem_cgroup_tree_per_node *mctz; + unsigned long excess; + ++ if (lru_gen_enabled()) ++ return 0; ++ + if (order > 0) + return 0; + +@@ -5382,6 +5395,7 @@ static int mem_cgroup_css_online(struct + if (unlikely(mem_cgroup_is_root(memcg))) + queue_delayed_work(system_unbound_wq, &stats_flush_dwork, + 2UL*HZ); ++ lru_gen_online_memcg(memcg); + return 0; + offline_kmem: + memcg_offline_kmem(memcg); +@@ -5413,6 +5427,7 @@ static void mem_cgroup_css_offline(struc + memcg_offline_kmem(memcg); + reparent_shrinker_deferred(memcg); + wb_memcg_offline(memcg); ++ lru_gen_offline_memcg(memcg); + + drain_all_stock(memcg); + +@@ -5424,6 +5439,7 @@ static void mem_cgroup_css_released(stru + struct mem_cgroup *memcg = mem_cgroup_from_css(css); + + invalidate_reclaim_iterators(memcg); ++ lru_gen_release_memcg(memcg); + } + + static void mem_cgroup_css_free(struct cgroup_subsys_state *css) +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -7957,6 +7957,7 @@ static void __init free_area_init_node(i + pgdat_set_deferred_range(pgdat); + + free_area_init_core(pgdat); ++ lru_gen_init_pgdat(pgdat); + } + + static void __init free_area_init_memoryless_node(int nid) +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -54,6 +54,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -134,11 +136,6 @@ 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 long last_reclaimed; +-#endif +- + /* Allocation order */ + s8 order; + +@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_ca + for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ + for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) + ++#define get_memcg_gen(seq) ((seq) % MEMCG_NR_GENS) ++#define get_memcg_bin(bin) ((bin) % MEMCG_NR_BINS) ++ + static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid) + { + struct pglist_data *pgdat = NODE_DATA(nid); +@@ -4440,8 +4440,7 @@ done: + 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); ++ return false; + } + + VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); +@@ -4514,8 +4513,6 @@ static void lru_gen_age_node(struct pgli + + VM_WARN_ON_ONCE(!current_is_kswapd()); + +- sc->last_reclaimed = sc->nr_reclaimed; +- + /* check the order to exclude compaction-induced reclaim */ + if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY) + return; +@@ -5104,8 +5101,7 @@ static bool should_run_aging(struct lruv + * 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) ++static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool can_swap) + { + unsigned long nr_to_scan; + struct mem_cgroup *memcg = lruvec_memcg(lruvec); +@@ -5122,10 +5118,8 @@ static unsigned long get_nr_to_scan(stru + if (sc->priority == DEF_PRIORITY) + return nr_to_scan; + +- try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false); +- + /* skip this lruvec as it's low on cold folios */ +- return 0; ++ return try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false) ? -1 : 0; + } + + static unsigned long get_nr_to_reclaim(struct scan_control *sc) +@@ -5134,29 +5128,18 @@ static unsigned long get_nr_to_reclaim(s + if (!global_reclaim(sc)) + return -1; + +- /* discount the previous progress for kswapd */ +- if (current_is_kswapd()) +- return sc->nr_to_reclaim + sc->last_reclaimed; +- + return max(sc->nr_to_reclaim, compact_gap(sc->order)); + } + +-static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) ++static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) + { +- struct blk_plug plug; ++ long nr_to_scan; + unsigned long scanned = 0; + unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); + +- lru_add_drain(); +- +- blk_start_plug(&plug); +- +- set_mm_walk(lruvec_pgdat(lruvec)); +- + while (true) { + int delta; + int swappiness; +- unsigned long nr_to_scan; + + if (sc->may_swap) + swappiness = get_swappiness(lruvec, sc); +@@ -5166,7 +5149,7 @@ static void lru_gen_shrink_lruvec(struct + swappiness = 0; + + nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); +- if (!nr_to_scan) ++ if (nr_to_scan <= 0) + break; + + delta = evict_folios(lruvec, sc, swappiness); +@@ -5183,10 +5166,251 @@ static void lru_gen_shrink_lruvec(struct + cond_resched(); + } + ++ /* whether try_to_inc_max_seq() was successful */ ++ return nr_to_scan < 0; ++} ++ ++static int shrink_one(struct lruvec *lruvec, struct scan_control *sc) ++{ ++ bool success; ++ unsigned long scanned = sc->nr_scanned; ++ unsigned long reclaimed = sc->nr_reclaimed; ++ int seg = lru_gen_memcg_seg(lruvec); ++ struct mem_cgroup *memcg = lruvec_memcg(lruvec); ++ struct pglist_data *pgdat = lruvec_pgdat(lruvec); ++ ++ /* see the comment on MEMCG_NR_GENS */ ++ if (!lruvec_is_sizable(lruvec, sc)) ++ return seg != MEMCG_LRU_TAIL ? MEMCG_LRU_TAIL : MEMCG_LRU_YOUNG; ++ ++ mem_cgroup_calculate_protection(NULL, memcg); ++ ++ if (mem_cgroup_below_min(memcg)) ++ return MEMCG_LRU_YOUNG; ++ ++ if (mem_cgroup_below_low(memcg)) { ++ /* see the comment on MEMCG_NR_GENS */ ++ if (seg != MEMCG_LRU_TAIL) ++ return MEMCG_LRU_TAIL; ++ ++ memcg_memory_event(memcg, MEMCG_LOW); ++ } ++ ++ success = try_to_shrink_lruvec(lruvec, sc); ++ ++ shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, sc->priority); ++ ++ if (!sc->proactive) ++ vmpressure(sc->gfp_mask, memcg, false, sc->nr_scanned - scanned, ++ sc->nr_reclaimed - reclaimed); ++ ++ sc->nr_reclaimed += current->reclaim_state->reclaimed_slab; ++ current->reclaim_state->reclaimed_slab = 0; ++ ++ return success ? MEMCG_LRU_YOUNG : 0; ++} ++ ++#ifdef CONFIG_MEMCG ++ ++static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) ++{ ++ int gen; ++ int bin; ++ int first_bin; ++ struct lruvec *lruvec; ++ struct lru_gen_folio *lrugen; ++ const struct hlist_nulls_node *pos; ++ int op = 0; ++ struct mem_cgroup *memcg = NULL; ++ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); ++ ++ bin = first_bin = get_random_u32_below(MEMCG_NR_BINS); ++restart: ++ gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq)); ++ ++ rcu_read_lock(); ++ ++ hlist_nulls_for_each_entry_rcu(lrugen, pos, &pgdat->memcg_lru.fifo[gen][bin], list) { ++ if (op) ++ lru_gen_rotate_memcg(lruvec, op); ++ ++ mem_cgroup_put(memcg); ++ ++ lruvec = container_of(lrugen, struct lruvec, lrugen); ++ memcg = lruvec_memcg(lruvec); ++ ++ if (!mem_cgroup_tryget(memcg)) { ++ op = 0; ++ memcg = NULL; ++ continue; ++ } ++ ++ rcu_read_unlock(); ++ ++ op = shrink_one(lruvec, sc); ++ ++ if (sc->nr_reclaimed >= nr_to_reclaim) ++ goto success; ++ ++ rcu_read_lock(); ++ } ++ ++ rcu_read_unlock(); ++ ++ /* restart if raced with lru_gen_rotate_memcg() */ ++ if (gen != get_nulls_value(pos)) ++ goto restart; ++ ++ /* try the rest of the bins of the current generation */ ++ bin = get_memcg_bin(bin + 1); ++ if (bin != first_bin) ++ goto restart; ++success: ++ if (op) ++ lru_gen_rotate_memcg(lruvec, op); ++ ++ mem_cgroup_put(memcg); ++} ++ ++static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) ++{ ++ struct blk_plug plug; ++ ++ VM_WARN_ON_ONCE(global_reclaim(sc)); ++ ++ lru_add_drain(); ++ ++ blk_start_plug(&plug); ++ ++ set_mm_walk(lruvec_pgdat(lruvec)); ++ ++ if (try_to_shrink_lruvec(lruvec, sc)) ++ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG); ++ ++ clear_mm_walk(); ++ ++ blk_finish_plug(&plug); ++} ++ ++#else /* !CONFIG_MEMCG */ ++ ++static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) ++{ ++ BUILD_BUG(); ++} ++ ++static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) ++{ ++ BUILD_BUG(); ++} ++ ++#endif ++ ++static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc) ++{ ++ int priority; ++ unsigned long reclaimable; ++ struct lruvec *lruvec = mem_cgroup_lruvec(NULL, pgdat); ++ ++ if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH) ++ return; ++ /* ++ * Determine the initial priority based on ((total / MEMCG_NR_GENS) >> ++ * priority) * reclaimed_to_scanned_ratio = nr_to_reclaim, where the ++ * estimated reclaimed_to_scanned_ratio = inactive / total. ++ */ ++ reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE); ++ if (get_swappiness(lruvec, sc)) ++ reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON); ++ ++ reclaimable /= MEMCG_NR_GENS; ++ ++ /* round down reclaimable and round up sc->nr_to_reclaim */ ++ priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1); ++ ++ sc->priority = clamp(priority, 0, DEF_PRIORITY); ++} ++ ++static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc) ++{ ++ struct blk_plug plug; ++ unsigned long reclaimed = sc->nr_reclaimed; ++ ++ VM_WARN_ON_ONCE(!global_reclaim(sc)); ++ ++ lru_add_drain(); ++ ++ blk_start_plug(&plug); ++ ++ set_mm_walk(pgdat); ++ ++ set_initial_priority(pgdat, sc); ++ ++ if (current_is_kswapd()) ++ sc->nr_reclaimed = 0; ++ ++ if (mem_cgroup_disabled()) ++ shrink_one(&pgdat->__lruvec, sc); ++ else ++ shrink_many(pgdat, sc); ++ ++ if (current_is_kswapd()) ++ sc->nr_reclaimed += reclaimed; ++ + clear_mm_walk(); + + blk_finish_plug(&plug); ++ ++ /* kswapd should never fail */ ++ pgdat->kswapd_failures = 0; ++} ++ ++#ifdef CONFIG_MEMCG ++void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) ++{ ++ int seg; ++ int old, new; ++ int bin = get_random_u32_below(MEMCG_NR_BINS); ++ struct pglist_data *pgdat = lruvec_pgdat(lruvec); ++ ++ spin_lock(&pgdat->memcg_lru.lock); ++ ++ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); ++ ++ seg = 0; ++ new = old = lruvec->lrugen.gen; ++ ++ /* see the comment on MEMCG_NR_GENS */ ++ if (op == MEMCG_LRU_HEAD) ++ seg = MEMCG_LRU_HEAD; ++ else if (op == MEMCG_LRU_TAIL) ++ seg = MEMCG_LRU_TAIL; ++ else if (op == MEMCG_LRU_OLD) ++ new = get_memcg_gen(pgdat->memcg_lru.seq); ++ else if (op == MEMCG_LRU_YOUNG) ++ new = get_memcg_gen(pgdat->memcg_lru.seq + 1); ++ else ++ VM_WARN_ON_ONCE(true); ++ ++ hlist_nulls_del_rcu(&lruvec->lrugen.list); ++ ++ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD) ++ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); ++ else ++ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); ++ ++ pgdat->memcg_lru.nr_memcgs[old]--; ++ pgdat->memcg_lru.nr_memcgs[new]++; ++ ++ lruvec->lrugen.gen = new; ++ WRITE_ONCE(lruvec->lrugen.seg, seg); ++ ++ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq)) ++ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); ++ ++ spin_unlock(&pgdat->memcg_lru.lock); + } ++#endif + + /****************************************************************************** + * state change +@@ -5644,11 +5868,11 @@ static int run_cmd(char cmd, int memcg_i + + if (!mem_cgroup_disabled()) { + rcu_read_lock(); ++ + memcg = mem_cgroup_from_id(memcg_id); +-#ifdef CONFIG_MEMCG +- if (memcg && !css_tryget(&memcg->css)) ++ if (!mem_cgroup_tryget(memcg)) + memcg = NULL; +-#endif ++ + rcu_read_unlock(); + + if (!memcg) +@@ -5796,6 +6020,19 @@ void lru_gen_init_lruvec(struct lruvec * + } + + #ifdef CONFIG_MEMCG ++ ++void lru_gen_init_pgdat(struct pglist_data *pgdat) ++{ ++ int i, j; ++ ++ spin_lock_init(&pgdat->memcg_lru.lock); ++ ++ for (i = 0; i < MEMCG_NR_GENS; i++) { ++ for (j = 0; j < MEMCG_NR_BINS; j++) ++ INIT_HLIST_NULLS_HEAD(&pgdat->memcg_lru.fifo[i][j], i); ++ } ++} ++ + void lru_gen_init_memcg(struct mem_cgroup *memcg) + { + INIT_LIST_HEAD(&memcg->mm_list.fifo); +@@ -5819,7 +6056,69 @@ void lru_gen_exit_memcg(struct mem_cgrou + } + } + } +-#endif ++ ++void lru_gen_online_memcg(struct mem_cgroup *memcg) ++{ ++ int gen; ++ int nid; ++ int bin = get_random_u32_below(MEMCG_NR_BINS); ++ ++ for_each_node(nid) { ++ struct pglist_data *pgdat = NODE_DATA(nid); ++ struct lruvec *lruvec = get_lruvec(memcg, nid); ++ ++ spin_lock(&pgdat->memcg_lru.lock); ++ ++ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list)); ++ ++ gen = get_memcg_gen(pgdat->memcg_lru.seq); ++ ++ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]); ++ pgdat->memcg_lru.nr_memcgs[gen]++; ++ ++ lruvec->lrugen.gen = gen; ++ ++ spin_unlock(&pgdat->memcg_lru.lock); ++ } ++} ++ ++void lru_gen_offline_memcg(struct mem_cgroup *memcg) ++{ ++ int nid; ++ ++ for_each_node(nid) { ++ struct lruvec *lruvec = get_lruvec(memcg, nid); ++ ++ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD); ++ } ++} ++ ++void lru_gen_release_memcg(struct mem_cgroup *memcg) ++{ ++ int gen; ++ int nid; ++ ++ for_each_node(nid) { ++ struct pglist_data *pgdat = NODE_DATA(nid); ++ struct lruvec *lruvec = get_lruvec(memcg, nid); ++ ++ spin_lock(&pgdat->memcg_lru.lock); ++ ++ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); ++ ++ gen = lruvec->lrugen.gen; ++ ++ hlist_nulls_del_rcu(&lruvec->lrugen.list); ++ pgdat->memcg_lru.nr_memcgs[gen]--; ++ ++ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq)) ++ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); ++ ++ spin_unlock(&pgdat->memcg_lru.lock); ++ } ++} ++ ++#endif /* CONFIG_MEMCG */ + + static int __init init_lru_gen(void) + { +@@ -5846,6 +6145,10 @@ static void lru_gen_shrink_lruvec(struct + { + } + ++static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc) ++{ ++} ++ + #endif /* CONFIG_LRU_GEN */ + + static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) +@@ -5859,7 +6162,7 @@ static void shrink_lruvec(struct lruvec + bool proportional_reclaim; + struct blk_plug plug; + +- if (lru_gen_enabled()) { ++ if (lru_gen_enabled() && !global_reclaim(sc)) { + lru_gen_shrink_lruvec(lruvec, sc); + return; + } +@@ -6102,6 +6405,11 @@ static void shrink_node(pg_data_t *pgdat + struct lruvec *target_lruvec; + bool reclaimable = false; + ++ if (lru_gen_enabled() && global_reclaim(sc)) { ++ lru_gen_shrink_node(pgdat, sc); ++ return; ++ } ++ + target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); + + again: diff --git a/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch b/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch new file mode 100644 index 000000000..29430636f --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch @@ -0,0 +1,202 @@ +From 11b14ee8cbbbebd8204609076a9327a1171cd253 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 21 Dec 2022 21:19:05 -0700 +Subject: [PATCH 07/19] BACKPORT: mm: multi-gen LRU: clarify scan_control flags + +Among the flags in scan_control: +1. sc->may_swap, which indicates swap constraint due to memsw.max, is + supported as usual. +2. sc->proactive, which indicates reclaim by memory.reclaim, may not + opportunistically skip the aging path, since it is considered less + latency sensitive. +3. !(sc->gfp_mask & __GFP_IO), which indicates IO constraint, lowers + swappiness to prioritize file LRU, since clean file folios are more + likely to exist. +4. sc->may_writepage and sc->may_unmap, which indicates opportunistic + reclaim, are rejected, since unmapped clean folios are already + prioritized. Scanning for more of them is likely futile and can + cause high reclaim latency when there is a large number of memcgs. + +The rest are handled by the existing code. + +Link: https://lkml.kernel.org/r/20221222041905.2431096-8-yuzhao@google.com +Signed-off-by: Yu Zhao +Cc: Johannes Weiner +Cc: Jonathan Corbet +Cc: Michael Larabel +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Roman Gushchin +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit e9d4e1ee788097484606c32122f146d802a9c5fb) +[TJ: Resolved conflict with older function signature for min_cgroup_below_min, and over +cdded861182142ac4488a4d64c571107aeb77f53 ("ANDROID: MGLRU: Don't skip anon reclaim if swap low")] +Change-Id: Ic2e779eaf4e91a3921831b4e2fa10c740dc59d50 +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 55 +++++++++++++++++++++++++++-------------------------- + 1 file changed, 28 insertions(+), 27 deletions(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + struct pglist_data *pgdat = lruvec_pgdat(lruvec); + ++ if (!sc->may_swap) ++ return 0; ++ + if (!can_demote(pgdat->node_id, sc) && + mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH) + return 0; +@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruve + } while (err == -EAGAIN); + } + +-static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat) ++static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat, bool force_alloc) + { + struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk; + +@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_wa + VM_WARN_ON_ONCE(walk); + + walk = &pgdat->mm_walk; +- } else if (!pgdat && !walk) { ++ } else if (!walk && force_alloc) { + VM_WARN_ON_ONCE(current_is_kswapd()); + + walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); +@@ -4417,7 +4420,7 @@ static bool try_to_inc_max_seq(struct lr + goto done; + } + +- walk = set_mm_walk(NULL); ++ walk = set_mm_walk(NULL, true); + if (!walk) { + success = iterate_mm_list_nowalk(lruvec, max_seq); + goto done; +@@ -4486,8 +4489,6 @@ static bool lruvec_is_reclaimable(struct + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + DEFINE_MIN_SEQ(lruvec); + +- VM_WARN_ON_ONCE(sc->memcg_low_reclaim); +- + /* see the comment on lru_gen_folio */ + gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); + birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); +@@ -4743,12 +4744,8 @@ static bool isolate_folio(struct lruvec + { + bool success; + +- /* unmapping inhibited */ +- if (!sc->may_unmap && folio_mapped(folio)) +- return false; +- + /* swapping inhibited */ +- if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) && ++ if (!(sc->gfp_mask & __GFP_IO) && + (folio_test_dirty(folio) || + (folio_test_anon(folio) && !folio_test_swapcache(folio)))) + return false; +@@ -4845,9 +4842,8 @@ static int scan_folios(struct lruvec *lr + __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. ++ * There might not be eligible folios due to reclaim_idx. Check the ++ * remaining to prevent livelock if it's not making progress. + */ + return isolated || !remaining ? scanned : 0; + } +@@ -5107,8 +5103,7 @@ static long get_nr_to_scan(struct lruvec + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + DEFINE_MAX_SEQ(lruvec); + +- if (mem_cgroup_below_min(memcg) || +- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) ++ if (mem_cgroup_below_min(memcg)) + return 0; + + if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan)) +@@ -5136,17 +5131,14 @@ static bool try_to_shrink_lruvec(struct + long nr_to_scan; + unsigned long scanned = 0; + unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); ++ int swappiness = get_swappiness(lruvec, sc); ++ ++ /* clean file folios are more likely to exist */ ++ if (swappiness && !(sc->gfp_mask & __GFP_IO)) ++ swappiness = 1; + + while (true) { + int delta; +- int swappiness; +- +- 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 <= 0) +@@ -5277,12 +5269,13 @@ static void lru_gen_shrink_lruvec(struct + struct blk_plug plug; + + VM_WARN_ON_ONCE(global_reclaim(sc)); ++ VM_WARN_ON_ONCE(!sc->may_writepage || !sc->may_unmap); + + lru_add_drain(); + + blk_start_plug(&plug); + +- set_mm_walk(lruvec_pgdat(lruvec)); ++ set_mm_walk(NULL, sc->proactive); + + if (try_to_shrink_lruvec(lruvec, sc)) + lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG); +@@ -5338,11 +5331,19 @@ static void lru_gen_shrink_node(struct p + + VM_WARN_ON_ONCE(!global_reclaim(sc)); + ++ /* ++ * Unmapped clean folios are already prioritized. Scanning for more of ++ * them is likely futile and can cause high reclaim latency when there ++ * is a large number of memcgs. ++ */ ++ if (!sc->may_writepage || !sc->may_unmap) ++ goto done; ++ + lru_add_drain(); + + blk_start_plug(&plug); + +- set_mm_walk(pgdat); ++ set_mm_walk(pgdat, sc->proactive); + + set_initial_priority(pgdat, sc); + +@@ -5360,7 +5361,7 @@ static void lru_gen_shrink_node(struct p + clear_mm_walk(); + + blk_finish_plug(&plug); +- ++done: + /* kswapd should never fail */ + pgdat->kswapd_failures = 0; + } +@@ -5932,7 +5933,7 @@ static ssize_t lru_gen_seq_write(struct + set_task_reclaim_state(current, &sc.reclaim_state); + flags = memalloc_noreclaim_save(); + blk_start_plug(&plug); +- if (!set_mm_walk(NULL)) { ++ if (!set_mm_walk(NULL, true)) { + err = -ENOMEM; + goto done; + } diff --git a/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch b/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch new file mode 100644 index 000000000..d7d98ca6c --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch @@ -0,0 +1,38 @@ +From 25887d48dff860751a06caa4188bfaf6bfb6e4b2 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 21 Dec 2022 21:19:06 -0700 +Subject: [PATCH 08/19] UPSTREAM: mm: multi-gen LRU: simplify + arch_has_hw_pte_young() check + +Scanning page tables when hardware does not set the accessed bit has +no real use cases. + +Link: https://lkml.kernel.org/r/20221222041905.2431096-9-yuzhao@google.com +Signed-off-by: Yu Zhao +Cc: Johannes Weiner +Cc: Jonathan Corbet +Cc: Michael Larabel +Cc: Michal Hocko +Cc: Mike Rapoport +Cc: Roman Gushchin +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit f386e9314025ea99dae639ed2032560a92081430) +Change-Id: I84d97ab665b4e3bb862a9bc7d72f50dea7191a6b +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4415,7 +4415,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 (!force_scan && !(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { ++ if (!arch_has_hw_pte_young() || !get_cap(LRU_GEN_MM_WALK)) { + success = iterate_mm_list_nowalk(lruvec, max_seq); + goto done; + } diff --git a/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch b/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch new file mode 100644 index 000000000..1f91cb9f5 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch @@ -0,0 +1,92 @@ +From 620b0ee94455e48d124414cd06d8a53f69fb6453 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Mon, 13 Feb 2023 00:53:22 -0700 +Subject: [PATCH 09/19] UPSTREAM: mm: multi-gen LRU: avoid futile retries + +Recall that the per-node memcg LRU has two generations and they alternate +when the last memcg (of a given node) is moved from one to the other. +Each generation is also sharded into multiple bins to improve scalability. +A reclaimer starts with a random bin (in the old generation) and, if it +fails, it will retry, i.e., to try the rest of the bins. + +If a reclaimer fails with the last memcg, it should move this memcg to the +young generation first, which causes the generations to alternate, and +then retry. Otherwise, the retries will be futile because all other bins +are empty. + +Link: https://lkml.kernel.org/r/20230213075322.1416966-1-yuzhao@google.com +Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists") +Signed-off-by: Yu Zhao +Reported-by: T.J. Mercier +Signed-off-by: Andrew Morton +Bug: 274865848 +(cherry picked from commit 9f550d78b40da21b4da515db4c37d8d7b12aa1a6) +Change-Id: Ie92535676b005ec9e7987632b742fdde8d54436f +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -5206,18 +5206,20 @@ static int shrink_one(struct lruvec *lru + + static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) + { ++ int op; + int gen; + int bin; + int first_bin; + struct lruvec *lruvec; + struct lru_gen_folio *lrugen; ++ struct mem_cgroup *memcg; + const struct hlist_nulls_node *pos; +- int op = 0; +- struct mem_cgroup *memcg = NULL; + unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); + + bin = first_bin = get_random_u32_below(MEMCG_NR_BINS); + restart: ++ op = 0; ++ memcg = NULL; + gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq)); + + rcu_read_lock(); +@@ -5241,14 +5243,22 @@ restart: + + op = shrink_one(lruvec, sc); + +- if (sc->nr_reclaimed >= nr_to_reclaim) +- goto success; +- + rcu_read_lock(); ++ ++ if (sc->nr_reclaimed >= nr_to_reclaim) ++ break; + } + + rcu_read_unlock(); + ++ if (op) ++ lru_gen_rotate_memcg(lruvec, op); ++ ++ mem_cgroup_put(memcg); ++ ++ if (sc->nr_reclaimed >= nr_to_reclaim) ++ return; ++ + /* restart if raced with lru_gen_rotate_memcg() */ + if (gen != get_nulls_value(pos)) + goto restart; +@@ -5257,11 +5267,6 @@ restart: + bin = get_memcg_bin(bin + 1); + if (bin != first_bin) + goto restart; +-success: +- if (op) +- lru_gen_rotate_memcg(lruvec, op); +- +- mem_cgroup_put(memcg); + } + + static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) diff --git a/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch b/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch new file mode 100644 index 000000000..b5051d71a --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch @@ -0,0 +1,191 @@ +From 70d216c71ff5c5b17dd1da6294f97b91fb6aba7a Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Fri, 30 Dec 2022 14:52:51 -0700 +Subject: [PATCH 10/19] UPSTREAM: mm: add vma_has_recency() + +Add vma_has_recency() to indicate whether a VMA may exhibit temporal +locality that the LRU algorithm relies on. + +This function returns false for VMAs marked by VM_SEQ_READ or +VM_RAND_READ. While the former flag indicates linear access, i.e., a +special case of spatial locality, both flags indicate a lack of temporal +locality, i.e., the reuse of an area within a relatively small duration. + +"Recency" is chosen over "locality" to avoid confusion between temporal +and spatial localities. + +Before this patch, the active/inactive LRU only ignored the accessed bit +from VMAs marked by VM_SEQ_READ. After this patch, the active/inactive +LRU and MGLRU share the same logic: they both ignore the accessed bit if +vma_has_recency() returns false. + +For the active/inactive LRU, the following fio test showed a [6, 8]% +increase in IOPS when randomly accessing mapped files under memory +pressure. + + kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo) + kb=$((kb - 8*1024*1024)) + + modprobe brd rd_nr=1 rd_size=$kb + dd if=/dev/zero of=/dev/ram0 bs=1M + + mkfs.ext4 /dev/ram0 + mount /dev/ram0 /mnt/ + swapoff -a + + fio --name=test --directory=/mnt/ --ioengine=mmap --numjobs=8 \ + --size=8G --rw=randrw --time_based --runtime=10m \ + --group_reporting + +The discussion that led to this patch is here [1]. Additional test +results are available in that thread. + +[1] https://lore.kernel.org/r/Y31s%2FK8T85jh05wH@google.com/ + +Link: https://lkml.kernel.org/r/20221230215252.2628425-1-yuzhao@google.com +Change-Id: I291dcb795197659e40e46539cd32b857677c34ad +Signed-off-by: Yu Zhao +Cc: Alexander Viro +Cc: Andrea Righi +Cc: Johannes Weiner +Cc: Michael Larabel +Signed-off-by: Andrew Morton +(cherry picked from commit 8788f6781486769d9598dcaedc3fe0eb12fc3e59) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + include/linux/mm_inline.h | 8 ++++++++ + mm/memory.c | 7 +++---- + mm/rmap.c | 42 +++++++++++++++++---------------------- + mm/vmscan.c | 5 ++++- + 4 files changed, 33 insertions(+), 29 deletions(-) + +--- a/include/linux/mm_inline.h ++++ b/include/linux/mm_inline.h +@@ -595,4 +595,12 @@ pte_install_uffd_wp_if_needed(struct vm_ + #endif + } + ++static inline bool vma_has_recency(struct vm_area_struct *vma) ++{ ++ if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)) ++ return false; ++ ++ return true; ++} ++ + #endif +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -1435,8 +1435,7 @@ again: + force_flush = 1; + set_page_dirty(page); + } +- if (pte_young(ptent) && +- likely(!(vma->vm_flags & VM_SEQ_READ))) ++ if (pte_young(ptent) && likely(vma_has_recency(vma))) + mark_page_accessed(page); + } + rss[mm_counter(page)]--; +@@ -5170,8 +5169,8 @@ static inline void mm_account_fault(stru + #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)); ++ /* the LRU algorithm only applies to accesses with recency */ ++ current->in_lru_fault = vma_has_recency(vma); + } + + static void lru_gen_exit_fault(void) +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -823,25 +823,14 @@ 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))) { ++ if (lru_gen_enabled() && pte_young(*pvmw.pte)) { + lru_gen_look_around(&pvmw); + referenced++; + } + + if (ptep_clear_flush_young_notify(vma, address, +- pvmw.pte)) { +- /* +- * Don't treat a reference through +- * a sequentially read mapping as such. +- * If the folio has been used in another mapping, +- * we will catch it; if this other mapping is +- * already gone, the unmap path will have set +- * the referenced flag or activated the folio. +- */ +- if (likely(!(vma->vm_flags & VM_SEQ_READ))) +- referenced++; +- } ++ pvmw.pte)) ++ referenced++; + } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { + if (pmdp_clear_flush_young_notify(vma, address, + pvmw.pmd)) +@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma + struct folio_referenced_arg *pra = arg; + struct mem_cgroup *memcg = pra->memcg; + +- if (!mm_match_cgroup(vma->vm_mm, memcg)) ++ /* ++ * Ignore references from this mapping if it has no recency. If the ++ * folio has been used in another mapping, we will catch it; if this ++ * other mapping is already gone, the unmap path will have set the ++ * referenced flag or activated the folio in zap_pte_range(). ++ */ ++ if (!vma_has_recency(vma)) ++ return true; ++ ++ /* ++ * If we are reclaiming on behalf of a cgroup, skip counting on behalf ++ * of references from different cgroups. ++ */ ++ if (memcg && !mm_match_cgroup(vma->vm_mm, memcg)) + return true; + + return false; +@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio + .arg = (void *)&pra, + .anon_lock = folio_lock_anon_vma_read, + .try_lock = true, ++ .invalid_vma = invalid_folio_referenced_vma, + }; + + *vm_flags = 0; +@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio + return 1; + } + +- /* +- * If we are reclaiming on behalf of a cgroup, skip +- * counting on behalf of references from different +- * cgroups +- */ +- if (memcg) { +- rwc.invalid_vma = invalid_folio_referenced_vma; +- } +- + rmap_walk(folio, &rwc); + *vm_flags = pra.vm_flags; + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3778,7 +3778,10 @@ static int should_skip_vma(unsigned long + if (is_vm_hugetlb_page(vma)) + return true; + +- if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ)) ++ if (!vma_has_recency(vma)) ++ return true; ++ ++ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) + return true; + + if (vma == get_gate_vma(vma->vm_mm)) diff --git a/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch b/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch new file mode 100644 index 000000000..00e5b6e8d --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch @@ -0,0 +1,129 @@ +From 9ca4e437a24dfc4ec6c362f319eb9850b9eca497 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Fri, 30 Dec 2022 14:52:52 -0700 +Subject: [PATCH 11/19] UPSTREAM: mm: support POSIX_FADV_NOREUSE + +This patch adds POSIX_FADV_NOREUSE to vma_has_recency() so that the LRU +algorithm can ignore access to mapped files marked by this flag. + +The advantages of POSIX_FADV_NOREUSE are: +1. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not alter the + default readahead behavior. +2. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not split VMAs and + therefore does not take mmap_lock. +3. Unlike MADV_COLD, setting it has a negligible cost, regardless of + how many pages it affects. + +Its limitations are: +1. Like POSIX_FADV_RANDOM and POSIX_FADV_SEQUENTIAL, it currently does + not support range. IOW, its scope is the entire file. +2. It currently does not ignore access through file descriptors. + Specifically, for the active/inactive LRU, given a file page shared + by two users and one of them having set POSIX_FADV_NOREUSE on the + file, this page will be activated upon the second user accessing + it. This corner case can be covered by checking POSIX_FADV_NOREUSE + before calling folio_mark_accessed() on the read path. But it is + considered not worth the effort. + +There have been a few attempts to support POSIX_FADV_NOREUSE, e.g., [1]. +This time the goal is to fill a niche: a few desktop applications, e.g., +large file transferring and video encoding/decoding, want fast file +streaming with mmap() rather than direct IO. Among those applications, an +SVT-AV1 regression was reported when running with MGLRU [2]. The +following test can reproduce that regression. + + kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo) + kb=$((kb - 8*1024*1024)) + + modprobe brd rd_nr=1 rd_size=$kb + dd if=/dev/zero of=/dev/ram0 bs=1M + + mkfs.ext4 /dev/ram0 + mount /dev/ram0 /mnt/ + swapoff -a + + fallocate -l 8G /mnt/swapfile + mkswap /mnt/swapfile + swapon /mnt/swapfile + + wget http://ultravideo.cs.tut.fi/video/Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z + 7z e -o/mnt/ Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z + SvtAv1EncApp --preset 12 -w 3840 -h 2160 \ + -i /mnt/Bosphorus_3840x2160.y4m + +For MGLRU, the following change showed a [9-11]% increase in FPS, +which makes it on par with the active/inactive LRU. + + patch Source/App/EncApp/EbAppMain.c < #include + 35d35 + < #include /* _O_BINARY */ + 117a118 + > posix_fadvise(config->mmap.fd, 0, 0, POSIX_FADV_NOREUSE); + EOF + +[1] https://lore.kernel.org/r/1308923350-7932-1-git-send-email-andrea@betterlinux.com/ +[2] https://openbenchmarking.org/result/2209259-PTS-MGLRU8GB57 + +Link: https://lkml.kernel.org/r/20221230215252.2628425-2-yuzhao@google.com +Change-Id: I0b7f5f971d78014ea1ba44cee6a8ec902a4330d0 +Signed-off-by: Yu Zhao +Cc: Alexander Viro +Cc: Andrea Righi +Cc: Johannes Weiner +Cc: Michael Larabel +Signed-off-by: Andrew Morton +(cherry picked from commit 17e810229cb3068b692fa078bd9b3a6527e0866a) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + include/linux/fs.h | 2 ++ + include/linux/mm_inline.h | 3 +++ + mm/fadvise.c | 5 ++++- + 3 files changed, 9 insertions(+), 1 deletion(-) + +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb + /* File supports DIRECT IO */ + #define FMODE_CAN_ODIRECT ((__force fmode_t)0x400000) + ++#define FMODE_NOREUSE ((__force fmode_t)0x800000) ++ + /* File was opened by fanotify and shouldn't generate fanotify events */ + #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) + +--- a/include/linux/mm_inline.h ++++ b/include/linux/mm_inline.h +@@ -600,6 +600,9 @@ static inline bool vma_has_recency(struc + if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)) + return false; + ++ if (vma->vm_file && (vma->vm_file->f_mode & FMODE_NOREUSE)) ++ return false; ++ + return true; + } + +--- a/mm/fadvise.c ++++ b/mm/fadvise.c +@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, l + case POSIX_FADV_NORMAL: + file->f_ra.ra_pages = bdi->ra_pages; + spin_lock(&file->f_lock); +- file->f_mode &= ~FMODE_RANDOM; ++ file->f_mode &= ~(FMODE_RANDOM | FMODE_NOREUSE); + spin_unlock(&file->f_lock); + break; + case POSIX_FADV_RANDOM: +@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, l + force_page_cache_readahead(mapping, file, start_index, nrpages); + break; + case POSIX_FADV_NOREUSE: ++ spin_lock(&file->f_lock); ++ file->f_mode |= FMODE_NOREUSE; ++ spin_unlock(&file->f_lock); + break; + case POSIX_FADV_DONTNEED: + __filemap_fdatawrite_range(mapping, offset, endbyte, diff --git a/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch b/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch new file mode 100644 index 000000000..ca68b3a86 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch @@ -0,0 +1,67 @@ +From 1b5e4c317d80f4826eceb3781702d18d06b14394 Mon Sep 17 00:00:00 2001 +From: "T.J. Alumbaugh" +Date: Wed, 18 Jan 2023 00:18:21 +0000 +Subject: [PATCH 12/19] UPSTREAM: mm: multi-gen LRU: section for working set + protection + +Patch series "mm: multi-gen LRU: improve". + +This patch series improves a few MGLRU functions, collects related +functions, and adds additional documentation. + +This patch (of 7): + +Add a section for working set protection in the code and the design doc. +The admin doc already contains its usage. + +Link: https://lkml.kernel.org/r/20230118001827.1040870-1-talumbau@google.com +Link: https://lkml.kernel.org/r/20230118001827.1040870-2-talumbau@google.com +Change-Id: I65599075fd42951db7739a2ab7cee78516e157b3 +Signed-off-by: T.J. Alumbaugh +Cc: Yu Zhao +Signed-off-by: Andrew Morton +(cherry picked from commit 7b8144e63d84716f16a1b929e0c7e03ae5c4d5c1) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + Documentation/mm/multigen_lru.rst | 15 +++++++++++++++ + mm/vmscan.c | 4 ++++ + 2 files changed, 19 insertions(+) + +--- a/Documentation/mm/multigen_lru.rst ++++ b/Documentation/mm/multigen_lru.rst +@@ -141,6 +141,21 @@ loop has detected outlying refaults from + this end, the feedback loop uses the first tier as the baseline, for + the reason stated earlier. + ++Working set protection ++---------------------- ++Each generation is timestamped at birth. If ``lru_gen_min_ttl`` is ++set, an ``lruvec`` is protected from the eviction when its oldest ++generation was born within ``lru_gen_min_ttl`` milliseconds. In other ++words, it prevents the working set of ``lru_gen_min_ttl`` milliseconds ++from getting evicted. The OOM killer is triggered if this working set ++cannot be kept in memory. ++ ++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. ++ + Summary + ------- + The multi-gen LRU can be disassembled into the following parts: +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4459,6 +4459,10 @@ done: + return true; + } + ++/****************************************************************************** ++ * working set protection ++ ******************************************************************************/ ++ + static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) + { + int gen, type, zone; diff --git a/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch b/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch new file mode 100644 index 000000000..ca28cee2c --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch @@ -0,0 +1,57 @@ +From 5ddf9d53d375e42af49b744bd7c2f8247c6bce15 Mon Sep 17 00:00:00 2001 +From: "T.J. Alumbaugh" +Date: Wed, 18 Jan 2023 00:18:22 +0000 +Subject: [PATCH 13/19] UPSTREAM: mm: multi-gen LRU: section for rmap/PT walk + feedback + +Add a section for lru_gen_look_around() in the code and the design doc. + +Link: https://lkml.kernel.org/r/20230118001827.1040870-3-talumbau@google.com +Change-Id: I5097af63f61b3b69ec2abee6cdbdc33c296df213 +Signed-off-by: T.J. Alumbaugh +Cc: Yu Zhao +Signed-off-by: Andrew Morton +(cherry picked from commit db19a43d9b3a8876552f00f656008206ef9a5efa) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + Documentation/mm/multigen_lru.rst | 14 ++++++++++++++ + mm/vmscan.c | 4 ++++ + 2 files changed, 18 insertions(+) + +--- a/Documentation/mm/multigen_lru.rst ++++ b/Documentation/mm/multigen_lru.rst +@@ -156,6 +156,20 @@ This time-based approach has the followi + and memory sizes. + 2. It is more reliable because it is directly wired to the OOM killer. + ++Rmap/PT walk feedback ++--------------------- ++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. ++ ++``lru_gen_look_around()`` exploits spatial locality to reduce the ++trips into the 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. ++ + Summary + ------- + The multi-gen LRU can be disassembled into the following parts: +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4553,6 +4553,10 @@ static void lru_gen_age_node(struct pgli + } + } + ++/****************************************************************************** ++ * rmap/PT walk feedback ++ ******************************************************************************/ ++ + /* + * This function exploits spatial locality when shrink_folio_list() walks the + * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If diff --git a/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch b/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch new file mode 100644 index 000000000..a7dfb5ffe --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch @@ -0,0 +1,243 @@ +From 397624e12244ec038f51cb1f178ccb7a2ec562e5 Mon Sep 17 00:00:00 2001 +From: "T.J. Alumbaugh" +Date: Wed, 18 Jan 2023 00:18:23 +0000 +Subject: [PATCH 14/19] UPSTREAM: mm: multi-gen LRU: section for Bloom filters + +Move Bloom filters code into a dedicated section. Improve the design doc +to explain Bloom filter usage and connection between aging and eviction in +their use. + +Link: https://lkml.kernel.org/r/20230118001827.1040870-4-talumbau@google.com +Change-Id: I73e866f687c1ed9f5c8538086aa39408b79897db +Signed-off-by: T.J. Alumbaugh +Cc: Yu Zhao +Signed-off-by: Andrew Morton +(cherry picked from commit ccbbbb85945d8f0255aa9dbc1b617017e2294f2c) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + Documentation/mm/multigen_lru.rst | 16 +++ + mm/vmscan.c | 180 +++++++++++++++--------------- + 2 files changed, 108 insertions(+), 88 deletions(-) + +--- a/Documentation/mm/multigen_lru.rst ++++ b/Documentation/mm/multigen_lru.rst +@@ -170,6 +170,22 @@ promotes hot pages. If the scan was done + adds the PMD entry pointing to the PTE table to the Bloom filter. This + forms a feedback loop between the eviction and the aging. + ++Bloom Filters ++------------- ++Bloom filters are a space and memory efficient data structure for set ++membership test, i.e., test if an element is not in the set or may be ++in the set. ++ ++In the eviction path, specifically, in ``lru_gen_look_around()``, if a ++PMD has a sufficient number of hot pages, its address is placed in the ++filter. In the aging path, set membership means that the PTE range ++will be scanned for young pages. ++ ++Note that Bloom filters are probabilistic on set membership. If a test ++is false positive, the cost is an additional scan of a range of PTEs, ++which may yield hot pages anyway. Parameters of the filter itself can ++control the false positive rate in the limit. ++ + Summary + ------- + The multi-gen LRU can be disassembled into the following parts: +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3209,6 +3209,98 @@ static bool __maybe_unused seq_is_valid( + } + + /****************************************************************************** ++ * Bloom filters ++ ******************************************************************************/ ++ ++/* ++ * 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 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 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 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); ++} ++ ++/****************************************************************************** + * mm_struct list + ******************************************************************************/ + +@@ -3333,94 +3425,6 @@ void lru_gen_migrate_mm(struct mm_struct + } + #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; diff --git a/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch b/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch new file mode 100644 index 000000000..735c91f79 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch @@ -0,0 +1,427 @@ +From 48c916b812652f9453be5bd45a703728926d41ca Mon Sep 17 00:00:00 2001 +From: "T.J. Alumbaugh" +Date: Wed, 18 Jan 2023 00:18:24 +0000 +Subject: [PATCH 15/19] UPSTREAM: mm: multi-gen LRU: section for memcg LRU + +Move memcg LRU code into a dedicated section. Improve the design doc to +outline its architecture. + +Link: https://lkml.kernel.org/r/20230118001827.1040870-5-talumbau@google.com +Change-Id: Id252e420cff7a858acb098cf2b3642da5c40f602 +Signed-off-by: T.J. Alumbaugh +Cc: Yu Zhao +Signed-off-by: Andrew Morton +(cherry picked from commit 36c7b4db7c942ae9e1b111f0c6b468c8b2e33842) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + Documentation/mm/multigen_lru.rst | 33 +++- + include/linux/mm_inline.h | 17 -- + include/linux/mmzone.h | 13 +- + mm/memcontrol.c | 8 +- + mm/vmscan.c | 250 +++++++++++++++++------------- + 5 files changed, 178 insertions(+), 143 deletions(-) + +--- a/Documentation/mm/multigen_lru.rst ++++ b/Documentation/mm/multigen_lru.rst +@@ -186,9 +186,40 @@ is false positive, the cost is an additi + which may yield hot pages anyway. Parameters of the filter itself can + control the false positive rate in the limit. + ++Memcg LRU ++--------- ++An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs, ++since each node and memcg combination has an LRU of folios (see ++``mem_cgroup_lruvec()``). Its goal is to improve the scalability of ++global reclaim, which is critical to system-wide memory overcommit in ++data centers. Note that memcg LRU only applies to global reclaim. ++ ++The basic structure of an memcg LRU can be understood by an analogy to ++the active/inactive LRU (of folios): ++ ++1. It has the young and the old (generations), i.e., the counterparts ++ to the active and the inactive; ++2. The increment of ``max_seq`` triggers promotion, i.e., the ++ counterpart to activation; ++3. Other events trigger similar operations, e.g., offlining an memcg ++ triggers demotion, i.e., the counterpart to deactivation. ++ ++In terms of global reclaim, it has two distinct features: ++ ++1. Sharding, which allows each thread to start at a random memcg (in ++ the old generation) and improves parallelism; ++2. Eventual fairness, which allows direct reclaim to bail out at will ++ and reduces latency without affecting fairness over some time. ++ ++In terms of traversing memcgs during global reclaim, it improves the ++best-case complexity from O(n) to O(1) and does not affect the ++worst-case complexity O(n). Therefore, on average, it has a sublinear ++complexity. ++ + Summary + ------- +-The multi-gen LRU can be disassembled into the following parts: ++The multi-gen LRU (of folios) can be disassembled into the following ++parts: + + * Generations + * Rmap walks +--- a/include/linux/mm_inline.h ++++ b/include/linux/mm_inline.h +@@ -122,18 +122,6 @@ static inline bool lru_gen_in_fault(void + return current->in_lru_fault; + } + +-#ifdef CONFIG_MEMCG +-static inline int lru_gen_memcg_seg(struct lruvec *lruvec) +-{ +- return READ_ONCE(lruvec->lrugen.seg); +-} +-#else +-static inline int lru_gen_memcg_seg(struct lruvec *lruvec) +-{ +- return 0; +-} +-#endif +- + static inline int lru_gen_from_seq(unsigned long seq) + { + return seq % MAX_NR_GENS; +@@ -309,11 +297,6 @@ static inline bool lru_gen_in_fault(void + return false; + } + +-static inline int lru_gen_memcg_seg(struct lruvec *lruvec) +-{ +- return 0; +-} +- + static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) + { + return false; +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -368,15 +368,6 @@ 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) + +-/* see the comment on MEMCG_NR_GENS */ +-enum { +- MEMCG_LRU_NOP, +- MEMCG_LRU_HEAD, +- MEMCG_LRU_TAIL, +- MEMCG_LRU_OLD, +- MEMCG_LRU_YOUNG, +-}; +- + #ifdef CONFIG_LRU_GEN + + enum { +@@ -557,7 +548,7 @@ void lru_gen_exit_memcg(struct mem_cgrou + void lru_gen_online_memcg(struct mem_cgroup *memcg); + void lru_gen_offline_memcg(struct mem_cgroup *memcg); + void lru_gen_release_memcg(struct mem_cgroup *memcg); +-void lru_gen_rotate_memcg(struct lruvec *lruvec, int op); ++void lru_gen_soft_reclaim(struct lruvec *lruvec); + + #else /* !CONFIG_MEMCG */ + +@@ -608,7 +599,7 @@ static inline void lru_gen_release_memcg + { + } + +-static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) ++static inline void lru_gen_soft_reclaim(struct lruvec *lruvec) + { + } + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -478,12 +478,8 @@ static void mem_cgroup_update_tree(struc + struct mem_cgroup_tree_per_node *mctz; + + if (lru_gen_enabled()) { +- struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec; +- +- /* see the comment on MEMCG_NR_GENS */ +- if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD) +- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD); +- ++ if (soft_limit_excess(memcg)) ++ lru_gen_soft_reclaim(&memcg->nodeinfo[nid]->lruvec); + return; + } + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4690,6 +4690,148 @@ void lru_gen_look_around(struct page_vma + } + + /****************************************************************************** ++ * memcg LRU ++ ******************************************************************************/ ++ ++/* see the comment on MEMCG_NR_GENS */ ++enum { ++ MEMCG_LRU_NOP, ++ MEMCG_LRU_HEAD, ++ MEMCG_LRU_TAIL, ++ MEMCG_LRU_OLD, ++ MEMCG_LRU_YOUNG, ++}; ++ ++#ifdef CONFIG_MEMCG ++ ++static int lru_gen_memcg_seg(struct lruvec *lruvec) ++{ ++ return READ_ONCE(lruvec->lrugen.seg); ++} ++ ++static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) ++{ ++ int seg; ++ int old, new; ++ int bin = get_random_u32_below(MEMCG_NR_BINS); ++ struct pglist_data *pgdat = lruvec_pgdat(lruvec); ++ ++ spin_lock(&pgdat->memcg_lru.lock); ++ ++ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); ++ ++ seg = 0; ++ new = old = lruvec->lrugen.gen; ++ ++ /* see the comment on MEMCG_NR_GENS */ ++ if (op == MEMCG_LRU_HEAD) ++ seg = MEMCG_LRU_HEAD; ++ else if (op == MEMCG_LRU_TAIL) ++ seg = MEMCG_LRU_TAIL; ++ else if (op == MEMCG_LRU_OLD) ++ new = get_memcg_gen(pgdat->memcg_lru.seq); ++ else if (op == MEMCG_LRU_YOUNG) ++ new = get_memcg_gen(pgdat->memcg_lru.seq + 1); ++ else ++ VM_WARN_ON_ONCE(true); ++ ++ hlist_nulls_del_rcu(&lruvec->lrugen.list); ++ ++ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD) ++ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); ++ else ++ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); ++ ++ pgdat->memcg_lru.nr_memcgs[old]--; ++ pgdat->memcg_lru.nr_memcgs[new]++; ++ ++ lruvec->lrugen.gen = new; ++ WRITE_ONCE(lruvec->lrugen.seg, seg); ++ ++ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq)) ++ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); ++ ++ spin_unlock(&pgdat->memcg_lru.lock); ++} ++ ++void lru_gen_online_memcg(struct mem_cgroup *memcg) ++{ ++ int gen; ++ int nid; ++ int bin = get_random_u32_below(MEMCG_NR_BINS); ++ ++ for_each_node(nid) { ++ struct pglist_data *pgdat = NODE_DATA(nid); ++ struct lruvec *lruvec = get_lruvec(memcg, nid); ++ ++ spin_lock(&pgdat->memcg_lru.lock); ++ ++ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list)); ++ ++ gen = get_memcg_gen(pgdat->memcg_lru.seq); ++ ++ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]); ++ pgdat->memcg_lru.nr_memcgs[gen]++; ++ ++ lruvec->lrugen.gen = gen; ++ ++ spin_unlock(&pgdat->memcg_lru.lock); ++ } ++} ++ ++void lru_gen_offline_memcg(struct mem_cgroup *memcg) ++{ ++ int nid; ++ ++ for_each_node(nid) { ++ struct lruvec *lruvec = get_lruvec(memcg, nid); ++ ++ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD); ++ } ++} ++ ++void lru_gen_release_memcg(struct mem_cgroup *memcg) ++{ ++ int gen; ++ int nid; ++ ++ for_each_node(nid) { ++ struct pglist_data *pgdat = NODE_DATA(nid); ++ struct lruvec *lruvec = get_lruvec(memcg, nid); ++ ++ spin_lock(&pgdat->memcg_lru.lock); ++ ++ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); ++ ++ gen = lruvec->lrugen.gen; ++ ++ hlist_nulls_del_rcu(&lruvec->lrugen.list); ++ pgdat->memcg_lru.nr_memcgs[gen]--; ++ ++ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq)) ++ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); ++ ++ spin_unlock(&pgdat->memcg_lru.lock); ++ } ++} ++ ++void lru_gen_soft_reclaim(struct lruvec *lruvec) ++{ ++ /* see the comment on MEMCG_NR_GENS */ ++ if (lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD) ++ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD); ++} ++ ++#else /* !CONFIG_MEMCG */ ++ ++static int lru_gen_memcg_seg(struct lruvec *lruvec) ++{ ++ return 0; ++} ++ ++#endif ++ ++/****************************************************************************** + * the eviction + ******************************************************************************/ + +@@ -5386,53 +5528,6 @@ done: + pgdat->kswapd_failures = 0; + } + +-#ifdef CONFIG_MEMCG +-void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) +-{ +- int seg; +- int old, new; +- int bin = get_random_u32_below(MEMCG_NR_BINS); +- struct pglist_data *pgdat = lruvec_pgdat(lruvec); +- +- spin_lock(&pgdat->memcg_lru.lock); +- +- VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); +- +- seg = 0; +- new = old = lruvec->lrugen.gen; +- +- /* see the comment on MEMCG_NR_GENS */ +- if (op == MEMCG_LRU_HEAD) +- seg = MEMCG_LRU_HEAD; +- else if (op == MEMCG_LRU_TAIL) +- seg = MEMCG_LRU_TAIL; +- else if (op == MEMCG_LRU_OLD) +- new = get_memcg_gen(pgdat->memcg_lru.seq); +- else if (op == MEMCG_LRU_YOUNG) +- new = get_memcg_gen(pgdat->memcg_lru.seq + 1); +- else +- VM_WARN_ON_ONCE(true); +- +- hlist_nulls_del_rcu(&lruvec->lrugen.list); +- +- if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD) +- hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); +- else +- hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); +- +- pgdat->memcg_lru.nr_memcgs[old]--; +- pgdat->memcg_lru.nr_memcgs[new]++; +- +- lruvec->lrugen.gen = new; +- WRITE_ONCE(lruvec->lrugen.seg, seg); +- +- if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq)) +- WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); +- +- spin_unlock(&pgdat->memcg_lru.lock); +-} +-#endif +- + /****************************************************************************** + * state change + ******************************************************************************/ +@@ -6078,67 +6173,6 @@ void lru_gen_exit_memcg(struct mem_cgrou + } + } + +-void lru_gen_online_memcg(struct mem_cgroup *memcg) +-{ +- int gen; +- int nid; +- int bin = get_random_u32_below(MEMCG_NR_BINS); +- +- for_each_node(nid) { +- struct pglist_data *pgdat = NODE_DATA(nid); +- struct lruvec *lruvec = get_lruvec(memcg, nid); +- +- spin_lock(&pgdat->memcg_lru.lock); +- +- VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list)); +- +- gen = get_memcg_gen(pgdat->memcg_lru.seq); +- +- hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]); +- pgdat->memcg_lru.nr_memcgs[gen]++; +- +- lruvec->lrugen.gen = gen; +- +- spin_unlock(&pgdat->memcg_lru.lock); +- } +-} +- +-void lru_gen_offline_memcg(struct mem_cgroup *memcg) +-{ +- int nid; +- +- for_each_node(nid) { +- struct lruvec *lruvec = get_lruvec(memcg, nid); +- +- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD); +- } +-} +- +-void lru_gen_release_memcg(struct mem_cgroup *memcg) +-{ +- int gen; +- int nid; +- +- for_each_node(nid) { +- struct pglist_data *pgdat = NODE_DATA(nid); +- struct lruvec *lruvec = get_lruvec(memcg, nid); +- +- spin_lock(&pgdat->memcg_lru.lock); +- +- VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); +- +- gen = lruvec->lrugen.gen; +- +- hlist_nulls_del_rcu(&lruvec->lrugen.list); +- pgdat->memcg_lru.nr_memcgs[gen]--; +- +- if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq)) +- WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); +- +- spin_unlock(&pgdat->memcg_lru.lock); +- } +-} +- + #endif /* CONFIG_MEMCG */ + + static int __init init_lru_gen(void) diff --git a/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch b/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch new file mode 100644 index 000000000..944737550 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch @@ -0,0 +1,40 @@ +From bec433f29537652ed054148edfd7e2183ddcf7c3 Mon Sep 17 00:00:00 2001 +From: "T.J. Alumbaugh" +Date: Wed, 18 Jan 2023 00:18:25 +0000 +Subject: [PATCH 16/19] UPSTREAM: mm: multi-gen LRU: improve + lru_gen_exit_memcg() + +Add warnings and poison ->next. + +Link: https://lkml.kernel.org/r/20230118001827.1040870-6-talumbau@google.com +Change-Id: I53de9e04c1ae941e122b33cd45d2bbb5f34aae0c +Signed-off-by: T.J. Alumbaugh +Cc: Yu Zhao +Signed-off-by: Andrew Morton +(cherry picked from commit 37cc99979d04cca677c0ad5c0acd1149ec165d1b) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -6160,12 +6160,17 @@ void lru_gen_exit_memcg(struct mem_cgrou + int i; + int nid; + ++ VM_WARN_ON_ONCE(!list_empty(&memcg->mm_list.fifo)); ++ + for_each_node(nid) { + struct lruvec *lruvec = get_lruvec(memcg, nid); + ++ VM_WARN_ON_ONCE(lruvec->mm_state.nr_walkers); + VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, + sizeof(lruvec->lrugen.nr_pages))); + ++ lruvec->lrugen.list.next = LIST_POISON1; ++ + for (i = 0; i < NR_BLOOM_FILTERS; i++) { + bitmap_free(lruvec->mm_state.filters[i]); + lruvec->mm_state.filters[i] = NULL; diff --git a/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch b/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch new file mode 100644 index 000000000..2273977dc --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch @@ -0,0 +1,135 @@ +From fc0e3b06e0f19917b7ecad7967a72f61d4743644 Mon Sep 17 00:00:00 2001 +From: "T.J. Alumbaugh" +Date: Wed, 18 Jan 2023 00:18:26 +0000 +Subject: [PATCH 17/19] UPSTREAM: mm: multi-gen LRU: improve walk_pmd_range() + +Improve readability of walk_pmd_range() and walk_pmd_range_locked(). + +Link: https://lkml.kernel.org/r/20230118001827.1040870-7-talumbau@google.com +Change-Id: Ia084fbf53fe989673b7804ca8ca520af12d7d52a +Signed-off-by: T.J. Alumbaugh +Cc: Yu Zhao +Signed-off-by: Andrew Morton +(cherry picked from commit b5ff4133617d0eced35b685da0bd0929dd9fabb7) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 40 ++++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3980,8 +3980,8 @@ restart: + } + + #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) ++static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area_struct *vma, ++ struct mm_walk *args, unsigned long *bitmap, unsigned long *first) + { + int i; + pmd_t *pmd; +@@ -3994,18 +3994,19 @@ static void walk_pmd_range_locked(pud_t + VM_WARN_ON_ONCE(pud_leaf(*pud)); + + /* try to batch at most 1+MIN_LRU_BATCH+1 entries */ +- if (*start == -1) { +- *start = next; ++ if (*first == -1) { ++ *first = addr; ++ bitmap_zero(bitmap, MIN_LRU_BATCH); + return; + } + +- i = next == -1 ? 0 : pmd_index(next) - pmd_index(*start); ++ i = addr == -1 ? 0 : pmd_index(addr) - pmd_index(*first); + if (i && i <= MIN_LRU_BATCH) { + __set_bit(i - 1, bitmap); + return; + } + +- pmd = pmd_offset(pud, *start); ++ pmd = pmd_offset(pud, *first); + + ptl = pmd_lockptr(args->mm, pmd); + if (!spin_trylock(ptl)) +@@ -4016,15 +4017,16 @@ static void walk_pmd_range_locked(pud_t + do { + unsigned long pfn; + struct folio *folio; +- unsigned long addr = i ? (*start & PMD_MASK) + i * PMD_SIZE : *start; ++ ++ /* don't round down the first address */ ++ addr = i ? (*first & PMD_MASK) + i * PMD_SIZE : *first; + + pfn = get_pmd_pfn(pmd[i], vma, addr); + if (pfn == -1) + goto next; + + if (!pmd_trans_huge(pmd[i])) { +- if (arch_has_hw_nonleaf_pmd_young() && +- get_cap(LRU_GEN_NONLEAF_YOUNG)) ++ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG)) + pmdp_test_and_clear_young(vma, addr, pmd + i); + goto next; + } +@@ -4053,12 +4055,11 @@ next: + arch_leave_lazy_mmu_mode(); + spin_unlock(ptl); + done: +- *start = -1; +- bitmap_zero(bitmap, MIN_LRU_BATCH); ++ *first = -1; + } + #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) ++static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area_struct *vma, ++ struct mm_walk *args, unsigned long *bitmap, unsigned long *first) + { + } + #endif +@@ -4071,9 +4072,9 @@ static void walk_pmd_range(pud_t *pud, u + unsigned long next; + unsigned long addr; + struct vm_area_struct *vma; +- unsigned long pos = -1; ++ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)]; ++ unsigned long first = -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)); + +@@ -4115,18 +4116,17 @@ restart: + if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) + continue; + +- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); ++ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first); + continue; + } + #endif + walk->mm_stats[MM_NONLEAF_TOTAL]++; + +- if (arch_has_hw_nonleaf_pmd_young() && +- get_cap(LRU_GEN_NONLEAF_YOUNG)) { ++ if (arch_has_hw_nonleaf_pmd_young() && 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, &first); + } + + if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i)) +@@ -4143,7 +4143,7 @@ restart: + update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i); + } + +- walk_pmd_range_locked(pud, -1, vma, args, bitmap, &pos); ++ walk_pmd_range_locked(pud, -1, vma, args, bitmap, &first); + + if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end)) + goto restart; diff --git a/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch b/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch new file mode 100644 index 000000000..1f071f083 --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch @@ -0,0 +1,148 @@ +From e604c3ccb4dfbdde2467fccef9bb36170a392695 Mon Sep 17 00:00:00 2001 +From: "T.J. Alumbaugh" +Date: Wed, 18 Jan 2023 00:18:27 +0000 +Subject: [PATCH 18/19] UPSTREAM: mm: multi-gen LRU: simplify + lru_gen_look_around() + +Update the folio generation in place with or without +current->reclaim_state->mm_walk. The LRU lock is held for longer, if +mm_walk is NULL and the number of folios to update is more than +PAGEVEC_SIZE. + +This causes a measurable regression from the LRU lock contention during a +microbencmark. But a tiny regression is not worth the complexity. + +Link: https://lkml.kernel.org/r/20230118001827.1040870-8-talumbau@google.com +Change-Id: I9ce18b4f4062e6c1c13c98ece9422478eb8e1846 +Signed-off-by: T.J. Alumbaugh +Cc: Yu Zhao +Signed-off-by: Andrew Morton +(cherry picked from commit abf086721a2f1e6897c57796f7268df1b194c750) +Bug: 274865848 +Signed-off-by: T.J. Mercier +--- + mm/vmscan.c | 73 +++++++++++++++++------------------------------------ + 1 file changed, 23 insertions(+), 50 deletions(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -4571,13 +4571,12 @@ static void lru_gen_age_node(struct pgli + 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; + struct lru_gen_mm_walk *walk; + int young = 0; +- unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; ++ pte_t *pte = pvmw->pte; ++ unsigned long addr = pvmw->address; + struct folio *folio = pfn_folio(pvmw->pfn); + struct mem_cgroup *memcg = folio_memcg(folio); + struct pglist_data *pgdat = folio_pgdat(folio); +@@ -4594,25 +4593,28 @@ void lru_gen_look_around(struct page_vma + /* 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; ++ start = max(addr & PMD_MASK, pvmw->vma->vm_start); ++ end = min(addr | ~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) ++ if (addr - 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) ++ else if (end - addr < 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; ++ start = addr - MIN_LRU_BATCH * PAGE_SIZE / 2; ++ end = addr + MIN_LRU_BATCH * PAGE_SIZE / 2; + } + } + +- pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE; ++ /* folio_update_gen() requires stable folio_memcg() */ ++ if (!mem_cgroup_trylock_pages(memcg)) ++ return; + +- rcu_read_lock(); + arch_enter_lazy_mmu_mode(); + ++ pte -= (addr - start) / PAGE_SIZE; ++ + for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) { + unsigned long pfn; + +@@ -4637,56 +4639,27 @@ void lru_gen_look_around(struct page_vma + !folio_test_swapcache(folio))) + folio_mark_dirty(folio); + ++ if (walk) { ++ 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); ++ ++ continue; ++ } ++ + old_gen = folio_lru_gen(folio); + if (old_gen < 0) + folio_set_referenced(folio); + else if (old_gen != new_gen) +- __set_bit(i, bitmap); ++ folio_activate(folio); + } + + arch_leave_lazy_mmu_mode(); +- rcu_read_unlock(); ++ mem_cgroup_unlock_pages(); + + /* 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); +- } +- return; +- } +- +- /* folio_update_gen() requires stable folio_memcg() */ +- if (!mem_cgroup_trylock_pages(memcg)) +- return; +- +- 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])); +- if (folio_memcg_rcu(folio) != memcg) +- continue; +- +- old_gen = folio_update_gen(folio, new_gen); +- if (old_gen < 0 || old_gen == new_gen) +- continue; +- +- if (walk) +- update_batch_size(walk, folio, old_gen, new_gen); +- else +- lru_gen_update_size(lruvec, folio, old_gen, new_gen); +- } +- +- if (!walk) +- spin_unlock_irq(&lruvec->lru_lock); +- +- mem_cgroup_unlock_pages(); + } + + /****************************************************************************** diff --git a/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch b/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch new file mode 100644 index 000000000..fc42a245f --- /dev/null +++ b/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch @@ -0,0 +1,273 @@ +From 418038c22452df38cde519cc8c662bb15139764a Mon Sep 17 00:00:00 2001 +From: Kalesh Singh +Date: Thu, 13 Apr 2023 14:43:26 -0700 +Subject: [PATCH 19/19] mm: Multi-gen LRU: remove wait_event_killable() + +Android 14 and later default to MGLRU [1] and field telemetry showed +occasional long tail latency (>100ms) in the reclaim path. + +Tracing revealed priority inversion in the reclaim path. In +try_to_inc_max_seq(), when high priority tasks were blocked on +wait_event_killable(), the preemption of the low priority task to call +wake_up_all() caused those high priority tasks to wait longer than +necessary. In general, this problem is not different from others of its +kind, e.g., one caused by mutex_lock(). However, it is specific to MGLRU +because it introduced the new wait queue lruvec->mm_state.wait. + +The purpose of this new wait queue is to avoid the thundering herd +problem. If many direct reclaimers rush into try_to_inc_max_seq(), only +one can succeed, i.e., the one to wake up the rest, and the rest who +failed might cause premature OOM kills if they do not wait. So far there +is no evidence supporting this scenario, based on how often the wait has +been hit. And this begs the question how useful the wait queue is in +practice. + +Based on Minchan's recommendation, which is in line with his commit +6d4675e60135 ("mm: don't be stuck to rmap lock on reclaim path") and the +rest of the MGLRU code which also uses trylock when possible, remove the +wait queue. + +[1] https://android-review.googlesource.com/q/I7ed7fbfd6ef9ce10053347528125dd98c39e50bf + +Link: https://lkml.kernel.org/r/20230413214326.2147568-1-kaleshsingh@google.com +Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks") +Signed-off-by: Kalesh Singh +Suggested-by: Minchan Kim +Reported-by: Wei Wang +Acked-by: Yu Zhao +Cc: Minchan Kim +Cc: Jan Alexander Steffens (heftig) +Cc: Oleksandr Natalenko +Cc: Suleiman Souhlal +Cc: Suren Baghdasaryan +Signed-off-by: Andrew Morton +--- + include/linux/mmzone.h | 8 +-- + mm/vmscan.c | 112 +++++++++++++++-------------------------- + 2 files changed, 42 insertions(+), 78 deletions(-) + +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -453,18 +453,14 @@ enum { + struct lru_gen_mm_state { + /* set to max_seq after each iteration */ + unsigned long seq; +- /* where the current iteration continues (inclusive) */ ++ /* where the current iteration continues after */ + struct list_head *head; +- /* where the last iteration ended (exclusive) */ ++ /* where the last iteration ended before */ + 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 { +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3371,18 +3371,13 @@ void lru_gen_del_mm(struct mm_struct *mm + if (!lruvec) + continue; + +- /* where the last iteration ended (exclusive) */ ++ /* where the current iteration continues after */ ++ if (lruvec->mm_state.head == &mm->lru_gen.list) ++ lruvec->mm_state.head = lruvec->mm_state.head->prev; ++ ++ /* where the last iteration ended before */ + 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); +@@ -3478,68 +3473,54 @@ static bool iterate_mm_list(struct lruve + struct mm_struct **iter) + { + bool first = false; +- bool last = true; ++ bool last = false; + 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. ++ * mm_state->seq is incremented after each iteration of mm_list. There ++ * are three interesting cases for this page table walker: ++ * 1. It tries to start a new iteration with a stale max_seq: there is ++ * nothing left to do. ++ * 2. It started the next iteration: it needs to reset the Bloom filter ++ * so that a fresh set of PTE tables can be recorded. ++ * 3. It ended the current iteration: it needs to reset the mm stats ++ * counters and tell its caller to increment max_seq. + */ + 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; ++ if (walk->max_seq <= mm_state->seq) + goto done; +- } + +- if (!mm_state->nr_walkers) { +- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); ++ if (!mm_state->head) ++ mm_state->head = &mm_list->fifo; + +- mm_state->head = mm_list->fifo.next; ++ if (mm_state->head == &mm_list->fifo) + first = true; +- } +- +- while (!mm && mm_state->head != &mm_list->fifo) { +- mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list); + ++ do { + mm_state->head = mm_state->head->next; ++ if (mm_state->head == &mm_list->fifo) { ++ WRITE_ONCE(mm_state->seq, mm_state->seq + 1); ++ last = true; ++ break; ++ } + + /* 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; ++ if (!mm_state->tail || mm_state->tail == mm_state->head) { ++ mm_state->tail = mm_state->head->next; + walk->force_scan = true; + } + ++ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list); + if (should_skip_mm(mm, walk)) + mm = NULL; +- } +- +- if (mm_state->head == &mm_list->fifo) +- WRITE_ONCE(mm_state->seq, mm_state->seq + 1); ++ } while (!mm); + 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); + +@@ -3567,9 +3548,9 @@ static bool iterate_mm_list_nowalk(struc + + 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); +- ++ if (max_seq > mm_state->seq) { ++ mm_state->head = NULL; ++ mm_state->tail = NULL; + WRITE_ONCE(mm_state->seq, mm_state->seq + 1); + reset_mm_stats(lruvec, NULL, true); + success = true; +@@ -4172,10 +4153,6 @@ restart: + + 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; +@@ -4208,8 +4185,14 @@ static void walk_mm(struct lruvec *lruve + walk->next_addr = FIRST_USER_ADDRESS; + + do { ++ DEFINE_MAX_SEQ(lruvec); ++ + err = -EBUSY; + ++ /* another thread might have called inc_max_seq() */ ++ if (walk->max_seq != max_seq) ++ break; ++ + /* folio_update_gen() requires stable folio_memcg() */ + if (!mem_cgroup_trylock_pages(memcg)) + break; +@@ -4442,25 +4425,12 @@ static bool try_to_inc_max_seq(struct lr + 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 false; +- } ++ if (success) ++ inc_max_seq(lruvec, can_swap, force_scan); + +- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); +- +- 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); +- +- return true; ++ return success; + } + + /****************************************************************************** +@@ -6105,7 +6075,6 @@ void lru_gen_init_lruvec(struct lruvec * + INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]); + + lruvec->mm_state.seq = MIN_NR_GENS; +- init_waitqueue_head(&lruvec->mm_state.wait); + } + + #ifdef CONFIG_MEMCG +@@ -6138,7 +6107,6 @@ void lru_gen_exit_memcg(struct mem_cgrou + for_each_node(nid) { + struct lruvec *lruvec = get_lruvec(memcg, nid); + +- VM_WARN_ON_ONCE(lruvec->mm_state.nr_walkers); + VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, + sizeof(lruvec->lrugen.nr_pages))); + 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 deleted file mode 100644 index f363b1a8e..000000000 --- a/target/linux/generic/backport-6.1/100-net-add-netdev_sw_irq_coalesce_default_on.patch +++ /dev/null @@ -1,59 +0,0 @@ -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 -@@ -10534,6 +10534,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 deleted file mode 100644 index 258d38afa..000000000 --- a/target/linux/generic/backport-6.1/101-net-Remove-the-obsolte-u64_stats_fetch_-_irq-users-d.patch +++ /dev/null @@ -1,2022 +0,0 @@ -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 -@@ -3305,10 +3305,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; -@@ -3316,20 +3316,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 -@@ -948,7 +948,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; -@@ -965,15 +965,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; -@@ -1260,9 +1260,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 -@@ -6393,10 +6393,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 -@@ -6656,10 +6656,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; - } -@@ -6672,10 +6672,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 -@@ -4802,10 +4802,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; - } -@@ -4819,10 +4819,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 -@@ -9051,10 +9051,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; - } -@@ -9074,10 +9074,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 -@@ -866,7 +866,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; -@@ -878,7 +878,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; -@@ -3708,13 +3708,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 -@@ -881,7 +881,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; -@@ -889,10 +889,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; -@@ -902,7 +902,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 -@@ -1376,12 +1376,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 -@@ -2801,9 +2801,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; -@@ -2882,9 +2882,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; -@@ -2938,9 +2938,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 -@@ -1866,13 +1866,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 -@@ -2107,18 +2107,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; -@@ -2726,12 +2726,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; - } - -@@ -2740,12 +2740,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 deleted file mode 100644 index 59c422457..000000000 --- a/target/linux/generic/backport-6.1/102-drivers-net-convert-to-boolean-for-the-mac_managed_p.patch +++ /dev/null @@ -1,56 +0,0 @@ -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 -@@ -2234,7 +2234,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 -@@ -5015,7 +5015,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 -@@ -714,7 +714,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); - -@@ -734,7 +734,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 deleted file mode 100644 index 40e81287a..000000000 --- a/target/linux/generic/backport-6.1/103-r8169-use-tp_to_dev-instead-of-open-code.patch +++ /dev/null @@ -1,38 +0,0 @@ -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 -@@ -4556,12 +4556,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 deleted file mode 100644 index b581d7491..000000000 --- a/target/linux/generic/backport-6.1/104-r8169-enable-GRO-software-interrupt-coalescing-per-d.patch +++ /dev/null @@ -1,33 +0,0 @@ -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 -@@ -5280,6 +5280,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/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch b/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch new file mode 100644 index 000000000..d8d0cf955 --- /dev/null +++ b/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch @@ -0,0 +1,63 @@ +From 579aee9fc594af94c242068c011b0233563d4bbf Mon Sep 17 00:00:00 2001 +From: Stephen Rothwell +Date: Mon, 10 Oct 2022 16:57:21 +1100 +Subject: [PATCH] powerpc: suppress some linker warnings in recent linker + versions + +This is a follow on from commit + + 0d362be5b142 ("Makefile: link with -z noexecstack --no-warn-rwx-segments") + +for arch/powerpc/boot to address wanrings like: + + ld: warning: opal-calls.o: missing .note.GNU-stack section implies executable stack + ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker + ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions + +This fixes issue https://github.com/linuxppc/issues/issues/417 + +Signed-off-by: Stephen Rothwell +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20221010165721.106267e6@canb.auug.org.au +--- + arch/powerpc/boot/wrapper | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/boot/wrapper ++++ b/arch/powerpc/boot/wrapper +@@ -215,6 +215,11 @@ ld_version() + }' + } + ++ld_is_lld() ++{ ++ ${CROSS}ld -V 2>&1 | grep -q LLD ++} ++ + # Do not include PT_INTERP segment when linking pie. Non-pie linking + # just ignores this option. + LD_VERSION=$(${CROSS}ld --version | ld_version) +@@ -223,6 +228,14 @@ if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VE + nodl="--no-dynamic-linker" + fi + ++# suppress some warnings in recent ld versions ++nowarn="-z noexecstack" ++if ! ld_is_lld; then ++ if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then ++ nowarn="$nowarn --no-warn-rwx-segments" ++ fi ++fi ++ + platformo=$object/"$platform".o + lds=$object/zImage.lds + ext=strip +@@ -504,7 +517,7 @@ if [ "$platform" != "miboot" ]; then + text_start="-Ttext $link_address" + fi + #link everything +- ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $rodynamic $notext -o "$ofile" $map \ ++ ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $nowarn $rodynamic $notext -o "$ofile" $map \ + $platformo $tmp $object/wrapper.a + rm $tmp + fi diff --git a/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch b/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch new file mode 100644 index 000000000..7dbc27172 --- /dev/null +++ b/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch @@ -0,0 +1,35 @@ +From ebed787a0becb9354f0a23620a5130cccd6c730c Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Thu, 19 Jan 2023 03:45:43 +0000 +Subject: [PATCH] mtd: spinand: macronix: use scratch buffer for DMA operation + +The mx35lf1ge4ab_get_eccsr() function uses an SPI DMA operation to +read the eccsr, hence the buffer should not be on stack. Since commit +380583227c0c7f ("spi: spi-mem: Add extra sanity checks on the op param") +the kernel emmits a warning and blocks such operations. + +Use the scratch buffer to get eccsr instead of trying to directly read +into a stack-allocated variable. + +Signed-off-by: Daniel Golle +Reviewed-by: Dhruva Gole +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/Y8i85zM0u4XdM46z@makrotopia.org +--- + drivers/mtd/nand/spi/macronix.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/nand/spi/macronix.c ++++ b/drivers/mtd/nand/spi/macronix.c +@@ -83,9 +83,10 @@ static int mx35lf1ge4ab_ecc_get_status(s + * in order to avoid forcing the wear-leveling layer to move + * data around if it's not necessary. + */ +- if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr)) ++ if (mx35lf1ge4ab_get_eccsr(spinand, spinand->scratchbuf)) + return nanddev_get_ecc_conf(nand)->strength; + ++ eccsr = *spinand->scratchbuf; + if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength || + !eccsr)) + return nanddev_get_ecc_conf(nand)->strength; diff --git a/target/linux/generic/backport-6.1/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch b/target/linux/generic/backport-6.1/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch new file mode 100644 index 000000000..9ddda420a --- /dev/null +++ b/target/linux/generic/backport-6.1/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch @@ -0,0 +1,47 @@ +From 281f7a6c1a33fffcde32001bacbb4f672140fbf9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Wed, 8 Mar 2023 09:20:21 +0100 +Subject: [PATCH] mtd: core: prepare mtd_otp_nvmem_add() to handle + -EPROBE_DEFER + +NVMEM soon will get the ability for nvmem layouts and these might +not be ready when nvmem_register() is called and thus it might +return -EPROBE_DEFER. Don't print the error message in this case. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc +--- + drivers/mtd/mtdcore.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -953,8 +953,8 @@ static int mtd_otp_nvmem_add(struct mtd_ + nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size, + mtd_nvmem_user_otp_reg_read); + if (IS_ERR(nvmem)) { +- dev_err(dev, "Failed to register OTP NVMEM device\n"); +- return PTR_ERR(nvmem); ++ err = PTR_ERR(nvmem); ++ goto err; + } + mtd->otp_user_nvmem = nvmem; + } +@@ -971,7 +971,6 @@ static int mtd_otp_nvmem_add(struct mtd_ + nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size, + mtd_nvmem_fact_otp_reg_read); + if (IS_ERR(nvmem)) { +- dev_err(dev, "Failed to register OTP NVMEM device\n"); + err = PTR_ERR(nvmem); + goto err; + } +@@ -983,7 +982,7 @@ static int mtd_otp_nvmem_add(struct mtd_ + + err: + nvmem_unregister(mtd->otp_user_nvmem); +- return err; ++ return dev_err_probe(dev, err, "Failed to register OTP NVMEM device\n"); + } + + /** diff --git a/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch b/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch new file mode 100644 index 000000000..28b7b4383 --- /dev/null +++ b/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch @@ -0,0 +1,41 @@ +From 7390609b0121a1b982c5ecdfcd72dc328e5784ee Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:42 +0000 +Subject: [PATCH] net: add helper eth_addr_add() + +Add a helper to add an offset to a ethernet address. This comes in handy +if you have a base ethernet address for multiple interfaces. + +Signed-off-by: Michael Walle +Reviewed-by: Andrew Lunn +Acked-by: Jakub Kicinski +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-9-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/etherdevice.h | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/include/linux/etherdevice.h ++++ b/include/linux/etherdevice.h +@@ -508,6 +508,20 @@ static inline void eth_addr_inc(u8 *addr + } + + /** ++ * eth_addr_add() - Add (or subtract) an offset to/from the given MAC address. ++ * ++ * @offset: Offset to add. ++ * @addr: Pointer to a six-byte array containing Ethernet address to increment. ++ */ ++static inline void eth_addr_add(u8 *addr, long offset) ++{ ++ u64 u = ether_addr_to_u64(addr); ++ ++ u += offset; ++ u64_to_ether_addr(u, addr); ++} ++ ++/** + * is_etherdev_addr - Tell if given Ethernet address belongs to the device. + * @dev: Pointer to a device structure + * @addr: Pointer to a six-byte array containing the Ethernet address diff --git a/target/linux/generic/backport-6.1/700-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch b/target/linux/generic/backport-6.1/700-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch new file mode 100644 index 000000000..81c14a055 --- /dev/null +++ b/target/linux/generic/backport-6.1/700-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch @@ -0,0 +1,48 @@ +From 9c5a170677c3c8facc83e931a57f4c99c0511ae0 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:10:37 +0100 +Subject: [PATCH] net: phylink: add phylink_get_link_timer_ns() helper + +Add a helper to convert the PHY interface mode to the required link +timer setting as stated by the appropriate standard. Inappropriate +interface modes return an error. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + include/linux/phylink.h | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/include/linux/phylink.h ++++ b/include/linux/phylink.h +@@ -614,6 +614,30 @@ int phylink_speed_up(struct phylink *pl) + + void phylink_set_port_modes(unsigned long *bits); + ++/** ++ * phylink_get_link_timer_ns - return the PCS link timer value ++ * @interface: link &typedef phy_interface_t mode ++ * ++ * Return the PCS link timer setting in nanoseconds for the PHY @interface ++ * mode, or -EINVAL if not appropriate. ++ */ ++static inline int phylink_get_link_timer_ns(phy_interface_t interface) ++{ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_QSGMII: ++ case PHY_INTERFACE_MODE_USXGMII: ++ return 1600000; ++ ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_2500BASEX: ++ return 10000000; ++ ++ default: ++ return -EINVAL; ++ } ++} ++ + void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, + u16 bmsr, u16 lpa); + void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs, diff --git a/target/linux/generic/backport-6.1/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch b/target/linux/generic/backport-6.1/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch new file mode 100644 index 000000000..980cb0f91 --- /dev/null +++ b/target/linux/generic/backport-6.1/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch @@ -0,0 +1,394 @@ +From 4765a9722e09765866e131ec31f7b9cf4c1f4854 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 19 Mar 2023 12:57:50 +0000 +Subject: [PATCH] net: pcs: add driver for MediaTek SGMII PCS + +The SGMII core found in several MediaTek SoCs is identical to what can +also be found in MediaTek's MT7531 Ethernet switch IC. +As this has not always been clear, both drivers developed different +implementations to deal with the PCS. +Recently Alexander Couzens pointed out this fact which lead to the +development of this shared driver. + +Add a dedicated driver, mostly by copying the code now found in the +Ethernet driver. The now redundant code will be removed by a follow-up +commit. + +Suggested-by: Alexander Couzens +Suggested-by: Russell King (Oracle) +Signed-off-by: Daniel Golle +Tested-by: Frank Wunderlich +Reviewed-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + MAINTAINERS | 8 + + drivers/net/pcs/Kconfig | 7 + + drivers/net/pcs/Makefile | 1 + + drivers/net/pcs/pcs-mtk-lynxi.c | 305 ++++++++++++++++++++++++++++++ + include/linux/pcs/pcs-mtk-lynxi.h | 13 ++ + 5 files changed, 334 insertions(+) + create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c + create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -12926,6 +12926,14 @@ L: netdev@vger.kernel.org + S: Maintained + F: drivers/net/ethernet/mediatek/ + ++MEDIATEK ETHERNET PCS DRIVER ++M: Alexander Couzens ++M: Daniel Golle ++L: netdev@vger.kernel.org ++S: Maintained ++F: drivers/net/pcs/pcs-mtk-lynxi.c ++F: include/linux/pcs/pcs-mtk-lynxi.h ++ + MEDIATEK I2C CONTROLLER DRIVER + M: Qii Wang + L: linux-i2c@vger.kernel.org +--- a/drivers/net/pcs/Kconfig ++++ b/drivers/net/pcs/Kconfig +@@ -32,4 +32,11 @@ config PCS_ALTERA_TSE + This module provides helper functions for the Altera Triple Speed + Ethernet SGMII PCS, that can be found on the Intel Socfpga family. + ++config PCS_MTK_LYNXI ++ tristate ++ select REGMAP ++ help ++ This module provides helpers to phylink for managing the LynxI PCS ++ which is part of MediaTek's SoC and Ethernet switch ICs. ++ + endmenu +--- a/drivers/net/pcs/Makefile ++++ b/drivers/net/pcs/Makefile +@@ -7,3 +7,4 @@ obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o + obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o + obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o + obj-$(CONFIG_PCS_ALTERA_TSE) += pcs-altera-tse.o ++obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o +--- /dev/null ++++ b/drivers/net/pcs/pcs-mtk-lynxi.c +@@ -0,0 +1,305 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2018-2019 MediaTek Inc. ++/* A library for MediaTek SGMII circuit ++ * ++ * Author: Sean Wang ++ * Author: Alexander Couzens ++ * Author: Daniel Golle ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* SGMII subsystem config registers */ ++/* BMCR (low 16) BMSR (high 16) */ ++#define SGMSYS_PCS_CONTROL_1 0x0 ++#define SGMII_BMCR GENMASK(15, 0) ++#define SGMII_BMSR GENMASK(31, 16) ++ ++#define SGMSYS_PCS_DEVICE_ID 0x4 ++#define SGMII_LYNXI_DEV_ID 0x4d544950 ++ ++#define SGMSYS_PCS_ADVERTISE 0x8 ++#define SGMII_ADVERTISE GENMASK(15, 0) ++#define SGMII_LPA GENMASK(31, 16) ++ ++#define SGMSYS_PCS_SCRATCH 0x14 ++#define SGMII_DEV_VERSION GENMASK(31, 16) ++ ++/* Register to programmable link timer, the unit in 2 * 8ns */ ++#define SGMSYS_PCS_LINK_TIMER 0x18 ++#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) ++#define SGMII_LINK_TIMER_VAL(ns) FIELD_PREP(SGMII_LINK_TIMER_MASK, \ ++ ((ns) / 2 / 8)) ++ ++/* Register to control remote fault */ ++#define SGMSYS_SGMII_MODE 0x20 ++#define SGMII_IF_MODE_SGMII BIT(0) ++#define SGMII_SPEED_DUPLEX_AN BIT(1) ++#define SGMII_SPEED_MASK GENMASK(3, 2) ++#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) ++#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) ++#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) ++#define SGMII_DUPLEX_HALF BIT(4) ++#define SGMII_REMOTE_FAULT_DIS BIT(8) ++ ++/* Register to reset SGMII design */ ++#define SGMSYS_RESERVED_0 0x34 ++#define SGMII_SW_RESET BIT(0) ++ ++/* Register to set SGMII speed, ANA RG_ Control Signals III */ ++#define SGMII_PHY_SPEED_MASK GENMASK(3, 2) ++#define SGMII_PHY_SPEED_1_25G FIELD_PREP(SGMII_PHY_SPEED_MASK, 0) ++#define SGMII_PHY_SPEED_3_125G FIELD_PREP(SGMII_PHY_SPEED_MASK, 1) ++ ++/* Register to power up QPHY */ ++#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 ++#define SGMII_PHYA_PWD BIT(4) ++ ++/* Register to QPHY wrapper control */ ++#define SGMSYS_QPHY_WRAP_CTRL 0xec ++#define SGMII_PN_SWAP_MASK GENMASK(1, 0) ++#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) ++ ++/* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated ++ * data ++ * @regmap: The register map pointing at the range used to setup ++ * SGMII modes ++ * @dev: Pointer to device owning the PCS ++ * @ana_rgc3: The offset of register ANA_RGC3 relative to regmap ++ * @interface: Currently configured interface mode ++ * @pcs: Phylink PCS structure ++ * @flags: Flags indicating hardware properties ++ */ ++struct mtk_pcs_lynxi { ++ struct regmap *regmap; ++ u32 ana_rgc3; ++ phy_interface_t interface; ++ struct phylink_pcs pcs; ++ u32 flags; ++}; ++ ++static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs) ++{ ++ return container_of(pcs, struct mtk_pcs_lynxi, pcs); ++} ++ ++static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs, ++ struct phylink_link_state *state) ++{ ++ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); ++ unsigned int bm, adv; ++ ++ /* Read the BMSR and LPA */ ++ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); ++ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); ++ ++ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), ++ FIELD_GET(SGMII_LPA, adv)); ++} ++ ++static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode, ++ phy_interface_t interface, ++ const unsigned long *advertising, ++ bool permit_pause_to_mac) ++{ ++ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); ++ bool mode_changed = false, changed, use_an; ++ unsigned int rgc3, sgm_mode, bmcr; ++ int advertise, link_timer; ++ ++ advertise = phylink_mii_c22_pcs_encode_advertisement(interface, ++ advertising); ++ if (advertise < 0) ++ return advertise; ++ ++ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and ++ * we assume that fixes it's speed at bitrate = line rate (in ++ * other words, 1000Mbps or 2500Mbps). ++ */ ++ if (interface == PHY_INTERFACE_MODE_SGMII) { ++ sgm_mode = SGMII_IF_MODE_SGMII; ++ if (phylink_autoneg_inband(mode)) { ++ sgm_mode |= SGMII_REMOTE_FAULT_DIS | ++ SGMII_SPEED_DUPLEX_AN; ++ use_an = true; ++ } else { ++ use_an = false; ++ } ++ } else if (phylink_autoneg_inband(mode)) { ++ /* 1000base-X or 2500base-X autoneg */ ++ sgm_mode = SGMII_REMOTE_FAULT_DIS; ++ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, ++ advertising); ++ } else { ++ /* 1000base-X or 2500base-X without autoneg */ ++ sgm_mode = 0; ++ use_an = false; ++ } ++ ++ if (use_an) ++ bmcr = BMCR_ANENABLE; ++ else ++ bmcr = 0; ++ ++ if (mpcs->interface != interface) { ++ link_timer = phylink_get_link_timer_ns(interface); ++ if (link_timer < 0) ++ return link_timer; ++ ++ /* PHYA power down */ ++ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, ++ SGMII_PHYA_PWD); ++ ++ /* Reset SGMII PCS state */ ++ regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0, ++ SGMII_SW_RESET); ++ ++ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) ++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, ++ SGMII_PN_SWAP_MASK, ++ SGMII_PN_SWAP_TX_RX); ++ ++ if (interface == PHY_INTERFACE_MODE_2500BASEX) ++ rgc3 = SGMII_PHY_SPEED_3_125G; ++ else ++ rgc3 = SGMII_PHY_SPEED_1_25G; ++ ++ /* Configure the underlying interface speed */ ++ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, ++ SGMII_PHY_SPEED_MASK, rgc3); ++ ++ /* Setup the link timer */ ++ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, ++ SGMII_LINK_TIMER_VAL(link_timer)); ++ ++ mpcs->interface = interface; ++ mode_changed = true; ++ } ++ ++ /* Update the advertisement, noting whether it has changed */ ++ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, ++ SGMII_ADVERTISE, advertise, &changed); ++ ++ /* Update the sgmsys mode register */ ++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, ++ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | ++ SGMII_IF_MODE_SGMII, sgm_mode); ++ ++ /* Update the BMCR */ ++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, ++ BMCR_ANENABLE, bmcr); ++ ++ /* Release PHYA power down state ++ * Only removing bit SGMII_PHYA_PWD isn't enough. ++ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which ++ * prevents SGMII from working. The SGMII still shows link but no traffic ++ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was ++ * taken from a good working state of the SGMII interface. ++ * Unknown how much the QPHY needs but it is racy without a sleep. ++ * Tested on mt7622 & mt7986. ++ */ ++ usleep_range(50, 100); ++ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); ++ ++ return changed || mode_changed; ++} ++ ++static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs) ++{ ++ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); ++ ++ regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART); ++} ++ ++static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode, ++ phy_interface_t interface, int speed, ++ int duplex) ++{ ++ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); ++ unsigned int sgm_mode; ++ ++ if (!phylink_autoneg_inband(mode)) { ++ /* Force the speed and duplex setting */ ++ if (speed == SPEED_10) ++ sgm_mode = SGMII_SPEED_10; ++ else if (speed == SPEED_100) ++ sgm_mode = SGMII_SPEED_100; ++ else ++ sgm_mode = SGMII_SPEED_1000; ++ ++ if (duplex != DUPLEX_FULL) ++ sgm_mode |= SGMII_DUPLEX_HALF; ++ ++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, ++ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, ++ sgm_mode); ++ } ++} ++ ++static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { ++ .pcs_get_state = mtk_pcs_lynxi_get_state, ++ .pcs_config = mtk_pcs_lynxi_config, ++ .pcs_an_restart = mtk_pcs_lynxi_restart_an, ++ .pcs_link_up = mtk_pcs_lynxi_link_up, ++}; ++ ++struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, ++ struct regmap *regmap, u32 ana_rgc3, ++ u32 flags) ++{ ++ struct mtk_pcs_lynxi *mpcs; ++ u32 id, ver; ++ int ret; ++ ++ ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id); ++ if (ret < 0) ++ return NULL; ++ ++ if (id != SGMII_LYNXI_DEV_ID) { ++ dev_err(dev, "unknown PCS device id %08x\n", id); ++ return NULL; ++ } ++ ++ ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver); ++ if (ret < 0) ++ return NULL; ++ ++ ver = FIELD_GET(SGMII_DEV_VERSION, ver); ++ if (ver != 0x1) { ++ dev_err(dev, "unknown PCS device version %04x\n", ver); ++ return NULL; ++ } ++ ++ dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id, ++ ver); ++ ++ mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); ++ if (!mpcs) ++ return NULL; ++ ++ mpcs->ana_rgc3 = ana_rgc3; ++ mpcs->regmap = regmap; ++ mpcs->flags = flags; ++ mpcs->pcs.ops = &mtk_pcs_lynxi_ops; ++ mpcs->pcs.poll = true; ++ mpcs->interface = PHY_INTERFACE_MODE_NA; ++ ++ return &mpcs->pcs; ++} ++EXPORT_SYMBOL(mtk_pcs_lynxi_create); ++ ++void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs) ++{ ++ if (!pcs) ++ return; ++ ++ kfree(pcs_to_mtk_pcs_lynxi(pcs)); ++} ++EXPORT_SYMBOL(mtk_pcs_lynxi_destroy); ++ ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/include/linux/pcs/pcs-mtk-lynxi.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __LINUX_PCS_MTK_LYNXI_H ++#define __LINUX_PCS_MTK_LYNXI_H ++ ++#include ++#include ++ ++#define MTK_SGMII_FLAG_PN_SWAP BIT(0) ++struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, ++ struct regmap *regmap, ++ u32 ana_rgc3, u32 flags); ++void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs); ++#endif diff --git a/target/linux/generic/pending-6.1/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch b/target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch similarity index 100% rename from target/linux/generic/pending-6.1/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch rename to target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch diff --git a/target/linux/generic/pending-6.1/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch b/target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch similarity index 100% rename from target/linux/generic/pending-6.1/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch rename to target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch 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/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch similarity index 100% rename from target/linux/generic/pending-6.1/733-03-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch rename to target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch 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/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch similarity index 100% rename from target/linux/generic/pending-6.1/733-04-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch rename to target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch diff --git a/target/linux/generic/pending-6.1/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch b/target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch similarity index 100% rename from target/linux/generic/pending-6.1/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch rename to target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch diff --git a/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch b/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch new file mode 100644 index 000000000..83e015cc6 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch @@ -0,0 +1,36 @@ +From: Lorenzo Bianconi +Date: Thu, 17 Nov 2022 00:58:46 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: remove cpu_relax in + mtk_pending_work + +Get rid of cpu_relax in mtk_pending_work routine since MTK_RESETTING is +set only in mtk_pending_work() and it runs holding rtnl lock + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3495,11 +3495,8 @@ static void mtk_pending_work(struct work + rtnl_lock(); + + dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); ++ set_bit(MTK_RESETTING, ð->state); + +- while (test_and_set_bit_lock(MTK_RESETTING, ð->state)) +- cpu_relax(); +- +- dev_dbg(eth->dev, "[%s][%d] mtk_stop starts\n", __func__, __LINE__); + /* stop all devices to make sure that dma is properly shut down */ + for (i = 0; i < MTK_MAC_COUNT; i++) { + if (!eth->netdev[i]) +@@ -3533,7 +3530,7 @@ static void mtk_pending_work(struct work + + dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); + +- clear_bit_unlock(MTK_RESETTING, ð->state); ++ clear_bit(MTK_RESETTING, ð->state); + + rtnl_unlock(); + } diff --git a/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch b/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch new file mode 100644 index 000000000..117ccc090 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch @@ -0,0 +1,80 @@ +From: Sujuan Chen +Date: Thu, 24 Nov 2022 11:18:14 +0800 +Subject: [PATCH] net: ethernet: mtk_wed: add wcid overwritten support for wed + v1 + +All wed versions should enable the wcid overwritten feature, +since the wcid size is controlled by the wlan driver. + +Tested-by: Sujuan Chen +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Signed-off-by: Sujuan Chen +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -526,9 +526,9 @@ mtk_wed_dma_disable(struct mtk_wed_devic + 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); + } ++ ++ mtk_wed_set_512_support(dev, false); + } + + static void +@@ -1290,9 +1290,10 @@ mtk_wed_start(struct mtk_wed_device *dev + if (mtk_wed_rro_cfg(dev)) + return; + +- mtk_wed_set_512_support(dev, dev->wlan.wcid_512); + } + ++ mtk_wed_set_512_support(dev, dev->wlan.wcid_512); ++ + mtk_wed_dma_enable(dev); + dev->running = true; + } +@@ -1358,11 +1359,13 @@ mtk_wed_attach(struct mtk_wed_device *de + } + + mtk_wed_hw_init_early(dev); +- if (hw->version == 1) ++ if (hw->version == 1) { + regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, + BIT(hw->index), 0); +- else ++ } else { ++ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID); + ret = mtk_wed_wo_init(hw); ++ } + out: + if (ret) + mtk_wed_detach(dev); +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -20,6 +20,8 @@ struct mtk_wdma_desc { + __le32 info; + } __packed __aligned(4); + ++#define MTK_WED_REV_ID 0x004 ++ + #define MTK_WED_RESET 0x008 + #define MTK_WED_RESET_TX_BM BIT(0) + #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -85,6 +85,9 @@ struct mtk_wed_device { + int irq; + u8 version; + ++ /* used by wlan driver */ ++ u32 rev_id; ++ + 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; diff --git a/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch b/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch new file mode 100644 index 000000000..ec58c3fc5 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch @@ -0,0 +1,85 @@ +From: Lorenzo Bianconi +Date: Thu, 24 Nov 2022 16:22:51 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: return status value in + mtk_wdma_rx_reset + +Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine. +Increase poll timeout to 10ms in order to be aligned with vendor sdk. +This is a preliminary patch to add Wireless Ethernet Dispatcher reset +support. + +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_devic + return wdma_r32(dev, MTK_WDMA_GLO_CFG); + } + +-static void ++static int + mtk_wdma_rx_reset(struct mtk_wed_device *dev) + { + u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY; +- int i; ++ int i, ret; + + 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)) ++ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status, ++ !(status & mask), 0, 10000); ++ if (ret) + dev_err(dev->hw->dev, "rx reset failed\n"); + ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); ++ + for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) { + if (dev->rx_wdma[i].desc) + continue; +@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device + wdma_w32(dev, + MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); + } ++ ++ return ret; + } + + static void +@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *de + + mtk_wed_stop(dev); + +- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); +- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); +- ++ mtk_wdma_rx_reset(dev); + 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); +@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *de + 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) { +@@ -999,11 +1002,7 @@ mtk_wed_reset_dma(struct mtk_wed_device + wed_w32(dev, MTK_WED_RESET_IDX, 0); + } + +- 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); ++ mtk_wdma_rx_reset(dev); + + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); diff --git a/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch b/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch new file mode 100644 index 000000000..10c1732c9 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch @@ -0,0 +1,52 @@ +From: Lorenzo Bianconi +Date: Thu, 24 Nov 2022 16:22:52 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX + configuration in mtk_wdma_tx_reset + +Remove duplicated code. Increase poll timeout to 10ms in order to be +aligned with vendor sdk. +This is a preliminary patch to add Wireless Ethernet Dispatcher reset +support. + +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device + + 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)) ++ !(status & mask), 0, 10000)) + 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_RESET_IDX, MTK_WDMA_RESET_IDX_TX); ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); + ++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) + wdma_w32(dev, + MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); +- } + } + + static void +@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *de + + mtk_wdma_rx_reset(dev); + 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_tx_buffer(dev); + mtk_wed_free_tx_rings(dev); + diff --git a/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch b/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch new file mode 100644 index 000000000..f4e842d51 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch @@ -0,0 +1,98 @@ +From: Lorenzo Bianconi +Date: Thu, 24 Nov 2022 16:22:53 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: update mtk_wed_stop + +Update mtk_wed_stop routine and rename old mtk_wed_stop() to +mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet +Dispatcher reset support. + +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_devic + static void + mtk_wed_stop(struct mtk_wed_device *dev) + { +- mtk_wed_dma_disable(dev); + mtk_wed_set_ext_int(dev, false); + +- wed_clr(dev, MTK_WED_CTRL, +- MTK_WED_CTRL_WDMA_INT_AGENT_EN | +- MTK_WED_CTRL_WPDMA_INT_AGENT_EN | +- MTK_WED_CTRL_WED_TX_BM_EN | +- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); + wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0); + wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0); + wdma_w32(dev, MTK_WDMA_INT_MASK, 0); +@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev) + + 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 ++mtk_wed_deinit(struct mtk_wed_device *dev) ++{ ++ mtk_wed_stop(dev); ++ mtk_wed_dma_disable(dev); ++ ++ wed_clr(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_WDMA_INT_AGENT_EN | ++ MTK_WED_CTRL_WPDMA_INT_AGENT_EN | ++ MTK_WED_CTRL_WED_TX_BM_EN | ++ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); ++ ++ if (dev->hw->version == 1) ++ return; ++ ++ wed_clr(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_RX_ROUTE_QM_EN | ++ MTK_WED_CTRL_WED_RX_BM_EN | ++ MTK_WED_CTRL_RX_RRO_QM_EN); + } + + static void +@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *de + + mutex_lock(&hw_lock); + +- mtk_wed_stop(dev); ++ mtk_wed_deinit(dev); + + mtk_wdma_rx_reset(dev); + mtk_wed_reset(dev, MTK_WED_RESET_WED); +@@ -670,7 +684,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev + { + u32 mask, set; + +- mtk_wed_stop(dev); ++ mtk_wed_deinit(dev); + mtk_wed_reset(dev, MTK_WED_RESET_WED); + mtk_wed_set_wpdma(dev); + +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -234,6 +234,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic + (_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) ++#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) ++#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) + #else + static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) + { +@@ -250,6 +252,8 @@ static inline bool mtk_wed_device_active + #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 ++#define mtk_wed_device_stop(_dev) do {} while (0) ++#define mtk_wed_device_dma_reset(_dev) do {} while (0) + #endif + + #endif diff --git a/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch b/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch new file mode 100644 index 000000000..a0fc9da99 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch @@ -0,0 +1,309 @@ +From: Lorenzo Bianconi +Date: Thu, 24 Nov 2022 16:22:54 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_rx_reset routine + +Introduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless +Ethernet Dispatcher available on MT7986 SoC. + +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -944,42 +944,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring * + } + + static u32 +-mtk_wed_check_busy(struct mtk_wed_device *dev) ++mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) + { +- if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY) +- return true; +- +- if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) & +- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY) +- return true; +- +- if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY) +- return true; +- +- if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) & +- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) +- return true; +- +- if (wdma_r32(dev, MTK_WDMA_GLO_CFG) & +- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) +- return true; +- +- if (wed_r32(dev, MTK_WED_CTRL) & +- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY)) +- return true; +- +- return false; ++ return !!(wed_r32(dev, reg) & mask); + } + + static int +-mtk_wed_poll_busy(struct mtk_wed_device *dev) ++mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) + { + int sleep = 15000; + int timeout = 100 * sleep; + u32 val; + + return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, +- timeout, false, dev); ++ timeout, false, dev, reg, mask); ++} ++ ++static int ++mtk_wed_rx_reset(struct mtk_wed_device *dev) ++{ ++ struct mtk_wed_wo *wo = dev->hw->wed_wo; ++ u8 val = MTK_WED_WO_STATE_SER_RESET; ++ int i, ret; ++ ++ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, ++ MTK_WED_WO_CMD_CHANGE_STATE, &val, ++ sizeof(val), true); ++ if (ret) ++ return ret; ++ ++ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN); ++ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, ++ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY); ++ if (ret) { ++ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); ++ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV); ++ } else { ++ 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_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, ++ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | ++ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE); ++ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, ++ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | ++ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE); ++ ++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); ++ } ++ ++ /* reset rro qm */ ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN); ++ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_RX_RRO_QM_BUSY); ++ if (ret) { ++ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM); ++ } else { ++ 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); ++ } ++ ++ /* reset route qm */ ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); ++ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_RX_ROUTE_QM_BUSY); ++ if (ret) ++ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); ++ else ++ wed_set(dev, MTK_WED_RTQM_GLO_CFG, ++ MTK_WED_RTQM_Q_RST); ++ ++ /* reset tx wdma */ ++ mtk_wdma_tx_reset(dev); ++ ++ /* reset tx wdma drv */ ++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN); ++ mtk_wed_poll_busy(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); ++ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV); ++ ++ /* reset wed rx dma */ ++ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, ++ MTK_WED_GLO_CFG_RX_DMA_BUSY); ++ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN); ++ if (ret) { ++ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA); ++ } else { ++ struct mtk_eth *eth = dev->hw->eth; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ wed_set(dev, MTK_WED_RESET_IDX, ++ MTK_WED_RESET_IDX_RX_V2); ++ else ++ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX); ++ wed_w32(dev, MTK_WED_RESET_IDX, 0); ++ } ++ ++ /* reset rx bm */ ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); ++ mtk_wed_poll_busy(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_WED_RX_BM_BUSY); ++ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM); ++ ++ /* wo change to enable state */ ++ val = MTK_WED_WO_STATE_ENABLE; ++ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, ++ MTK_WED_WO_CMD_CHANGE_STATE, &val, ++ sizeof(val), true); ++ if (ret) ++ return ret; ++ ++ /* wed_rx_ring_reset */ ++ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) { ++ if (!dev->rx_ring[i].desc) ++ continue; ++ ++ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE, ++ false); ++ } ++ mtk_wed_free_rx_buffer(dev); ++ ++ return 0; + } + + static void +@@ -997,19 +1085,23 @@ mtk_wed_reset_dma(struct mtk_wed_device + true); + } + +- if (mtk_wed_poll_busy(dev)) +- busy = mtk_wed_check_busy(dev); +- ++ /* 1. reset WED tx DMA */ ++ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN); ++ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, ++ MTK_WED_GLO_CFG_TX_DMA_BUSY); + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA); + } else { +- wed_w32(dev, MTK_WED_RESET_IDX, +- MTK_WED_RESET_IDX_TX | +- MTK_WED_RESET_IDX_RX); ++ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX); + wed_w32(dev, MTK_WED_RESET_IDX, 0); + } + +- mtk_wdma_rx_reset(dev); ++ /* 2. reset WDMA rx DMA */ ++ busy = !!mtk_wdma_rx_reset(dev); ++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); ++ if (!busy) ++ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG, ++ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY); + + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); +@@ -1026,6 +1118,9 @@ mtk_wed_reset_dma(struct mtk_wed_device + MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE); + } + ++ /* 3. reset WED WPDMA tx */ ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); ++ + for (i = 0; i < 100; i++) { + val = wed_r32(dev, MTK_WED_TX_BM_INTF); + if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) +@@ -1033,8 +1128,19 @@ mtk_wed_reset_dma(struct mtk_wed_device + } + + mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT); ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN); + mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); + ++ /* 4. reset WED WPDMA tx */ ++ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY); ++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); ++ if (!busy) ++ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY); ++ + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); + mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); +@@ -1045,6 +1151,17 @@ mtk_wed_reset_dma(struct mtk_wed_device + MTK_WED_WPDMA_RESET_IDX_RX); + wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0); + } ++ ++ dev->init_done = false; ++ if (dev->hw->version == 1) ++ return; ++ ++ if (!busy) { ++ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX); ++ wed_w32(dev, MTK_WED_RESET_IDX, 0); ++ } ++ ++ mtk_wed_rx_reset(dev); + } + + static int +@@ -1267,6 +1384,9 @@ mtk_wed_start(struct mtk_wed_device *dev + { + int i; + ++ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev)) ++ return; ++ + 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); +@@ -1355,10 +1475,6 @@ mtk_wed_attach(struct mtk_wed_device *de + 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; +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -24,11 +24,15 @@ struct mtk_wdma_desc { + + #define MTK_WED_RESET 0x008 + #define MTK_WED_RESET_TX_BM BIT(0) ++#define MTK_WED_RESET_RX_BM BIT(1) + #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) + #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8) + #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) ++#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10) + #define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11) + #define MTK_WED_RESET_WED_TX_DMA BIT(12) ++#define MTK_WED_RESET_WED_RX_DMA BIT(13) ++#define MTK_WED_RESET_WDMA_TX_DRV BIT(16) + #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) +@@ -158,6 +162,8 @@ struct mtk_wdma_desc { + #define MTK_WED_RESET_IDX 0x20c + #define MTK_WED_RESET_IDX_TX GENMASK(3, 0) + #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) ++#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6) ++#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30) + + #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) + #define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4) +@@ -267,6 +273,9 @@ struct mtk_wdma_desc { + + #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_RX_DRV_BUSY BIT(1) ++#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3) ++#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4) + #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) + diff --git a/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch b/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch new file mode 100644 index 000000000..4404971cc --- /dev/null +++ b/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch @@ -0,0 +1,103 @@ +From: Lorenzo Bianconi +Date: Thu, 24 Nov 2022 16:22:55 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add reset to tx_ring_setup callback + +Introduce reset parameter to mtk_wed_tx_ring_setup signature. +This is a preliminary patch to add Wireless Ethernet Dispatcher reset +support. + +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -1181,7 +1181,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device + } + + static int +-mtk_wed_wdma_rx_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, ++ bool reset) + { + u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; + struct mtk_wed_ring *wdma; +@@ -1190,8 +1191,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we + return -EINVAL; + + wdma = &dev->rx_wdma[idx]; +- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, +- true)) ++ if (!reset && 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, +@@ -1389,7 +1390,7 @@ mtk_wed_start(struct mtk_wed_device *dev + + 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_wdma_rx_ring_setup(dev, i, 16, false); + + mtk_wed_hw_init(dev); + mtk_wed_configure_irq(dev, irq_mask); +@@ -1498,7 +1499,8 @@ unlock: + } + + static int +-mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) ++mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs, ++ bool reset) + { + struct mtk_wed_ring *ring = &dev->tx_ring[idx]; + +@@ -1517,11 +1519,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev + 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), true)) ++ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, ++ sizeof(*ring->desc), true)) + return -ENOMEM; + +- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) ++ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, ++ reset)) + 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 +@@ -158,7 +158,7 @@ struct mtk_wed_device { + 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); ++ void __iomem *regs, bool reset); + int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, + void __iomem *regs); + int (*txfree_ring_setup)(struct mtk_wed_device *dev, +@@ -216,8 +216,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic + #define mtk_wed_device_active(_dev) !!(_dev)->ops + #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) + #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask) +-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \ +- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs) ++#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \ ++ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset) + #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \ + (_dev)->ops->txfree_ring_setup(_dev, _regs) + #define mtk_wed_device_reg_read(_dev, _reg) \ +@@ -243,7 +243,7 @@ static inline bool mtk_wed_device_active + } + #define mtk_wed_device_detach(_dev) do {} while (0) + #define mtk_wed_device_start(_dev, _mask) do {} while (0) +-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV ++#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV + #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV + #define mtk_wed_device_reg_read(_dev, _reg) 0 + #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) diff --git a/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch b/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch new file mode 100644 index 000000000..f9b11326b --- /dev/null +++ b/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch @@ -0,0 +1,103 @@ +From: Lorenzo Bianconi +Date: Thu, 1 Dec 2022 16:26:53 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: fix sleep while atomic in + mtk_wed_wo_queue_refill + +In order to fix the following sleep while atomic bug always alloc pages +with GFP_ATOMIC in mtk_wed_wo_queue_refill since page_frag_alloc runs in +spin_lock critical section. + +[ 9.049719] Hardware name: MediaTek MT7986a RFB (DT) +[ 9.054665] Call trace: +[ 9.057096] dump_backtrace+0x0/0x154 +[ 9.060751] show_stack+0x14/0x1c +[ 9.064052] dump_stack_lvl+0x64/0x7c +[ 9.067702] dump_stack+0x14/0x2c +[ 9.071001] ___might_sleep+0xec/0x120 +[ 9.074736] __might_sleep+0x4c/0x9c +[ 9.078296] __alloc_pages+0x184/0x2e4 +[ 9.082030] page_frag_alloc_align+0x98/0x1ac +[ 9.086369] mtk_wed_wo_queue_refill+0x134/0x234 +[ 9.090974] mtk_wed_wo_init+0x174/0x2c0 +[ 9.094881] mtk_wed_attach+0x7c8/0x7e0 +[ 9.098701] mt7915_mmio_wed_init+0x1f0/0x3a0 [mt7915e] +[ 9.103940] mt7915_pci_probe+0xec/0x3bc [mt7915e] +[ 9.108727] pci_device_probe+0xac/0x13c +[ 9.112638] really_probe.part.0+0x98/0x2f4 +[ 9.116807] __driver_probe_device+0x94/0x13c +[ 9.121147] driver_probe_device+0x40/0x114 +[ 9.125314] __driver_attach+0x7c/0x180 +[ 9.129133] bus_for_each_dev+0x5c/0x90 +[ 9.132953] driver_attach+0x20/0x2c +[ 9.136513] bus_add_driver+0x104/0x1fc +[ 9.140333] driver_register+0x74/0x120 +[ 9.144153] __pci_register_driver+0x40/0x50 +[ 9.148407] mt7915_init+0x5c/0x1000 [mt7915e] +[ 9.152848] do_one_initcall+0x40/0x25c +[ 9.156669] do_init_module+0x44/0x230 +[ 9.160403] load_module+0x1f30/0x2750 +[ 9.164135] __do_sys_init_module+0x150/0x200 +[ 9.168475] __arm64_sys_init_module+0x18/0x20 +[ 9.172901] invoke_syscall.constprop.0+0x4c/0xe0 +[ 9.177589] do_el0_svc+0x48/0xe0 +[ 9.180889] el0_svc+0x14/0x50 +[ 9.183929] el0t_64_sync_handler+0x9c/0x120 +[ 9.188183] el0t_64_sync+0x158/0x15c + +Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Pavan Chebbi +Link: https://lore.kernel.org/r/67ca94bdd3d9eaeb86e52b3050fbca0bcf7bb02f.1669908312.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c +@@ -133,17 +133,18 @@ mtk_wed_wo_dequeue(struct mtk_wed_wo *wo + + static int + mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, +- gfp_t gfp, bool rx) ++ 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; ++ void *buf; + ++ buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC); + if (!buf) + break; + +@@ -215,7 +216,7 @@ mtk_wed_wo_rx_run_queue(struct mtk_wed_w + mtk_wed_mcu_rx_unsolicited_event(wo, skb); + } + +- if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) { ++ if (mtk_wed_wo_queue_refill(wo, q, true)) { + u32 index = (q->head - 1) % q->n_desc; + + mtk_wed_wo_queue_kick(wo, q, index); +@@ -432,7 +433,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_ + if (ret) + goto error; + +- mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false); ++ mtk_wed_wo_queue_refill(wo, &wo->q_tx, false); + mtk_wed_wo_queue_reset(wo, &wo->q_tx); + + regs.desc_base = MTK_WED_WO_CCIF_DUMMY5; +@@ -446,7 +447,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_ + if (ret) + goto error; + +- mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true); ++ mtk_wed_wo_queue_refill(wo, &wo->q_rx, true); + mtk_wed_wo_queue_reset(wo, &wo->q_rx); + + /* rx queue irqmask */ diff --git a/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch b/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch new file mode 100644 index 000000000..fa6f56dbe --- /dev/null +++ b/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch @@ -0,0 +1,52 @@ +From: Lorenzo Bianconi +Date: Tue, 10 Jan 2023 10:31:26 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for rx queue + +Queue spinlock is currently held in mtk_wed_wo_queue_rx_clean and +mtk_wed_wo_queue_refill routines for MTK Wireless Ethernet Dispatcher +MCU rx queue. mtk_wed_wo_queue_refill() is running during initialization +and in rx tasklet while mtk_wed_wo_queue_rx_clean() is running in +mtk_wed_wo_hw_deinit() during hw de-init phase after rx tasklet has been +disabled. Since mtk_wed_wo_queue_rx_clean and mtk_wed_wo_queue_refill +routines can't run concurrently get rid of spinlock for mcu rx queue. + +Reviewed-by: Alexander Duyck +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/36ec3b729542ea60898471d890796f745479ba32.1673342990.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c +@@ -138,7 +138,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w + 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) { + struct mtk_wed_wo_queue_entry *entry; + dma_addr_t addr; +@@ -172,7 +171,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w + q->queued++; + n_buf++; + } +- spin_unlock_bh(&q->lock); + + return n_buf; + } +@@ -316,7 +314,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed + { + struct page *page; + +- spin_lock_bh(&q->lock); + for (;;) { + void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true); + +@@ -325,7 +322,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed + + skb_free_frag(buf); + } +- spin_unlock_bh(&q->lock); + + if (!q->cache.va) + return; diff --git a/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch b/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch new file mode 100644 index 000000000..9b1e4c325 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch @@ -0,0 +1,75 @@ +From: Lorenzo Bianconi +Date: Thu, 12 Jan 2023 10:21:29 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for tx queue + +Similar to MTK Wireless Ethernet Dispatcher (WED) MCU rx queue, +we do not need to protect WED MCU tx queue with a spin lock since +the tx queue is accessed in the two following routines: +- mtk_wed_wo_queue_tx_skb(): + it is run at initialization and during mt7915 normal operation. + Moreover MCU messages are serialized through MCU mutex. +- mtk_wed_wo_queue_tx_clean(): + it runs just at mt7915 driver module unload when no more messages + are sent to the MCU. + +Remove tx queue spinlock. + +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/7bd0337b2a13ab1a63673b7c03fd35206b3b284e.1673515140.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c +@@ -258,7 +258,6 @@ mtk_wed_wo_queue_alloc(struct mtk_wed_wo + 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; +@@ -290,7 +289,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed + 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]; + +@@ -299,7 +297,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed + skb_free_frag(entry->buf); + entry->buf = NULL; + } +- spin_unlock_bh(&q->lock); + + if (!q->cache.va) + return; +@@ -347,8 +344,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w + 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) { +@@ -379,8 +374,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w + 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; +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h +@@ -211,7 +211,6 @@ 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; diff --git a/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch b/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch new file mode 100644 index 000000000..ce64f84ff --- /dev/null +++ b/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch @@ -0,0 +1,70 @@ +From: Lorenzo Bianconi +Date: Sat, 14 Jan 2023 18:01:28 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility + routine + +This is a preliminary patch to add Wireless Ethernet Dispatcher reset +support. + +Reviewed-by: Leon Romanovsky +Tested-by: Daniel Golle +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3254,6 +3254,27 @@ static void mtk_set_mcr_max_rx(struct mt + mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); + } + ++static void mtk_hw_reset(struct mtk_eth *eth) ++{ ++ u32 val; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); ++ val = RSTCTRL_PPE0_V2; ++ } else { ++ val = RSTCTRL_PPE0; ++ } ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= RSTCTRL_PPE1; ++ ++ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, ++ 0x3ffffff); ++} ++ + static int mtk_hw_init(struct mtk_eth *eth) + { + u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | +@@ -3293,22 +3314,9 @@ static int mtk_hw_init(struct mtk_eth *e + return 0; + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { +- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); +- val = RSTCTRL_PPE0_V2; +- } else { +- val = RSTCTRL_PPE0; +- } +- +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val |= RSTCTRL_PPE1; +- +- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); ++ mtk_hw_reset(eth); + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { +- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, +- 0x3ffffff); +- + /* Set FE to PDMAv2 if necessary */ + val = mtk_r32(eth, MTK_FE_GLO_MISC); + mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); diff --git a/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch b/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch new file mode 100644 index 000000000..09ee03706 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch @@ -0,0 +1,107 @@ +From: Lorenzo Bianconi +Date: Sat, 14 Jan 2023 18:01:29 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset + support + +Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch +to align reset procedure to vendor sdk and avoid to power down the chip +during hw reset. + +Reviewed-by: Leon Romanovsky +Tested-by: Daniel Golle +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3275,7 +3275,54 @@ static void mtk_hw_reset(struct mtk_eth + 0x3ffffff); + } + +-static int mtk_hw_init(struct mtk_eth *eth) ++static u32 mtk_hw_reset_read(struct mtk_eth *eth) ++{ ++ u32 val; ++ ++ regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val); ++ return val; ++} ++ ++static void mtk_hw_warm_reset(struct mtk_eth *eth) ++{ ++ u32 rst_mask, val; ++ ++ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE, ++ RSTCTRL_FE); ++ if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val, ++ val & RSTCTRL_FE, 1, 1000)) { ++ dev_err(eth->dev, "warm reset failed\n"); ++ mtk_hw_reset(eth); ++ return; ++ } ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; ++ else ++ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ rst_mask |= RSTCTRL_PPE1; ++ ++ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); ++ ++ udelay(1); ++ val = mtk_hw_reset_read(eth); ++ if (!(val & rst_mask)) ++ dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n", ++ val, rst_mask); ++ ++ rst_mask |= RSTCTRL_FE; ++ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask); ++ ++ udelay(1); ++ val = mtk_hw_reset_read(eth); ++ if (val & rst_mask) ++ dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n", ++ val, rst_mask); ++} ++ ++static int mtk_hw_init(struct mtk_eth *eth, bool reset) + { + u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | + ETHSYS_DMA_AG_MAP_PPE; +@@ -3314,7 +3361,12 @@ static int mtk_hw_init(struct mtk_eth *e + return 0; + } + +- mtk_hw_reset(eth); ++ msleep(100); ++ ++ if (reset) ++ mtk_hw_warm_reset(eth); ++ else ++ mtk_hw_reset(eth); + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { + /* Set FE to PDMAv2 if necessary */ +@@ -3522,7 +3574,7 @@ static void mtk_pending_work(struct work + if (eth->dev->pins) + pinctrl_select_state(eth->dev->pins->p, + eth->dev->pins->default_state); +- mtk_hw_init(eth); ++ mtk_hw_init(eth, true); + + /* restart DMA and enable IRQs */ + for (i = 0; i < MTK_MAC_COUNT; i++) { +@@ -4114,7 +4166,7 @@ static int mtk_probe(struct platform_dev + eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); + INIT_WORK(ð->pending_work, mtk_pending_work); + +- err = mtk_hw_init(eth); ++ err = mtk_hw_init(eth, false); + if (err) + goto err_wed_exit; + diff --git a/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch b/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch new file mode 100644 index 000000000..963235cd9 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch @@ -0,0 +1,262 @@ +From: Lorenzo Bianconi +Date: Sat, 14 Jan 2023 18:01:30 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: align reset procedure to vendor + sdk + +Avoid to power-down the ethernet chip during hw reset and align reset +procedure to vendor sdk. + +Reviewed-by: Leon Romanovsky +Tested-by: Daniel Golle +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2842,14 +2842,29 @@ static void mtk_dma_free(struct mtk_eth + kfree(eth->scratch_head); + } + ++static bool mtk_hw_reset_check(struct mtk_eth *eth) ++{ ++ u32 val = mtk_r32(eth, MTK_INT_STATUS2); ++ ++ return (val & MTK_FE_INT_FQ_EMPTY) || (val & MTK_FE_INT_RFIFO_UF) || ++ (val & MTK_FE_INT_RFIFO_OV) || (val & MTK_FE_INT_TSO_FAIL) || ++ (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL); ++} ++ + static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue) + { + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + ++ if (test_bit(MTK_RESETTING, ð->state)) ++ return; ++ ++ if (!mtk_hw_reset_check(eth)) ++ return; ++ + eth->netdev[mac->id]->stats.tx_errors++; +- netif_err(eth, tx_err, dev, +- "transmit timed out\n"); ++ netif_err(eth, tx_err, dev, "transmit timed out\n"); ++ + schedule_work(ð->pending_work); + } + +@@ -3329,15 +3344,17 @@ static int mtk_hw_init(struct mtk_eth *e + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + int i, val, ret; + +- if (test_and_set_bit(MTK_HW_INIT, ð->state)) ++ if (!reset && test_and_set_bit(MTK_HW_INIT, ð->state)) + return 0; + +- pm_runtime_enable(eth->dev); +- pm_runtime_get_sync(eth->dev); ++ if (!reset) { ++ pm_runtime_enable(eth->dev); ++ pm_runtime_get_sync(eth->dev); + +- ret = mtk_clk_enable(eth); +- if (ret) +- goto err_disable_pm; ++ ret = mtk_clk_enable(eth); ++ if (ret) ++ goto err_disable_pm; ++ } + + if (eth->ethsys) + regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask, +@@ -3466,8 +3483,10 @@ static int mtk_hw_init(struct mtk_eth *e + return 0; + + err_disable_pm: +- pm_runtime_put_sync(eth->dev); +- pm_runtime_disable(eth->dev); ++ if (!reset) { ++ pm_runtime_put_sync(eth->dev); ++ pm_runtime_disable(eth->dev); ++ } + + return ret; + } +@@ -3546,30 +3565,53 @@ static int mtk_do_ioctl(struct net_devic + return -EOPNOTSUPP; + } + ++static void mtk_prepare_for_reset(struct mtk_eth *eth) ++{ ++ u32 val; ++ int i; ++ ++ /* disabe FE P3 and P4 */ ++ val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= MTK_FE_LINK_DOWN_P4; ++ mtk_w32(eth, val, MTK_FE_GLO_CFG); ++ ++ /* adjust PPE configurations to prepare for reset */ ++ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) ++ mtk_ppe_prepare_reset(eth->ppe[i]); ++ ++ /* disable NETSYS interrupts */ ++ mtk_w32(eth, 0, MTK_FE_INT_ENABLE); ++ ++ /* force link down GMAC */ ++ for (i = 0; i < 2; i++) { ++ val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK; ++ mtk_w32(eth, val, MTK_MAC_MCR(i)); ++ } ++} ++ + static void mtk_pending_work(struct work_struct *work) + { + struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work); +- int err, i; + unsigned long restart = 0; ++ u32 val; ++ int i; + + rtnl_lock(); +- +- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); + set_bit(MTK_RESETTING, ð->state); + ++ mtk_prepare_for_reset(eth); ++ + /* stop all devices to make sure that dma is properly shut down */ + for (i = 0; i < MTK_MAC_COUNT; i++) { +- if (!eth->netdev[i]) ++ if (!eth->netdev[i] || !netif_running(eth->netdev[i])) + continue; ++ + mtk_stop(eth->netdev[i]); + __set_bit(i, &restart); + } +- dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__); + +- /* restart underlying hardware such as power, clock, pin mux +- * and the connected phy +- */ +- mtk_hw_deinit(eth); ++ usleep_range(15000, 16000); + + if (eth->dev->pins) + pinctrl_select_state(eth->dev->pins->p, +@@ -3580,15 +3622,19 @@ static void mtk_pending_work(struct work + for (i = 0; i < MTK_MAC_COUNT; i++) { + if (!test_bit(i, &restart)) + continue; +- err = mtk_open(eth->netdev[i]); +- if (err) { ++ ++ if (mtk_open(eth->netdev[i])) { + netif_alert(eth, ifup, eth->netdev[i], +- "Driver up/down cycle failed, closing device.\n"); ++ "Driver up/down cycle failed\n"); + dev_close(eth->netdev[i]); + } + } + +- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); ++ /* enabe FE P3 and P4 */ ++ val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val &= ~MTK_FE_LINK_DOWN_P4; ++ mtk_w32(eth, val, MTK_FE_GLO_CFG); + + clear_bit(MTK_RESETTING, ð->state); + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -72,12 +72,24 @@ + #define MTK_HW_LRO_REPLACE_DELTA 1000 + #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 + ++/* Frame Engine Global Configuration */ ++#define MTK_FE_GLO_CFG 0x00 ++#define MTK_FE_LINK_DOWN_P3 BIT(11) ++#define MTK_FE_LINK_DOWN_P4 BIT(12) ++ + /* Frame Engine Global Reset Register */ + #define MTK_RST_GL 0x04 + #define RST_GL_PSE BIT(0) + + /* Frame Engine Interrupt Status Register */ + #define MTK_INT_STATUS2 0x08 ++#define MTK_FE_INT_ENABLE 0x0c ++#define MTK_FE_INT_FQ_EMPTY BIT(8) ++#define MTK_FE_INT_TSO_FAIL BIT(12) ++#define MTK_FE_INT_TSO_ILLEGAL BIT(13) ++#define MTK_FE_INT_TSO_ALIGN BIT(14) ++#define MTK_FE_INT_RFIFO_OV BIT(18) ++#define MTK_FE_INT_RFIFO_UF BIT(19) + #define MTK_GDM1_AF BIT(28) + #define MTK_GDM2_AF BIT(29) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -710,6 +710,33 @@ int mtk_foe_entry_idle_time(struct mtk_p + return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); + } + ++int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) ++{ ++ if (!ppe) ++ return -EINVAL; ++ ++ /* disable KA */ ++ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); ++ ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); ++ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0); ++ usleep_range(10000, 11000); ++ ++ /* set KA timer to maximum */ ++ ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); ++ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff); ++ ++ /* set KA tick select */ ++ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL); ++ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); ++ usleep_range(10000, 11000); ++ ++ /* disable scan mode */ ++ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE); ++ usleep_range(10000, 11000); ++ ++ return mtk_ppe_wait_busy(ppe); ++} ++ + struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, + int version, int index) + { +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -306,6 +306,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + void mtk_ppe_deinit(struct mtk_eth *eth); + void mtk_ppe_start(struct mtk_ppe *ppe); + int mtk_ppe_stop(struct mtk_ppe *ppe); ++int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); + + void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +@@ -58,6 +58,12 @@ + #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) + #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) + #define MTK_PPE_TB_CFG_INFO_SEL BIT(20) ++#define MTK_PPE_TB_TICK_SEL BIT(24) ++ ++#define MTK_PPE_BIND_LMT1 0x230 ++#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16) ++ ++#define MTK_PPE_KEEPALIVE 0x234 + + enum { + MTK_PPE_SCAN_MODE_DISABLED, diff --git a/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch b/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch new file mode 100644 index 000000000..5fa2500a4 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch @@ -0,0 +1,249 @@ +From: Lorenzo Bianconi +Date: Sat, 14 Jan 2023 18:01:31 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add dma checks to + mtk_hw_reset_check + +Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs. + +Reviewed-by: Leon Romanovsky +Tested-by: Daniel Golle +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -50,6 +50,7 @@ static const struct mtk_reg_map mtk_reg_ + .delay_irq = 0x0a0c, + .irq_status = 0x0a20, + .irq_mask = 0x0a28, ++ .adma_rx_dbg0 = 0x0a38, + .int_grp = 0x0a50, + }, + .qdma = { +@@ -79,6 +80,8 @@ static const struct mtk_reg_map mtk_reg_ + [0] = 0x2800, + [1] = 0x2c00, + }, ++ .pse_iq_sta = 0x0110, ++ .pse_oq_sta = 0x0118, + }; + + static const struct mtk_reg_map mt7628_reg_map = { +@@ -109,6 +112,7 @@ static const struct mtk_reg_map mt7986_r + .delay_irq = 0x620c, + .irq_status = 0x6220, + .irq_mask = 0x6228, ++ .adma_rx_dbg0 = 0x6238, + .int_grp = 0x6250, + }, + .qdma = { +@@ -138,6 +142,8 @@ static const struct mtk_reg_map mt7986_r + [0] = 0x4800, + [1] = 0x4c00, + }, ++ .pse_iq_sta = 0x0180, ++ .pse_oq_sta = 0x01a0, + }; + + /* strings used by ethtool */ +@@ -3337,6 +3343,102 @@ static void mtk_hw_warm_reset(struct mtk + val, rst_mask); + } + ++static bool mtk_hw_check_dma_hang(struct mtk_eth *eth) ++{ ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ bool gmac1_tx, gmac2_tx, gdm1_tx, gdm2_tx; ++ bool oq_hang, cdm1_busy, adma_busy; ++ bool wtx_busy, cdm_full, oq_free; ++ u32 wdidx, val, gdm1_fc, gdm2_fc; ++ bool qfsm_hang, qfwd_hang; ++ bool ret = false; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) ++ return false; ++ ++ /* WDMA sanity checks */ ++ wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc); ++ ++ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204); ++ wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val); ++ ++ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230); ++ cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val); ++ ++ oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) && ++ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) && ++ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16))); ++ ++ if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) { ++ if (++eth->reset.wdma_hang_count > 2) { ++ eth->reset.wdma_hang_count = 0; ++ ret = true; ++ } ++ goto out; ++ } ++ ++ /* QDMA sanity checks */ ++ qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234); ++ qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308); ++ ++ gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0; ++ gdm2_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM2_FSM)) > 0; ++ gmac1_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(0))) != 1; ++ gmac2_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(1))) != 1; ++ gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x24); ++ gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x64); ++ ++ if (qfsm_hang && qfwd_hang && ++ ((gdm1_tx && gmac1_tx && gdm1_fc < 1) || ++ (gdm2_tx && gmac2_tx && gdm2_fc < 1))) { ++ if (++eth->reset.qdma_hang_count > 2) { ++ eth->reset.qdma_hang_count = 0; ++ ret = true; ++ } ++ goto out; ++ } ++ ++ /* ADMA sanity checks */ ++ oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0)); ++ cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16)); ++ adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) && ++ !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6)); ++ ++ if (oq_hang && cdm1_busy && adma_busy) { ++ if (++eth->reset.adma_hang_count > 2) { ++ eth->reset.adma_hang_count = 0; ++ ret = true; ++ } ++ goto out; ++ } ++ ++ eth->reset.wdma_hang_count = 0; ++ eth->reset.qdma_hang_count = 0; ++ eth->reset.adma_hang_count = 0; ++out: ++ eth->reset.wdidx = wdidx; ++ ++ return ret; ++} ++ ++static void mtk_hw_reset_monitor_work(struct work_struct *work) ++{ ++ struct delayed_work *del_work = to_delayed_work(work); ++ struct mtk_eth *eth = container_of(del_work, struct mtk_eth, ++ reset.monitor_work); ++ ++ if (test_bit(MTK_RESETTING, ð->state)) ++ goto out; ++ ++ /* DMA stuck checks */ ++ if (mtk_hw_check_dma_hang(eth)) ++ schedule_work(ð->pending_work); ++ ++out: ++ schedule_delayed_work(ð->reset.monitor_work, ++ MTK_DMA_MONITOR_TIMEOUT); ++} ++ + static int mtk_hw_init(struct mtk_eth *eth, bool reset) + { + u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | +@@ -3672,6 +3774,7 @@ static int mtk_cleanup(struct mtk_eth *e + mtk_unreg_dev(eth); + mtk_free_dev(eth); + cancel_work_sync(ð->pending_work); ++ cancel_delayed_work_sync(ð->reset.monitor_work); + + return 0; + } +@@ -4099,6 +4202,7 @@ static int mtk_probe(struct platform_dev + + eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; + INIT_WORK(ð->rx_dim.work, mtk_dim_rx); ++ INIT_DELAYED_WORK(ð->reset.monitor_work, mtk_hw_reset_monitor_work); + + eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; + INIT_WORK(ð->tx_dim.work, mtk_dim_tx); +@@ -4301,6 +4405,8 @@ static int mtk_probe(struct platform_dev + netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx); + + platform_set_drvdata(pdev, eth); ++ schedule_delayed_work(ð->reset.monitor_work, ++ MTK_DMA_MONITOR_TIMEOUT); + + return 0; + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -257,6 +257,8 @@ + + #define MTK_RX_DONE_INT_V2 BIT(14) + ++#define MTK_CDM_TXFIFO_RDY BIT(7) ++ + /* QDMA Interrupt grouping registers */ + #define MTK_RLS_DONE_INT BIT(0) + +@@ -542,6 +544,17 @@ + #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) + #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) + ++#define MTK_FE_CDM1_FSM 0x220 ++#define MTK_FE_CDM2_FSM 0x224 ++#define MTK_FE_CDM3_FSM 0x238 ++#define MTK_FE_CDM4_FSM 0x298 ++#define MTK_FE_CDM5_FSM 0x318 ++#define MTK_FE_CDM6_FSM 0x328 ++#define MTK_FE_GDM1_FSM 0x228 ++#define MTK_FE_GDM2_FSM 0x22C ++ ++#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) ++ + struct mtk_rx_dma { + unsigned int rxd1; + unsigned int rxd2; +@@ -938,6 +951,7 @@ struct mtk_reg_map { + u32 delay_irq; /* delay interrupt */ + u32 irq_status; /* interrupt status */ + u32 irq_mask; /* interrupt mask */ ++ u32 adma_rx_dbg0; + u32 int_grp; + } pdma; + struct { +@@ -964,6 +978,8 @@ struct mtk_reg_map { + u32 gdma_to_ppe; + u32 ppe_base; + u32 wdma_base[2]; ++ u32 pse_iq_sta; ++ u32 pse_oq_sta; + }; + + /* struct mtk_eth_data - This is the structure holding all differences +@@ -1006,6 +1022,8 @@ struct mtk_soc_data { + } txrx; + }; + ++#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) ++ + /* currently no SoC has more than 2 macs */ + #define MTK_MAX_DEVS 2 + +@@ -1128,6 +1146,14 @@ struct mtk_eth { + struct rhashtable flow_table; + + struct bpf_prog __rcu *prog; ++ ++ struct { ++ struct delayed_work monitor_work; ++ u32 wdidx; ++ u8 wdma_hang_count; ++ u8 qdma_hang_count; ++ u8 adma_hang_count; ++ } reset; + }; + + /* struct mtk_mac - the structure that holds the info about the MACs of the diff --git a/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch b/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch new file mode 100644 index 000000000..2f816af7e --- /dev/null +++ b/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch @@ -0,0 +1,124 @@ +From: Lorenzo Bianconi +Date: Sat, 14 Jan 2023 18:01:32 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks + +Introduce reset and reset_complete wlan callback to schedule WLAN driver +reset when ethernet/wed driver is resetting. + +Tested-by: Daniel Golle +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3703,6 +3703,11 @@ static void mtk_pending_work(struct work + set_bit(MTK_RESETTING, ð->state); + + mtk_prepare_for_reset(eth); ++ mtk_wed_fe_reset(); ++ /* Run again reset preliminary configuration in order to avoid any ++ * possible race during FE reset since it can run releasing RTNL lock. ++ */ ++ mtk_prepare_for_reset(eth); + + /* stop all devices to make sure that dma is properly shut down */ + for (i = 0; i < MTK_MAC_COUNT; i++) { +@@ -3740,6 +3745,8 @@ static void mtk_pending_work(struct work + + clear_bit(MTK_RESETTING, ð->state); + ++ mtk_wed_fe_reset_complete(); ++ + rtnl_unlock(); + } + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device * + iounmap(reg); + } + ++void mtk_wed_fe_reset(void) ++{ ++ int i; ++ ++ mutex_lock(&hw_lock); ++ ++ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { ++ struct mtk_wed_hw *hw = hw_list[i]; ++ struct mtk_wed_device *dev = hw->wed_dev; ++ int err; ++ ++ if (!dev || !dev->wlan.reset) ++ continue; ++ ++ /* reset callback blocks until WLAN reset is completed */ ++ err = dev->wlan.reset(dev); ++ if (err) ++ dev_err(dev->dev, "wlan reset failed: %d\n", err); ++ } ++ ++ mutex_unlock(&hw_lock); ++} ++ ++void mtk_wed_fe_reset_complete(void) ++{ ++ int i; ++ ++ mutex_lock(&hw_lock); ++ ++ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { ++ struct mtk_wed_hw *hw = hw_list[i]; ++ struct mtk_wed_device *dev = hw->wed_dev; ++ ++ if (!dev || !dev->wlan.reset_complete) ++ continue; ++ ++ dev->wlan.reset_complete(dev); ++ } ++ ++ mutex_unlock(&hw_lock); ++} ++ + static struct mtk_wed_hw * + mtk_wed_assign(struct mtk_wed_device *dev) + { +--- a/drivers/net/ethernet/mediatek/mtk_wed.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed.h +@@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node * + void mtk_wed_exit(void); + int mtk_wed_flow_add(int index); + void mtk_wed_flow_remove(int index); ++void mtk_wed_fe_reset(void); ++void mtk_wed_fe_reset_complete(void); + #else + static inline void + mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, +@@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i + { + } + ++static inline void mtk_wed_fe_reset(void) ++{ ++} ++ ++static inline void mtk_wed_fe_reset_complete(void) ++{ ++} + #endif + + #ifdef CONFIG_DEBUG_FS +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -151,6 +151,8 @@ struct mtk_wed_device { + 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); ++ int (*reset)(struct mtk_wed_device *wed); ++ void (*reset_complete)(struct mtk_wed_device *wed); + } wlan; + #endif + }; diff --git a/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch b/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch new file mode 100644 index 000000000..c63628da9 --- /dev/null +++ b/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch @@ -0,0 +1,106 @@ +From: Lorenzo Bianconi +Date: Mon, 5 Dec 2022 12:34:42 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add reset to rx_ring_setup callback + +This patch adds reset parameter to mtk_wed_rx_ring_setup signature +in order to align rx_ring_setup callback to tx_ring_setup one introduced +in 'commit 23dca7a90017 ("net: ethernet: mtk_wed: add reset to +tx_ring_setup callback")' + +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Leon Romanovsky +Link: https://lore.kernel.org/r/29c6e7a5469e784406cf3e2920351d1207713d05.1670239984.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -1252,7 +1252,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we + } + + static int +-mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size) ++mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size, ++ bool reset) + { + u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; + struct mtk_wed_ring *wdma; +@@ -1261,8 +1262,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we + return -EINVAL; + + wdma = &dev->tx_wdma[idx]; +- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, +- true)) ++ if (!reset && 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, +@@ -1272,6 +1273,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we + 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 (reset) ++ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true); ++ + if (!idx) { + wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE, + wdma->desc_phys); +@@ -1611,18 +1615,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed + } + + static int +-mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) ++mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs, ++ bool reset) + { + 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)) ++ if (!reset && 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)) ++ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, ++ reset)) + return -ENOMEM; + + ring->reg_base = MTK_WED_RING_RX_DATA(idx); +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -162,7 +162,7 @@ struct mtk_wed_ops { + int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, + void __iomem *regs, bool reset); + int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, +- void __iomem *regs); ++ void __iomem *regs, bool reset); + int (*txfree_ring_setup)(struct mtk_wed_device *dev, + void __iomem *regs); + int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, +@@ -230,8 +230,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic + (_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_rx_ring_setup(_dev, _ring, _regs, _reset) \ ++ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset) + #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) \ +@@ -251,7 +251,7 @@ 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_rx_ring_setup(_dev, _ring, _regs, _reset) -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 + #define mtk_wed_device_stop(_dev) do {} while (0) 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/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch similarity index 100% rename from target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch rename to target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch 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/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch similarity index 90% rename from target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch rename to target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch index 3a723324f..34c41b8d4 100644 --- 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/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -939,7 +939,7 @@ static int mtk_init_fq_dma(struct mtk_et +@@ -945,7 +945,7 @@ static int mtk_init_fq_dma(struct mtk_et { const struct mtk_soc_data *soc = eth->soc; dma_addr_t phy_ring_tail; @@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau dma_addr_t dma_addr; int i; -@@ -2203,19 +2203,25 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2209,19 +2209,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; @@ -51,7 +51,7 @@ Signed-off-by: Felix Fietkau u32 next_ptr = ring->phys + next * sz; txd = ring->dma + i * sz; -@@ -2235,22 +2241,22 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2241,22 +2247,22 @@ static int mtk_tx_alloc(struct mtk_eth * * descriptors in ring->dma_pdma. */ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { @@ -79,7 +79,7 @@ Signed-off-by: Felix Fietkau ring->thresh = MAX_SKB_FRAGS; /* make sure that all changes to the dma ring are flushed before we -@@ -2262,14 +2268,14 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2268,14 +2274,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, @@ -96,7 +96,7 @@ Signed-off-by: Felix Fietkau mtk_w32(eth, 0, MT7628_TX_CTX_IDX0); mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx); } -@@ -2287,7 +2293,7 @@ static void mtk_tx_clean(struct mtk_eth +@@ -2293,7 +2299,7 @@ static void mtk_tx_clean(struct mtk_eth int i; if (ring->buf) { @@ -105,7 +105,7 @@ Signed-off-by: Felix Fietkau mtk_tx_unmap(eth, &ring->buf[i], NULL, false); kfree(ring->buf); ring->buf = NULL; -@@ -2295,14 +2301,14 @@ static void mtk_tx_clean(struct mtk_eth +@@ -2301,14 +2307,14 @@ static void mtk_tx_clean(struct mtk_eth if (ring->dma) { dma_free_coherent(eth->dma_dev, @@ -122,7 +122,7 @@ Signed-off-by: Felix Fietkau ring->dma_pdma, ring->phys_pdma); ring->dma_pdma = NULL; } -@@ -2824,7 +2830,7 @@ static void mtk_dma_free(struct mtk_eth +@@ -2830,7 +2836,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, 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/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch similarity index 93% rename from target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch rename to target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch index e8fa8339a..f5124ee6d 100644 --- a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch +++ b/target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4270,7 +4270,7 @@ static const struct mtk_soc_data mt7621_ +@@ -4484,7 +4484,7 @@ static const struct mtk_soc_data mt7621_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7621_CLKS_BITMAP, .required_pctl = false, @@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau .hash_offset = 2, .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, .txrx = { -@@ -4309,7 +4309,7 @@ static const struct mtk_soc_data mt7623_ +@@ -4523,7 +4523,7 @@ static const struct mtk_soc_data mt7623_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7623_CLKS_BITMAP, .required_pctl = true, 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/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch similarity index 88% rename from target/linux/generic/pending-6.1/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch rename to target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch index f10e3ec60..655faa245 100644 --- a/target/linux/generic/pending-6.1/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch +++ b/target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch @@ -22,7 +22,7 @@ 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_ +@@ -55,6 +55,7 @@ static const struct mtk_reg_map mtk_reg_ }, .qdma = { .qtx_cfg = 0x1800, @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau .rx_ptr = 0x1900, .rx_cnt_cfg = 0x1904, .qcrx_ptr = 0x1908, -@@ -61,6 +62,7 @@ static const struct mtk_reg_map mtk_reg_ +@@ -62,6 +63,7 @@ static const struct mtk_reg_map mtk_reg_ .rst_idx = 0x1a08, .delay_irq = 0x1a0c, .fc_th = 0x1a10, @@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau .int_grp = 0x1a20, .hred = 0x1a44, .ctx_ptr = 0x1b00, -@@ -113,6 +115,7 @@ static const struct mtk_reg_map mt7986_r +@@ -117,6 +119,7 @@ static const struct mtk_reg_map mt7986_r }, .qdma = { .qtx_cfg = 0x4400, @@ -46,7 +46,7 @@ Signed-off-by: Felix Fietkau .rx_ptr = 0x4500, .rx_cnt_cfg = 0x4504, .qcrx_ptr = 0x4508, -@@ -130,6 +133,7 @@ static const struct mtk_reg_map mt7986_r +@@ -134,6 +137,7 @@ static const struct mtk_reg_map mt7986_r .fq_tail = 0x4724, .fq_count = 0x4728, .fq_blen = 0x472c, @@ -54,7 +54,7 @@ Signed-off-by: Felix Fietkau }, .gdm1_cnt = 0x1c00, .gdma_to_ppe = 0x3333, -@@ -614,6 +618,75 @@ static void mtk_mac_link_down(struct phy +@@ -620,6 +624,75 @@ static void mtk_mac_link_down(struct phy mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); } @@ -130,7 +130,7 @@ Signed-off-by: Felix Fietkau static void mtk_mac_link_up(struct phylink_config *config, struct phy_device *phy, unsigned int mode, phy_interface_t interface, -@@ -639,6 +712,8 @@ static void mtk_mac_link_up(struct phyli +@@ -645,6 +718,8 @@ static void mtk_mac_link_up(struct phyli break; } @@ -139,7 +139,7 @@ Signed-off-by: Felix Fietkau /* Configure duplex */ if (duplex == DUPLEX_FULL) mcr |= MAC_MCR_FORCE_DPX; -@@ -1100,7 +1175,8 @@ static void mtk_tx_set_dma_desc_v1(struc +@@ -1106,7 +1181,8 @@ static void mtk_tx_set_dma_desc_v1(struc WRITE_ONCE(desc->txd1, info->addr); @@ -149,7 +149,7 @@ Signed-off-by: Felix Fietkau if (info->last) data |= TX_DMA_LS0; WRITE_ONCE(desc->txd3, data); -@@ -1134,9 +1210,6 @@ static void mtk_tx_set_dma_desc_v2(struc +@@ -1140,9 +1216,6 @@ static void mtk_tx_set_dma_desc_v2(struc data |= TX_DMA_LS0; WRITE_ONCE(desc->txd3, data); @@ -159,7 +159,7 @@ Signed-off-by: Felix Fietkau 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); -@@ -1180,11 +1253,12 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1186,11 +1259,12 @@ static int mtk_tx_map(struct sk_buff *sk .gso = gso, .csum = skb->ip_summed == CHECKSUM_PARTIAL, .vlan = skb_vlan_tag_present(skb), @@ -173,7 +173,7 @@ Signed-off-by: Felix Fietkau struct mtk_mac *mac = netdev_priv(dev); struct mtk_eth *eth = mac->hw; const struct mtk_soc_data *soc = eth->soc; -@@ -1192,8 +1266,10 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1198,8 +1272,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; @@ -184,7 +184,7 @@ Signed-off-by: Felix Fietkau itxd = ring->next_free; itxd_pdma = qdma_to_pdma(ring, itxd); if (itxd == ring->last_free) -@@ -1242,7 +1318,7 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1248,7 +1324,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); @@ -193,7 +193,7 @@ Signed-off-by: Felix Fietkau 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, -@@ -1281,7 +1357,7 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1287,7 +1363,7 @@ static int mtk_tx_map(struct sk_buff *sk txd_pdma->txd2 |= TX_DMA_LS1; } @@ -202,7 +202,7 @@ Signed-off-by: Felix Fietkau skb_tx_timestamp(skb); ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); -@@ -1293,8 +1369,7 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1299,8 +1375,7 @@ static int mtk_tx_map(struct sk_buff *sk wmb(); if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { @@ -212,7 +212,7 @@ Signed-off-by: Felix Fietkau mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); } else { int next_idx; -@@ -1363,7 +1438,7 @@ static void mtk_wake_queue(struct mtk_et +@@ -1369,7 +1444,7 @@ static void mtk_wake_queue(struct mtk_et for (i = 0; i < MTK_MAC_COUNT; i++) { if (!eth->netdev[i]) continue; @@ -221,7 +221,7 @@ Signed-off-by: Felix Fietkau } } -@@ -1387,7 +1462,7 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1393,7 +1468,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)) { @@ -230,7 +230,7 @@ Signed-off-by: Felix Fietkau netif_err(eth, tx_queued, dev, "Tx Ring full when queue awake!\n"); spin_unlock(ð->page_lock); -@@ -1413,7 +1488,7 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1419,7 +1494,7 @@ static netdev_tx_t mtk_start_xmit(struct goto drop; if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) @@ -239,7 +239,7 @@ Signed-off-by: Felix Fietkau spin_unlock(ð->page_lock); -@@ -1580,10 +1655,12 @@ static int mtk_xdp_submit_frame(struct m +@@ -1586,10 +1661,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; @@ -252,7 +252,7 @@ Signed-off-by: Felix Fietkau }; int err, index = 0, n_desc = 1, nr_frags; struct mtk_tx_buf *htx_buf, *tx_buf; -@@ -1633,6 +1710,7 @@ static int mtk_xdp_submit_frame(struct m +@@ -1639,6 +1716,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; @@ -260,7 +260,7 @@ Signed-off-by: Felix Fietkau data = skb_frag_address(&sinfo->frags[index]); index++; -@@ -1987,8 +2065,46 @@ rx_done: +@@ -1993,8 +2071,46 @@ rx_done: return done; } @@ -308,7 +308,7 @@ Signed-off-by: Felix Fietkau { const struct mtk_reg_map *reg_map = eth->soc->reg_map; struct mtk_tx_ring *ring = ð->tx_ring; -@@ -2020,12 +2136,9 @@ static int mtk_poll_tx_qdma(struct mtk_e +@@ -2026,12 +2142,9 @@ static int mtk_poll_tx_qdma(struct mtk_e break; if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { @@ -323,7 +323,7 @@ Signed-off-by: Felix Fietkau budget--; } mtk_tx_unmap(eth, tx_buf, &bq, true); -@@ -2044,7 +2157,7 @@ static int mtk_poll_tx_qdma(struct mtk_e +@@ -2050,7 +2163,7 @@ static int mtk_poll_tx_qdma(struct mtk_e } static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget, @@ -332,7 +332,7 @@ Signed-off-by: Felix Fietkau { struct mtk_tx_ring *ring = ð->tx_ring; struct mtk_tx_buf *tx_buf; -@@ -2062,12 +2175,8 @@ static int mtk_poll_tx_pdma(struct mtk_e +@@ -2068,12 +2181,8 @@ static int mtk_poll_tx_pdma(struct mtk_e break; if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { @@ -347,7 +347,7 @@ Signed-off-by: Felix Fietkau budget--; } mtk_tx_unmap(eth, tx_buf, &bq, true); -@@ -2089,26 +2198,15 @@ static int mtk_poll_tx(struct mtk_eth *e +@@ -2095,26 +2204,15 @@ static int mtk_poll_tx(struct mtk_eth *e { struct mtk_tx_ring *ring = ð->tx_ring; struct dim_sample dim_sample = {}; @@ -379,7 +379,7 @@ Signed-off-by: Felix Fietkau dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes, &dim_sample); -@@ -2118,7 +2216,7 @@ static int mtk_poll_tx(struct mtk_eth *e +@@ -2124,7 +2222,7 @@ static int mtk_poll_tx(struct mtk_eth *e (atomic_read(&ring->free_count) > ring->thresh)) mtk_wake_queue(eth); @@ -388,7 +388,7 @@ Signed-off-by: Felix Fietkau } static void mtk_handle_status_irq(struct mtk_eth *eth) -@@ -2204,6 +2302,7 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2210,6 +2308,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; @@ -396,7 +396,7 @@ Signed-off-by: Felix Fietkau if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) ring_size = MTK_QDMA_RING_SIZE; -@@ -2271,8 +2370,25 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2277,8 +2376,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); @@ -424,7 +424,7 @@ Signed-off-by: Felix Fietkau } else { mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); -@@ -2939,7 +3055,7 @@ static int mtk_start_dma(struct mtk_eth +@@ -2960,7 +3076,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 | @@ -433,7 +433,7 @@ Signed-off-by: Felix Fietkau else val |= MTK_RX_BT_32DWORDS; mtk_w32(eth, val, reg_map->qdma.glo_cfg); -@@ -2985,6 +3101,45 @@ static void mtk_gdm_config(struct mtk_et +@@ -3006,6 +3122,45 @@ static void mtk_gdm_config(struct mtk_et mtk_w32(eth, 0, MTK_RST_GL); } @@ -479,7 +479,7 @@ Signed-off-by: Felix Fietkau static int mtk_open(struct net_device *dev) { struct mtk_mac *mac = netdev_priv(dev); -@@ -3027,7 +3182,8 @@ static int mtk_open(struct net_device *d +@@ -3048,7 +3203,8 @@ static int mtk_open(struct net_device *d refcount_inc(ð->dma_refcnt); phylink_start(mac->phylink); @@ -489,7 +489,7 @@ Signed-off-by: Felix Fietkau return 0; } -@@ -3562,8 +3718,12 @@ static int mtk_unreg_dev(struct mtk_eth +@@ -3774,8 +3930,12 @@ static int mtk_unreg_dev(struct mtk_eth int i; for (i = 0; i < MTK_MAC_COUNT; i++) { @@ -502,7 +502,7 @@ Signed-off-by: Felix Fietkau unregister_netdev(eth->netdev[i]); } -@@ -3779,6 +3939,23 @@ static int mtk_set_rxnfc(struct net_devi +@@ -3992,6 +4152,23 @@ static int mtk_set_rxnfc(struct net_devi return ret; } @@ -526,7 +526,7 @@ Signed-off-by: Felix Fietkau static const struct ethtool_ops mtk_ethtool_ops = { .get_link_ksettings = mtk_get_link_ksettings, .set_link_ksettings = mtk_set_link_ksettings, -@@ -3814,6 +3991,7 @@ static const struct net_device_ops mtk_n +@@ -4027,6 +4204,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, @@ -534,7 +534,7 @@ Signed-off-by: Felix Fietkau }; static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) -@@ -3823,6 +4001,7 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4036,6 +4214,7 @@ static int mtk_add_mac(struct mtk_eth *e struct phylink *phylink; struct mtk_mac *mac; int id, err; @@ -542,7 +542,7 @@ Signed-off-by: Felix Fietkau if (!_id) { dev_err(eth->dev, "missing mac id\n"); -@@ -3840,7 +4019,10 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4053,7 +4232,10 @@ static int mtk_add_mac(struct mtk_eth *e return -EINVAL; } @@ -554,7 +554,7 @@ Signed-off-by: Felix Fietkau if (!eth->netdev[id]) { dev_err(eth->dev, "alloc_etherdev failed\n"); return -ENOMEM; -@@ -3937,6 +4119,11 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4150,6 +4332,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; @@ -576,7 +576,7 @@ Signed-off-by: Felix Fietkau #define MTK_QDMA_PAGE_SIZE 2048 #define MTK_MAX_RX_LENGTH 1536 #define MTK_MAX_RX_LENGTH_2K 2048 -@@ -204,8 +205,26 @@ +@@ -216,8 +217,26 @@ #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) /* QDMA TX Queue Configuration Registers */ @@ -603,7 +603,7 @@ Signed-off-by: Felix Fietkau /* QDMA Global Configuration Register */ #define MTK_RX_2B_OFFSET BIT(31) #define MTK_RX_BT_32DWORDS (3 << 11) -@@ -224,6 +243,7 @@ +@@ -236,6 +255,7 @@ #define MTK_WCOMP_EN BIT(24) #define MTK_RESV_BUF (0x40 << 16) #define MTK_MUTLI_CNT (0x4 << 12) @@ -611,7 +611,7 @@ Signed-off-by: Felix Fietkau /* QDMA Flow Control Register */ #define FC_THRES_DROP_MODE BIT(20) -@@ -252,8 +272,6 @@ +@@ -266,8 +286,6 @@ #define MTK_STAT_OFFSET 0x40 /* QDMA TX NUM */ @@ -620,7 +620,7 @@ Signed-off-by: Felix Fietkau #define QID_BITS_V2(x) (((x) & 0x3f) << 16) #define MTK_QDMA_GMAC2_QID 8 -@@ -283,6 +301,7 @@ +@@ -297,6 +315,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) @@ -628,7 +628,7 @@ Signed-off-by: Felix Fietkau /* PDMA on MT7628 */ #define TX_DMA_DONE BIT(31) -@@ -931,6 +950,7 @@ struct mtk_reg_map { +@@ -957,6 +976,7 @@ struct mtk_reg_map { } pdma; struct { u32 qtx_cfg; /* tx queue configuration */ @@ -636,7 +636,7 @@ Signed-off-by: Felix Fietkau u32 rx_ptr; /* rx base pointer */ u32 rx_cnt_cfg; /* rx max count configuration */ u32 qcrx_ptr; /* rx cpu pointer */ -@@ -948,6 +968,7 @@ struct mtk_reg_map { +@@ -974,6 +994,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 */ @@ -644,7 +644,7 @@ Signed-off-by: Felix Fietkau } qdma; u32 gdm1_cnt; u32 gdma_to_ppe; -@@ -1139,6 +1160,7 @@ struct mtk_mac { +@@ -1177,6 +1198,7 @@ struct mtk_mac { __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; int hwlro_ip_cnt; unsigned int syscfg0; diff --git a/target/linux/generic/pending-6.1/732-05-net-dsa-tag_mtk-assign-per-port-queues.patch b/target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch similarity index 80% rename from target/linux/generic/pending-6.1/732-05-net-dsa-tag_mtk-assign-per-port-queues.patch rename to target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch index 7739366ad..186df4bdc 100644 --- a/target/linux/generic/pending-6.1/732-05-net-dsa-tag_mtk-assign-per-port-queues.patch +++ b/target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch @@ -9,9 +9,9 @@ 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; +@@ -25,6 +25,8 @@ static struct sk_buff *mtk_tag_xmit(stru + u8 xmit_tpid; + u8 *mtk_tag; + skb_set_queue_mapping(skb, dp->index); + 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/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch similarity index 97% rename from target/linux/generic/pending-6.1/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch rename to target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch index 39d1d93dd..d29177eee 100644 --- a/target/linux/generic/pending-6.1/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch +++ b/target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch @@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau #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) -@@ -350,6 +352,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e +@@ -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); 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/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch similarity index 94% rename from target/linux/generic/pending-6.1/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch rename to target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch index 98199d1e8..31a8ca3ea 100644 --- a/target/linux/generic/pending-6.1/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch +++ b/target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -896,7 +896,13 @@ enum mkt_eth_capabilities { +@@ -921,7 +921,13 @@ enum mkt_eth_capabilities { #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) 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/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch similarity index 100% rename from target/linux/generic/pending-6.1/732-08-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch rename to target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch 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/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch similarity index 93% rename from target/linux/generic/pending-6.1/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch rename to target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch index 8c82ba575..8c368868e 100644 --- a/target/linux/generic/pending-6.1/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch +++ b/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau #include "mtk_eth_soc.h" #include "mtk_wed.h" -@@ -2016,16 +2017,22 @@ static int mtk_poll_rx(struct napi_struc +@@ -2022,16 +2023,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) { @@ -52,7 +52,7 @@ Signed-off-by: Felix Fietkau } skb_record_rx_queue(skb, 0); -@@ -2850,15 +2857,30 @@ static netdev_features_t mtk_fix_feature +@@ -2856,15 +2863,30 @@ static netdev_features_t mtk_fix_feature static int mtk_set_features(struct net_device *dev, netdev_features_t features) { @@ -88,7 +88,7 @@ Signed-off-by: Felix Fietkau } /* wait for DMA to finish whatever it is doing before we start using it again */ -@@ -3140,11 +3162,45 @@ found: +@@ -3161,11 +3183,45 @@ found: return NOTIFY_DONE; } @@ -135,7 +135,7 @@ Signed-off-by: Felix Fietkau err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); if (err) { -@@ -3507,6 +3563,10 @@ static int mtk_hw_init(struct mtk_eth *e +@@ -3686,6 +3742,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); @@ -146,7 +146,7 @@ Signed-off-by: Felix Fietkau /* Enable RX VLan Offloading */ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -@@ -3710,6 +3770,12 @@ static int mtk_free_dev(struct mtk_eth * +@@ -3922,6 +3982,12 @@ static int mtk_free_dev(struct mtk_eth * free_netdev(eth->netdev[i]); } @@ -171,7 +171,7 @@ Signed-off-by: Felix Fietkau #define MTK_QDMA_NUM_QUEUES 16 #define MTK_QDMA_PAGE_SIZE 2048 #define MTK_MAX_RX_LENGTH 1536 -@@ -93,6 +96,9 @@ +@@ -105,6 +108,9 @@ #define MTK_CDMQ_IG_CTRL 0x1400 #define MTK_CDMQ_STAG_EN BIT(0) @@ -181,7 +181,7 @@ Signed-off-by: Felix Fietkau /* CDMP Ingress Control Register */ #define MTK_CDMP_IG_CTRL 0x400 #define MTK_CDMP_STAG_EN BIT(0) -@@ -1140,6 +1146,8 @@ struct mtk_eth { +@@ -1170,6 +1176,8 @@ struct mtk_eth { int ip_align; diff --git a/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch b/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch new file mode 100644 index 000000000..efbceb9a1 --- /dev/null +++ b/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch @@ -0,0 +1,42 @@ +From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= +Date: Sat, 28 Jan 2023 12:42:32 +0300 +Subject: [PATCH] net: ethernet: mtk_eth_soc: disable hardware DSA untagging + for second MAC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +According to my tests on MT7621AT and MT7623NI SoCs, hardware DSA untagging +won't work on the second MAC. Therefore, disable this feature when the +second MAC of the MT7621 and MT7623 SoCs is being used. + +Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") +Link: https://lore.kernel.org/netdev/6249fc14-b38a-c770-36b4-5af6d41c21d3@arinc9.com/ +Tested-by: Arınç ÜNAL +Signed-off-by: Arınç ÜNAL +Link: https://lore.kernel.org/r/20230128094232.2451947-1-arinc.unal@arinc9.com +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3199,7 +3199,8 @@ static int mtk_open(struct net_device *d + struct mtk_eth *eth = mac->hw; + int i, err; + +- if (mtk_uses_dsa(dev) && !eth->prog) { ++ if ((mtk_uses_dsa(dev) && !eth->prog) && ++ !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) { + for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { + struct metadata_dst *md_dst = eth->dsa_meta[i]; + +@@ -3216,7 +3217,8 @@ static int mtk_open(struct net_device *d + } + } else { + /* Hardware special tag parsing needs to be disabled if at least +- * one MAC does not use DSA. ++ * one MAC does not use DSA, or the second MAC of the MT7621 and ++ * MT7623 SoCs is being used. + */ + u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); + val &= ~MTK_CDMP_STAG_EN; diff --git a/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch b/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch new file mode 100644 index 000000000..c0bfd9bd0 --- /dev/null +++ b/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch @@ -0,0 +1,54 @@ +From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= +Date: Sun, 5 Feb 2023 20:53:31 +0300 +Subject: [PATCH] net: ethernet: mtk_eth_soc: enable special tag when any MAC + uses DSA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The special tag is only enabled when the first MAC uses DSA. However, it +must be enabled when any MAC uses DSA. Change the check accordingly. + +This fixes hardware DSA untagging not working on the second MAC of the +MT7621 and MT7623 SoCs, and likely other SoCs too. Therefore, remove the +check that disables hardware DSA untagging for the second MAC of the MT7621 +and MT7623 SoCs. + +Fixes: a1f47752fd62 ("net: ethernet: mtk_eth_soc: disable hardware DSA untagging for second MAC") +Co-developed-by: Richard van Schagen +Signed-off-by: Richard van Schagen +Signed-off-by: Arınç ÜNAL +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3134,7 +3134,7 @@ static void mtk_gdm_config(struct mtk_et + + val |= config; + +- if (!i && eth->netdev[0] && netdev_uses_dsa(eth->netdev[0])) ++ if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i])) + val |= MTK_GDMA_SPECIAL_TAG; + + mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); +@@ -3199,8 +3199,7 @@ static int mtk_open(struct net_device *d + struct mtk_eth *eth = mac->hw; + int i, err; + +- if ((mtk_uses_dsa(dev) && !eth->prog) && +- !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) { ++ 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]; + +@@ -3217,8 +3216,7 @@ static int mtk_open(struct net_device *d + } + } else { + /* Hardware special tag parsing needs to be disabled if at least +- * one MAC does not use DSA, or the second MAC of the MT7621 and +- * MT7623 SoCs is being used. ++ * one MAC does not use DSA. + */ + u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); + val &= ~MTK_CDMP_STAG_EN; diff --git a/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch b/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch new file mode 100644 index 000000000..a9879ebfa --- /dev/null +++ b/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch @@ -0,0 +1,129 @@ +From: Vladimir Oltean +Date: Tue, 7 Feb 2023 12:30:27 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix DSA TX tag hwaccel for switch + port 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Arınç reports that on his MT7621AT Unielec U7621-06 board and MT7623NI +Bananapi BPI-R2, packets received by the CPU over mt7530 switch port 0 +(of which this driver acts as the DSA master) are not processed +correctly by software. More precisely, they arrive without a DSA tag +(in packet or in the hwaccel area - skb_metadata_dst()), so DSA cannot +demux them towards the switch's interface for port 0. Traffic from other +ports receives a skb_metadata_dst() with the correct port and is demuxed +properly. + +Looking at mtk_poll_rx(), it becomes apparent that this driver uses the +skb vlan hwaccel area: + + union { + u32 vlan_all; + struct { + __be16 vlan_proto; + __u16 vlan_tci; + }; + }; + +as a temporary storage for the VLAN hwaccel tag, or the DSA hwaccel tag. +If this is a DSA master it's a DSA hwaccel tag, and finally clears up +the skb VLAN hwaccel header. + +I'm guessing that the problem is the (mis)use of API. +skb_vlan_tag_present() looks like this: + + #define skb_vlan_tag_present(__skb) (!!(__skb)->vlan_all) + +So if both vlan_proto and vlan_tci are zeroes, skb_vlan_tag_present() +returns precisely false. I don't know for sure what is the format of the +DSA hwaccel tag, but I surely know that lowermost 3 bits of vlan_proto +are 0 when receiving from port 0: + + unsigned int port = vlan_proto & GENMASK(2, 0); + +If the RX descriptor has no other bits set to non-zero values in +RX_DMA_VTAG, then the call to __vlan_hwaccel_put_tag() will not, in +fact, make the subsequent skb_vlan_tag_present() return true, because +it's implemented like this: + +static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, + __be16 vlan_proto, u16 vlan_tci) +{ + skb->vlan_proto = vlan_proto; + skb->vlan_tci = vlan_tci; +} + +What we need to do to fix this problem (assuming this is the problem) is +to stop using skb->vlan_all as temporary storage for driver affairs, and +just create some local variables that serve the same purpose, but +hopefully better. Instead of calling skb_vlan_tag_present(), let's look +at a boolean has_hwaccel_tag which we set to true when the RX DMA +descriptors have something. Disambiguate based on netdev_uses_dsa() +whether this is a VLAN or DSA hwaccel tag, and only call +__vlan_hwaccel_put_tag() if we're certain it's a VLAN tag. + +Arınç confirms that the treatment works, so this validates the +assumption. + +Link: https://lore.kernel.org/netdev/704f3a72-fc9e-714a-db54-272e17612637@arinc9.com/ +Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") +Reported-by: Arınç ÜNAL +Tested-by: Arınç ÜNAL +Signed-off-by: Vladimir Oltean +Reviewed-by: Felix Fietkau +Signed-off-by: David S. Miller +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1878,7 +1878,9 @@ static int mtk_poll_rx(struct napi_struc + + while (done < budget) { + unsigned int pktlen, *rxdcsum; ++ bool has_hwaccel_tag = false; + struct net_device *netdev; ++ u16 vlan_proto, vlan_tci; + dma_addr_t dma_addr; + u32 hash, reason; + int mac = 0; +@@ -2018,27 +2020,29 @@ static int mtk_poll_rx(struct napi_struc + + 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)); ++ if (trxd.rxd3 & RX_DMA_VTAG_V2) { ++ vlan_proto = RX_DMA_VPID(trxd.rxd4); ++ vlan_tci = RX_DMA_VID(trxd.rxd4); ++ has_hwaccel_tag = true; ++ } + } else if (trxd.rxd2 & RX_DMA_VTAG) { +- __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)), +- RX_DMA_VID(trxd.rxd3)); ++ vlan_proto = RX_DMA_VPID(trxd.rxd3); ++ vlan_tci = RX_DMA_VID(trxd.rxd3); ++ has_hwaccel_tag = true; + } + } + + /* 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 (has_hwaccel_tag && netdev_uses_dsa(netdev)) { ++ unsigned int port = vlan_proto & 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); ++ } else if (has_hwaccel_tag) { ++ __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci); + } + + skb_record_rx_queue(skb, 0); diff --git a/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch b/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch new file mode 100644 index 000000000..a3bb1c5db --- /dev/null +++ b/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch @@ -0,0 +1,26 @@ +From: Christophe JAILLET +Date: Sun, 12 Feb 2023 07:51:51 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: No need to clear memory after a + dma_alloc_coherent() call + +dma_alloc_coherent() already clears the allocated memory, there is no need +to explicitly call memset(). + +Moreover, it is likely that the size in the memset() is incorrect and +should be "size * sizeof(*ring->desc)". + +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/d5acce7dd108887832c9719f62c7201b4c83b3fb.1676184599.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -779,7 +779,6 @@ mtk_wed_rro_ring_alloc(struct mtk_wed_de + + ring->desc_size = sizeof(*ring->desc); + ring->size = size; +- memset(ring->desc, 0, size); + + return 0; + } diff --git a/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch b/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch new file mode 100644 index 000000000..e043a681d --- /dev/null +++ b/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch @@ -0,0 +1,61 @@ +From: Lorenzo Bianconi +Date: Wed, 7 Dec 2022 15:04:54 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: fix some possible NULL pointer + dereferences + +Fix possible NULL pointer dereference in mtk_wed_detach routine checking +wo pointer is properly allocated before running mtk_wed_wo_reset() and +mtk_wed_wo_deinit(). +Even if it is just a theoretical issue at the moment check wo pointer is +not NULL in mtk_wed_mcu_msg_update. +Moreover, honor mtk_wed_mcu_send_msg return value in mtk_wed_wo_reset() + +Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support") +Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Leon Romanovsky +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -174,9 +174,10 @@ mtk_wed_wo_reset(struct mtk_wed_device * + 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 (mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, ++ MTK_WED_WO_CMD_CHANGE_STATE, &state, ++ sizeof(state), false)) ++ return; + + if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val, + val == MTK_WED_WOIF_DISABLE_DONE, +@@ -632,9 +633,11 @@ mtk_wed_detach(struct mtk_wed_device *de + mtk_wed_free_tx_rings(dev); + + if (mtk_wed_get_rx_capa(dev)) { +- mtk_wed_wo_reset(dev); ++ if (hw->wed_wo) ++ mtk_wed_wo_reset(dev); + mtk_wed_free_rx_rings(dev); +- mtk_wed_wo_deinit(hw); ++ if (hw->wed_wo) ++ mtk_wed_wo_deinit(hw); + } + + if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { +--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c +@@ -207,6 +207,9 @@ int mtk_wed_mcu_msg_update(struct mtk_we + if (dev->hw->version == 1) + return 0; + ++ if (WARN_ON(!wo)) ++ return -ENODEV; ++ + return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len, + true); + } diff --git a/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch b/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch new file mode 100644 index 000000000..0afe7106e --- /dev/null +++ b/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch @@ -0,0 +1,58 @@ +From: Lorenzo Bianconi +Date: Wed, 7 Dec 2022 15:04:55 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: fix possible deadlock if + mtk_wed_wo_init fails + +Introduce __mtk_wed_detach() in order to avoid a deadlock in +mtk_wed_attach routine if mtk_wed_wo_init fails since both +mtk_wed_attach and mtk_wed_detach run holding hw_lock mutex. + +Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Leon Romanovsky +Signed-off-by: Jakub Kicinski +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -619,12 +619,10 @@ mtk_wed_deinit(struct mtk_wed_device *de + } + + static void +-mtk_wed_detach(struct mtk_wed_device *dev) ++__mtk_wed_detach(struct mtk_wed_device *dev) + { + struct mtk_wed_hw *hw = dev->hw; + +- mutex_lock(&hw_lock); +- + mtk_wed_deinit(dev); + + mtk_wdma_rx_reset(dev); +@@ -657,6 +655,13 @@ mtk_wed_detach(struct mtk_wed_device *de + module_put(THIS_MODULE); + + hw->wed_dev = NULL; ++} ++ ++static void ++mtk_wed_detach(struct mtk_wed_device *dev) ++{ ++ mutex_lock(&hw_lock); ++ __mtk_wed_detach(dev); + mutex_unlock(&hw_lock); + } + +@@ -1538,8 +1543,10 @@ mtk_wed_attach(struct mtk_wed_device *de + ret = mtk_wed_wo_init(hw); + } + out: +- if (ret) +- mtk_wed_detach(dev); ++ if (ret) { ++ dev_err(dev->hw->dev, "failed to attach wed device\n"); ++ __mtk_wed_detach(dev); ++ } + unlock: + mutex_unlock(&hw_lock); + diff --git a/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch b/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch new file mode 100644 index 000000000..ca5b6b3a3 --- /dev/null +++ b/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch @@ -0,0 +1,31 @@ +From: Felix Fietkau +Date: Fri, 24 Mar 2023 14:56:58 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix tx throughput regression with + direct 1G links + +Using the QDMA tx scheduler to throttle tx to line speed works fine for +switch ports, but apparently caused a regression on non-switch ports. + +Based on a number of tests, it seems that this throttling can be safely +dropped without re-introducing the issues on switch ports that the +tx scheduling changes resolved. + +Link: https://lore.kernel.org/netdev/trinity-92c3826f-c2c8-40af-8339-bc6d0d3ffea4-1678213958520@3c-app-gmx-bs16/ +Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues") +Reported-by: Frank Wunderlich +Reported-by: Daniel Golle +Tested-by: Daniel Golle +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -719,8 +719,6 @@ 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; diff --git a/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch b/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch new file mode 100644 index 000000000..850b80641 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch @@ -0,0 +1,55 @@ +From b6a709cb51f7bdc55c01cec886098a9753ce8c28 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:10:42 +0100 +Subject: [PATCH 01/10] net: mtk_eth_soc: add definitions for PCS + +As a result of help from Frank Wunderlich to investigate and test, we +know a bit more about the PCS on the Mediatek platforms. Update the +definitions from this investigation. + +This PCS appears similar, but not identical to the Lynx PCS. + +Although not included in this patch, but for future reference, the PHY +ID registers at offset 4 read as 0x4d544950 'MTIP'. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -504,8 +504,10 @@ + #define ETHSYS_DMA_AG_MAP_PPE BIT(2) + + /* SGMII subsystem config registers */ +-/* Register to auto-negotiation restart */ ++/* BMCR (low 16) BMSR (high 16) */ + #define SGMSYS_PCS_CONTROL_1 0x0 ++#define SGMII_BMCR GENMASK(15, 0) ++#define SGMII_BMSR GENMASK(31, 16) + #define SGMII_AN_RESTART BIT(9) + #define SGMII_ISOLATE BIT(10) + #define SGMII_AN_ENABLE BIT(12) +@@ -515,13 +517,18 @@ + #define SGMII_PCS_FAULT BIT(23) + #define SGMII_AN_EXPANSION_CLR BIT(30) + ++#define SGMSYS_PCS_ADVERTISE 0x8 ++#define SGMII_ADVERTISE GENMASK(15, 0) ++#define SGMII_LPA GENMASK(31, 16) ++ + /* Register to programmable link timer, the unit in 2 * 8ns */ + #define SGMSYS_PCS_LINK_TIMER 0x18 +-#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & GENMASK(19, 0)) ++#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) ++#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK) + + /* Register to control remote fault */ + #define SGMSYS_SGMII_MODE 0x20 +-#define SGMII_IF_MODE_BIT0 BIT(0) ++#define SGMII_IF_MODE_SGMII BIT(0) + #define SGMII_SPEED_DUPLEX_AN BIT(1) + #define SGMII_SPEED_MASK GENMASK(3, 2) + #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) diff --git a/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch b/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch new file mode 100644 index 000000000..4ea428c9d --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch @@ -0,0 +1,74 @@ +From 5cf7797526ee81bea0f627bccaa3d887f48f53e0 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:10:47 +0100 +Subject: [PATCH 02/10] net: mtk_eth_soc: eliminate unnecessary error handling + +The functions called by the pcs_config() method always return zero, so +there is no point trying to handle an error from these functions. Make +these functions void, eliminate the "err" variable and simply return +zero from the pcs_config() function itself. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -20,7 +20,7 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st + } + + /* For SGMII interface mode */ +-static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) ++static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) + { + unsigned int val; + +@@ -39,16 +39,13 @@ static int mtk_pcs_setup_mode_an(struct + regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); + val &= ~SGMII_PHYA_PWD; + regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); +- +- return 0; +- + } + + /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a + * fixed speed. + */ +-static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, +- phy_interface_t interface) ++static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, ++ phy_interface_t interface) + { + unsigned int val; + +@@ -73,8 +70,6 @@ static int mtk_pcs_setup_mode_force(stru + regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); + val &= ~SGMII_PHYA_PWD; + regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); +- +- return 0; + } + + static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, +@@ -83,15 +78,14 @@ static int mtk_pcs_config(struct phylink + bool permit_pause_to_mac) + { + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); +- int err = 0; + + /* Setup SGMIISYS with the determined property */ + if (interface != PHY_INTERFACE_MODE_SGMII) +- err = mtk_pcs_setup_mode_force(mpcs, interface); ++ mtk_pcs_setup_mode_force(mpcs, interface); + else if (phylink_autoneg_inband(mode)) +- err = mtk_pcs_setup_mode_an(mpcs); ++ mtk_pcs_setup_mode_an(mpcs); + +- return err; ++ return 0; + } + + static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch b/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch new file mode 100644 index 000000000..64a4a72fa --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch @@ -0,0 +1,46 @@ +From c000dca098002da193b98099df051c9ead0cacb4 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:10:52 +0100 +Subject: [PATCH 03/10] net: mtk_eth_soc: add pcs_get_state() implementation + +Add a pcs_get_state() implementation which uses the advertisements +to compute the resulting link modes, and BMSR contents to determine +negotiation and link status. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -19,6 +19,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st + return container_of(pcs, struct mtk_pcs, pcs); + } + ++static void mtk_pcs_get_state(struct phylink_pcs *pcs, ++ struct phylink_link_state *state) ++{ ++ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); ++ unsigned int bm, adv; ++ ++ /* Read the BMSR and LPA */ ++ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); ++ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); ++ ++ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), ++ FIELD_GET(SGMII_LPA, adv)); ++} ++ + /* For SGMII interface mode */ + static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) + { +@@ -117,6 +131,7 @@ static void mtk_pcs_link_up(struct phyli + } + + static const struct phylink_pcs_ops mtk_pcs_ops = { ++ .pcs_get_state = mtk_pcs_get_state, + .pcs_config = mtk_pcs_config, + .pcs_an_restart = mtk_pcs_restart_an, + .pcs_link_up = mtk_pcs_link_up, diff --git a/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch b/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch new file mode 100644 index 000000000..24610fe11 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch @@ -0,0 +1,130 @@ +From 0d2351dc2768061689abd4de1529fa206bbd574e Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:10:58 +0100 +Subject: [PATCH 04/10] net: mtk_eth_soc: convert mtk_sgmii to use + regmap_update_bits() + +mtk_sgmii does a lot of read-modify-write operations, for which there +is a specific regmap function. Use this function instead of open-coding +the operations. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 61 ++++++++++------------- + 1 file changed, 26 insertions(+), 35 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -36,23 +36,18 @@ static void mtk_pcs_get_state(struct phy + /* For SGMII interface mode */ + static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) + { +- unsigned int val; +- + /* Setup the link timer and QPHY power up inside SGMIISYS */ + regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, + SGMII_LINK_TIMER_DEFAULT); + +- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); +- val |= SGMII_REMOTE_FAULT_DIS; +- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); +- +- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); +- val |= SGMII_AN_RESTART; +- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); +- +- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); +- val &= ~SGMII_PHYA_PWD; +- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); ++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, ++ SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); ++ ++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, ++ SGMII_AN_RESTART, SGMII_AN_RESTART); ++ ++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, ++ SGMII_PHYA_PWD, 0); + } + + /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a +@@ -61,29 +56,26 @@ static void mtk_pcs_setup_mode_an(struct + static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, + phy_interface_t interface) + { +- unsigned int val; ++ unsigned int rgc3; + +- regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); +- val &= ~RG_PHY_SPEED_MASK; + if (interface == PHY_INTERFACE_MODE_2500BASEX) +- val |= RG_PHY_SPEED_3_125G; +- regmap_write(mpcs->regmap, mpcs->ana_rgc3, val); ++ rgc3 = RG_PHY_SPEED_3_125G; ++ ++ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, ++ RG_PHY_SPEED_3_125G, rgc3); + + /* Disable SGMII AN */ +- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); +- val &= ~SGMII_AN_ENABLE; +- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); ++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, ++ SGMII_AN_ENABLE, 0); + + /* Set the speed etc but leave the duplex unchanged */ +- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); +- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK; +- val |= SGMII_SPEED_1000; +- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); ++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, ++ SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, ++ SGMII_SPEED_1000); + + /* Release PHYA power down state */ +- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); +- val &= ~SGMII_PHYA_PWD; +- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); ++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, ++ SGMII_PHYA_PWD, 0); + } + + static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, +@@ -105,29 +97,28 @@ static int mtk_pcs_config(struct phylink + static void mtk_pcs_restart_an(struct phylink_pcs *pcs) + { + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); +- unsigned int val; + +- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); +- val |= SGMII_AN_RESTART; +- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); ++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, ++ SGMII_AN_RESTART, SGMII_AN_RESTART); + } + + static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, + phy_interface_t interface, int speed, int duplex) + { + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); +- unsigned int val; ++ unsigned int sgm_mode; + + if (!phy_interface_mode_is_8023z(interface)) + return; + + /* SGMII force duplex setting */ +- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); +- val &= ~SGMII_DUPLEX_FULL; + if (duplex == DUPLEX_FULL) +- val |= SGMII_DUPLEX_FULL; ++ sgm_mode = SGMII_DUPLEX_FULL; ++ else ++ sgm_mode = 0; + +- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); ++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, ++ SGMII_DUPLEX_FULL, sgm_mode); + } + + static const struct phylink_pcs_ops mtk_pcs_ops = { diff --git a/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch b/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch new file mode 100644 index 000000000..ba76ca40f --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch @@ -0,0 +1,52 @@ +From 12198c3a410fe69843e335c1bbf6d4c2a4d48e4e Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:11:03 +0100 +Subject: [PATCH 05/10] net: mtk_eth_soc: add out of band forcing of speed and + duplex in pcs_link_up + +Add support for forcing the link speed and duplex setting in the +pcs_link_up() method for out of band modes, which will be useful when +we finish converting the pcs_config() method. Until then, we still have +to force duplex for 802.3z modes to work correctly. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 28 ++++++++++++++--------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -108,17 +108,23 @@ static void mtk_pcs_link_up(struct phyli + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); + unsigned int sgm_mode; + +- if (!phy_interface_mode_is_8023z(interface)) +- return; ++ if (!phylink_autoneg_inband(mode) || ++ phy_interface_mode_is_8023z(interface)) { ++ /* Force the speed and duplex setting */ ++ if (speed == SPEED_10) ++ sgm_mode = SGMII_SPEED_10; ++ else if (speed == SPEED_100) ++ sgm_mode = SGMII_SPEED_100; ++ else ++ sgm_mode = SGMII_SPEED_1000; + +- /* SGMII force duplex setting */ +- if (duplex == DUPLEX_FULL) +- sgm_mode = SGMII_DUPLEX_FULL; +- else +- sgm_mode = 0; ++ if (duplex == DUPLEX_FULL) ++ sgm_mode |= SGMII_DUPLEX_FULL; + +- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, +- SGMII_DUPLEX_FULL, sgm_mode); ++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, ++ SGMII_DUPLEX_FULL | SGMII_SPEED_MASK, ++ sgm_mode); ++ } + } + + static const struct phylink_pcs_ops mtk_pcs_ops = { diff --git a/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch b/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch new file mode 100644 index 000000000..b76e15927 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch @@ -0,0 +1,48 @@ +From 6f38fffe2179dd29612aea2c67c46ed6682b4e46 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:11:08 +0100 +Subject: [PATCH 06/10] net: mtk_eth_soc: move PHY power up + +The PHY power up is common to both configuration paths, so move it into +the parent function. We need to do this for all serdes modes. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -45,9 +45,6 @@ static void mtk_pcs_setup_mode_an(struct + + regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, + SGMII_AN_RESTART, SGMII_AN_RESTART); +- +- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, +- SGMII_PHYA_PWD, 0); + } + + /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a +@@ -72,10 +69,6 @@ static void mtk_pcs_setup_mode_force(str + regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, + SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, + SGMII_SPEED_1000); +- +- /* Release PHYA power down state */ +- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, +- SGMII_PHYA_PWD, 0); + } + + static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, +@@ -91,6 +84,10 @@ static int mtk_pcs_config(struct phylink + else if (phylink_autoneg_inband(mode)) + mtk_pcs_setup_mode_an(mpcs); + ++ /* Release PHYA power down state */ ++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, ++ SGMII_PHYA_PWD, 0); ++ + return 0; + } + diff --git a/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch b/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch new file mode 100644 index 000000000..cd9f0699b --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch @@ -0,0 +1,48 @@ +From f752c0df13dfeb721c11d3debb79f08cf437344f Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:11:13 +0100 +Subject: [PATCH 07/10] net: mtk_eth_soc: move interface speed selection + +Move the selection of the underlying interface speed to the pcs_config +function, so we always program the interface speed. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -53,14 +53,6 @@ static void mtk_pcs_setup_mode_an(struct + static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, + phy_interface_t interface) + { +- unsigned int rgc3; +- +- if (interface == PHY_INTERFACE_MODE_2500BASEX) +- rgc3 = RG_PHY_SPEED_3_125G; +- +- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, +- RG_PHY_SPEED_3_125G, rgc3); +- + /* Disable SGMII AN */ + regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, + SGMII_AN_ENABLE, 0); +@@ -77,6 +69,16 @@ static int mtk_pcs_config(struct phylink + bool permit_pause_to_mac) + { + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); ++ unsigned int rgc3; ++ ++ if (interface == PHY_INTERFACE_MODE_2500BASEX) ++ rgc3 = RG_PHY_SPEED_3_125G; ++ else ++ rgc3 = 0; ++ ++ /* Configure the underlying interface speed */ ++ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, ++ RG_PHY_SPEED_3_125G, rgc3); + + /* Setup SGMIISYS with the determined property */ + if (interface != PHY_INTERFACE_MODE_SGMII) diff --git a/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch b/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch new file mode 100644 index 000000000..f08358e96 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch @@ -0,0 +1,52 @@ +From c125c66ea71b9377ae2478c4f1b87b180cc5c6ef Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:11:18 +0100 +Subject: [PATCH 08/10] net: mtk_eth_soc: add advertisement programming + +Program the advertisement into the mtk PCS block. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -70,16 +70,27 @@ static int mtk_pcs_config(struct phylink + { + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); + unsigned int rgc3; ++ int advertise; ++ bool changed; + + if (interface == PHY_INTERFACE_MODE_2500BASEX) + rgc3 = RG_PHY_SPEED_3_125G; + else + rgc3 = 0; + ++ advertise = phylink_mii_c22_pcs_encode_advertisement(interface, ++ advertising); ++ if (advertise < 0) ++ return advertise; ++ + /* Configure the underlying interface speed */ + regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, + RG_PHY_SPEED_3_125G, rgc3); + ++ /* Update the advertisement, noting whether it has changed */ ++ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, ++ SGMII_ADVERTISE, advertise, &changed); ++ + /* Setup SGMIISYS with the determined property */ + if (interface != PHY_INTERFACE_MODE_SGMII) + mtk_pcs_setup_mode_force(mpcs, interface); +@@ -90,7 +101,7 @@ static int mtk_pcs_config(struct phylink + regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, + SGMII_PHYA_PWD, 0); + +- return 0; ++ return changed; + } + + static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch b/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch new file mode 100644 index 000000000..602d52c6f --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch @@ -0,0 +1,63 @@ +From 3027d89f87707e7f3e5b683e0d37a32afb5bde96 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:11:23 +0100 +Subject: [PATCH 09/10] net: mtk_eth_soc: move and correct link timer + programming + +Program the link timer appropriately for the interface mode being +used, using the newly introduced phylink helper that provides the +nanosecond link timer interval. + +The intervals are 1.6ms for SGMII based protocols and 10ms for +802.3z based protocols. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -36,10 +36,6 @@ static void mtk_pcs_get_state(struct phy + /* For SGMII interface mode */ + static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) + { +- /* Setup the link timer and QPHY power up inside SGMIISYS */ +- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, +- SGMII_LINK_TIMER_DEFAULT); +- + regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, + SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); + +@@ -69,8 +65,8 @@ static int mtk_pcs_config(struct phylink + bool permit_pause_to_mac) + { + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); ++ int advertise, link_timer; + unsigned int rgc3; +- int advertise; + bool changed; + + if (interface == PHY_INTERFACE_MODE_2500BASEX) +@@ -83,6 +79,10 @@ static int mtk_pcs_config(struct phylink + if (advertise < 0) + return advertise; + ++ link_timer = phylink_get_link_timer_ns(interface); ++ if (link_timer < 0) ++ return link_timer; ++ + /* Configure the underlying interface speed */ + regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, + RG_PHY_SPEED_3_125G, rgc3); +@@ -91,6 +91,9 @@ static int mtk_pcs_config(struct phylink + regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, + SGMII_ADVERTISE, advertise, &changed); + ++ /* Setup the link timer and QPHY power up inside SGMIISYS */ ++ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); ++ + /* Setup SGMIISYS with the determined property */ + if (interface != PHY_INTERFACE_MODE_SGMII) + mtk_pcs_setup_mode_force(mpcs, interface); diff --git a/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch b/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch new file mode 100644 index 000000000..0e9a0535a --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch @@ -0,0 +1,132 @@ +From 81b0f12a2a8a1699a7d49c3995e5f71e4ec018e6 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Thu, 27 Oct 2022 14:11:28 +0100 +Subject: [PATCH 10/10] net: mtk_eth_soc: add support for in-band 802.3z + negotiation + +As a result of help from Frank Wunderlich to investigate and test, we +now know how to program this PCS for in-band 802.3z negotiation. Add +support for this by moving the contents of the two functions into the +common mtk_pcs_config() function and adding the register settings for +802.3z negotiation. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 77 ++++++++++++----------- + 1 file changed, 42 insertions(+), 35 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -33,41 +33,15 @@ static void mtk_pcs_get_state(struct phy + FIELD_GET(SGMII_LPA, adv)); + } + +-/* For SGMII interface mode */ +-static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) +-{ +- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, +- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); +- +- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, +- SGMII_AN_RESTART, SGMII_AN_RESTART); +-} +- +-/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a +- * fixed speed. +- */ +-static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, +- phy_interface_t interface) +-{ +- /* Disable SGMII AN */ +- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, +- SGMII_AN_ENABLE, 0); +- +- /* Set the speed etc but leave the duplex unchanged */ +- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, +- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, +- SGMII_SPEED_1000); +-} +- + static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, + phy_interface_t interface, + const unsigned long *advertising, + bool permit_pause_to_mac) + { + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); ++ unsigned int rgc3, sgm_mode, bmcr; + int advertise, link_timer; +- unsigned int rgc3; +- bool changed; ++ bool changed, use_an; + + if (interface == PHY_INTERFACE_MODE_2500BASEX) + rgc3 = RG_PHY_SPEED_3_125G; +@@ -83,6 +57,37 @@ static int mtk_pcs_config(struct phylink + if (link_timer < 0) + return link_timer; + ++ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and ++ * we assume that fixes it's speed at bitrate = line rate (in ++ * other words, 1000Mbps or 2500Mbps). ++ */ ++ if (interface == PHY_INTERFACE_MODE_SGMII) { ++ sgm_mode = SGMII_IF_MODE_SGMII; ++ if (phylink_autoneg_inband(mode)) { ++ sgm_mode |= SGMII_REMOTE_FAULT_DIS | ++ SGMII_SPEED_DUPLEX_AN; ++ use_an = true; ++ } else { ++ use_an = false; ++ } ++ } else if (phylink_autoneg_inband(mode)) { ++ /* 1000base-X or 2500base-X autoneg */ ++ sgm_mode = SGMII_REMOTE_FAULT_DIS; ++ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, ++ advertising); ++ } else { ++ /* 1000base-X or 2500base-X without autoneg */ ++ sgm_mode = 0; ++ use_an = false; ++ } ++ ++ if (use_an) { ++ /* FIXME: Do we need to set AN_RESTART here? */ ++ bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE; ++ } else { ++ bmcr = 0; ++ } ++ + /* Configure the underlying interface speed */ + regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, + RG_PHY_SPEED_3_125G, rgc3); +@@ -94,11 +99,14 @@ static int mtk_pcs_config(struct phylink + /* Setup the link timer and QPHY power up inside SGMIISYS */ + regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); + +- /* Setup SGMIISYS with the determined property */ +- if (interface != PHY_INTERFACE_MODE_SGMII) +- mtk_pcs_setup_mode_force(mpcs, interface); +- else if (phylink_autoneg_inband(mode)) +- mtk_pcs_setup_mode_an(mpcs); ++ /* Update the sgmsys mode register */ ++ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, ++ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | ++ SGMII_IF_MODE_SGMII, sgm_mode); ++ ++ /* Update the BMCR */ ++ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, ++ SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); + + /* Release PHYA power down state */ + regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, +@@ -121,8 +129,7 @@ static void mtk_pcs_link_up(struct phyli + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); + unsigned int sgm_mode; + +- if (!phylink_autoneg_inband(mode) || +- phy_interface_mode_is_8023z(interface)) { ++ if (!phylink_autoneg_inband(mode)) { + /* Force the speed and duplex setting */ + if (speed == SPEED_10) + sgm_mode = SGMII_SPEED_10; diff --git a/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch b/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch new file mode 100644 index 000000000..7db59ad87 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch @@ -0,0 +1,119 @@ +From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001 +From: Alexander Couzens +Date: Wed, 1 Feb 2023 19:23:29 +0100 +Subject: [PATCH 11/13] net: mediatek: sgmii: ensure the SGMII PHY is powered + down on configuration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The code expect the PHY to be in power down which is only true after reset. +Allow changes of the SGMII parameters more than once. + +Only power down when reconfiguring to avoid bouncing the link when there's +no reason to - based on code from Russell King. + +There are cases when the SGMII_PHYA_PWD register contains 0x9 which +prevents SGMII from working. The SGMII still shows link but no traffic +can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was +taken from a good working state of the SGMII interface. + +Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC") +Suggested-by: Russell King (Oracle) +Signed-off-by: Alexander Couzens +[ bmork: rebased and squashed into one patch ] +Reviewed-by: Russell King (Oracle) +Signed-off-by: Bjørn Mork +Acked-by: Daniel Golle +Tested-by: Daniel Golle +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++ + drivers/net/ethernet/mediatek/mtk_sgmii.c | 39 +++++++++++++++------ + 2 files changed, 30 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1073,11 +1073,13 @@ struct mtk_soc_data { + * @regmap: The register map pointing at the range used to setup + * SGMII modes + * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap ++ * @interface: Currently configured interface mode + * @pcs: Phylink PCS structure + */ + struct mtk_pcs { + struct regmap *regmap; + u32 ana_rgc3; ++ phy_interface_t interface; + struct phylink_pcs pcs; + }; + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -43,11 +43,6 @@ static int mtk_pcs_config(struct phylink + int advertise, link_timer; + bool changed, use_an; + +- if (interface == PHY_INTERFACE_MODE_2500BASEX) +- rgc3 = RG_PHY_SPEED_3_125G; +- else +- rgc3 = 0; +- + advertise = phylink_mii_c22_pcs_encode_advertisement(interface, + advertising); + if (advertise < 0) +@@ -88,9 +83,22 @@ static int mtk_pcs_config(struct phylink + bmcr = 0; + } + +- /* Configure the underlying interface speed */ +- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, +- RG_PHY_SPEED_3_125G, rgc3); ++ if (mpcs->interface != interface) { ++ /* PHYA power down */ ++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, ++ SGMII_PHYA_PWD, SGMII_PHYA_PWD); ++ ++ if (interface == PHY_INTERFACE_MODE_2500BASEX) ++ rgc3 = RG_PHY_SPEED_3_125G; ++ else ++ rgc3 = 0; ++ ++ /* Configure the underlying interface speed */ ++ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, ++ RG_PHY_SPEED_3_125G, rgc3); ++ ++ mpcs->interface = interface; ++ } + + /* Update the advertisement, noting whether it has changed */ + regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, +@@ -108,9 +116,17 @@ static int mtk_pcs_config(struct phylink + regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, + SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); + +- /* Release PHYA power down state */ +- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, +- SGMII_PHYA_PWD, 0); ++ /* Release PHYA power down state ++ * Only removing bit SGMII_PHYA_PWD isn't enough. ++ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which ++ * prevents SGMII from working. The SGMII still shows link but no traffic ++ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was ++ * taken from a good working state of the SGMII interface. ++ * Unknown how much the QPHY needs but it is racy without a sleep. ++ * Tested on mt7622 & mt7986. ++ */ ++ usleep_range(50, 100); ++ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); + + return changed; + } +@@ -171,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, + return PTR_ERR(ss->pcs[i].regmap); + + ss->pcs[i].pcs.ops = &mtk_pcs_ops; ++ ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; + } + + return 0; diff --git a/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch b/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch new file mode 100644 index 000000000..a06298c0a --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch @@ -0,0 +1,52 @@ +From 9d32637122de88f1ef614c29703f0e050cad342e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Wed, 1 Feb 2023 19:23:30 +0100 +Subject: [PATCH 12/13] net: mediatek: sgmii: fix duplex configuration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The logic of the duplex bit is inverted. Setting it means half +duplex, not full duplex. + +Fix and rename macro to avoid confusion. + +Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") +Reviewed-by: Russell King (Oracle) +Signed-off-by: Bjørn Mork +Acked-by: Daniel Golle +Tested-by: Daniel Golle +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -534,7 +534,7 @@ + #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) + #define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) + #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) +-#define SGMII_DUPLEX_FULL BIT(4) ++#define SGMII_DUPLEX_HALF BIT(4) + #define SGMII_IF_MODE_BIT5 BIT(5) + #define SGMII_REMOTE_FAULT_DIS BIT(8) + #define SGMII_CODE_SYNC_SET_VAL BIT(9) +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -154,11 +154,11 @@ static void mtk_pcs_link_up(struct phyli + else + sgm_mode = SGMII_SPEED_1000; + +- if (duplex == DUPLEX_FULL) +- sgm_mode |= SGMII_DUPLEX_FULL; ++ if (duplex != DUPLEX_FULL) ++ sgm_mode |= SGMII_DUPLEX_HALF; + + regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, +- SGMII_DUPLEX_FULL | SGMII_SPEED_MASK, ++ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, + sgm_mode); + } + } diff --git a/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch b/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch new file mode 100644 index 000000000..56d7a1348 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch @@ -0,0 +1,33 @@ +From 3337a6e04ddf2923a1bdcf3d31b3b52412bf82dd Mon Sep 17 00:00:00 2001 +From: Alexander Couzens +Date: Wed, 1 Feb 2023 19:23:31 +0100 +Subject: [PATCH 13/13] mtk_sgmii: enable PCS polling to allow SFP work +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently there is no IRQ handling (even the SGMII supports it). +Enable polling to support SFP ports. + +Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs") +Reviewed-by: Russell King (Oracle) +Signed-off-by: Alexander Couzens +[ bmork: changed "1" => "true" ] +Signed-off-by: Bjørn Mork +Acked-by: Daniel Golle +Tested-by: Daniel Golle +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -187,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, + return PTR_ERR(ss->pcs[i].regmap); + + ss->pcs[i].pcs.ops = &mtk_pcs_ops; ++ ss->pcs[i].pcs.poll = true; + ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; + } + diff --git a/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch b/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch new file mode 100644 index 000000000..6acc62d4a --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch @@ -0,0 +1,48 @@ +From 611e2dabb4b3243d176739fd6a5a34d007fa3f86 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 14 Mar 2023 00:34:26 +0000 +Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: reset PCS state +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reset the internal PCS state machine when changing interface mode. +This prevents confusing the state machine when changing interface +modes, e.g. from SGMII to 2500Base-X or vice-versa. + +Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") +Reviewed-by: Russell King (Oracle) +Tested-by: Bjørn Mork +Signed-off-by: Daniel Golle +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++ + drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++ + 2 files changed, 8 insertions(+) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -542,6 +542,10 @@ + #define SGMII_SEND_AN_ERROR_EN BIT(11) + #define SGMII_IF_MODE_MASK GENMASK(5, 1) + ++/* Register to reset SGMII design */ ++#define SGMII_RESERVED_0 0x34 ++#define SGMII_SW_RESET BIT(0) ++ + /* Register to set SGMII speed, ANA RG_ Control Signals III*/ + #define SGMSYS_ANA_RG_CS3 0x2028 + #define RG_PHY_SPEED_MASK (BIT(2) | BIT(3)) +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink + regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, + SGMII_PHYA_PWD, SGMII_PHYA_PWD); + ++ /* Reset SGMII PCS state */ ++ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, ++ SGMII_SW_RESET, SGMII_SW_RESET); ++ + if (interface == PHY_INTERFACE_MODE_2500BASEX) + rgc3 = RG_PHY_SPEED_3_125G; + else diff --git a/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch b/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch new file mode 100644 index 000000000..0fabeea20 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch @@ -0,0 +1,103 @@ +From 6e933a804c7db8be64f367f33e63cd7dcc302ebb Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 14 Mar 2023 00:34:45 +0000 +Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: only write values if needed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Only restart auto-negotiation and write link timer if actually +necessary. This prevents losing the link in case of minor +changes. + +Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") +Reviewed-by: Russell King (Oracle) +Tested-by: Bjørn Mork +Signed-off-by: Daniel Golle +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink + const unsigned long *advertising, + bool permit_pause_to_mac) + { ++ bool mode_changed = false, changed, use_an; + struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); + unsigned int rgc3, sgm_mode, bmcr; + int advertise, link_timer; +- bool changed, use_an; + + advertise = phylink_mii_c22_pcs_encode_advertisement(interface, + advertising); + if (advertise < 0) + return advertise; + +- link_timer = phylink_get_link_timer_ns(interface); +- if (link_timer < 0) +- return link_timer; +- + /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and + * we assume that fixes it's speed at bitrate = line rate (in + * other words, 1000Mbps or 2500Mbps). +@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink + } + + if (use_an) { +- /* FIXME: Do we need to set AN_RESTART here? */ +- bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE; ++ bmcr = SGMII_AN_ENABLE; + } else { + bmcr = 0; + } + + if (mpcs->interface != interface) { ++ link_timer = phylink_get_link_timer_ns(interface); ++ if (link_timer < 0) ++ return link_timer; ++ + /* PHYA power down */ + regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, + SGMII_PHYA_PWD, SGMII_PHYA_PWD); +@@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink + regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, + RG_PHY_SPEED_3_125G, rgc3); + ++ /* Setup the link timer */ ++ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); ++ + mpcs->interface = interface; ++ mode_changed = true; + } + + /* Update the advertisement, noting whether it has changed */ + regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, + SGMII_ADVERTISE, advertise, &changed); + +- /* Setup the link timer and QPHY power up inside SGMIISYS */ +- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); +- + /* Update the sgmsys mode register */ + regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, + SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | +@@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink + + /* Update the BMCR */ + regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, +- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); ++ SGMII_AN_ENABLE, bmcr); + + /* Release PHYA power down state + * Only removing bit SGMII_PHYA_PWD isn't enough. +@@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink + usleep_range(50, 100); + regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); + +- return changed; ++ return changed || mode_changed; + } + + static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch b/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch new file mode 100644 index 000000000..1e3f2fb29 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch @@ -0,0 +1,200 @@ +From f5d43ddd334b7c32fcaed9ba46afbd85cb467f1f Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 19 Mar 2023 12:56:28 +0000 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for MT7981 SoC + +The MediaTek MT7981 SoC comes with two 1G/2.5G SGMII ports, just like +MT7986. + +In addition MT7981 is equipped with a built-in 1000Base-T PHY which can +be used with GMAC1. + +As many MT7981 boards make use of inverting SGMII signal polarity, add +new device-tree attribute 'mediatek,pn_swap' to support them. + +Signed-off-by: Daniel Golle +Signed-off-by: Jakub Kicinski + +--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c +@@ -96,12 +96,20 @@ static int set_mux_gmac2_gmac0_to_gephy( + + static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path) + { +- unsigned int val = 0; ++ unsigned int val = 0, mask = 0, reg = 0; + bool updated = true; + + switch (path) { + case MTK_ETH_PATH_GMAC2_SGMII: +- val = CO_QPHY_SEL; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) { ++ reg = USB_PHY_SWITCH_REG; ++ val = SGMII_QPHY_SEL; ++ mask = QPHY_SEL_MASK; ++ } else { ++ reg = INFRA_MISC2; ++ val = CO_QPHY_SEL; ++ mask = val; ++ } + break; + default: + updated = false; +@@ -109,7 +117,7 @@ static int set_mux_u3_gmac2_to_qphy(stru + } + + if (updated) +- regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val); ++ regmap_update_bits(eth->infra, reg, mask, val); + + dev_dbg(eth->dev, "path %s in %s updated = %d\n", + mtk_eth_path_name(path), __func__, updated); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4808,6 +4808,26 @@ static const struct mtk_soc_data mt7629_ + }, + }; + ++static const struct mtk_soc_data mt7981_data = { ++ .reg_map = &mt7986_reg_map, ++ .ana_rgc3 = 0x128, ++ .caps = MT7981_CAPS, ++ .hw_features = MTK_HW_FEATURES, ++ .required_clks = MT7981_CLKS_BITMAP, ++ .required_pctl = false, ++ .offload_version = 2, ++ .hash_offset = 4, ++ .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .txrx = { ++ .txd_size = sizeof(struct mtk_tx_dma_v2), ++ .rxd_size = sizeof(struct mtk_rx_dma_v2), ++ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, ++ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, ++ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, ++ .dma_len_offset = 8, ++ }, ++}; ++ + static const struct mtk_soc_data mt7986_data = { + .reg_map = &mt7986_reg_map, + .ana_rgc3 = 0x128, +@@ -4849,6 +4869,7 @@ const struct of_device_id of_mtk_match[] + { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, + { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, + { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, ++ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, + { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, + { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, + {}, +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -556,11 +556,22 @@ + #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 + #define SGMII_PHYA_PWD BIT(4) + ++/* Register to QPHY wrapper control */ ++#define SGMSYS_QPHY_WRAP_CTRL 0xec ++#define SGMII_PN_SWAP_MASK GENMASK(1, 0) ++#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) ++#define MTK_SGMII_FLAG_PN_SWAP BIT(0) ++ + /* Infrasys subsystem config registers */ + #define INFRA_MISC2 0x70c + #define CO_QPHY_SEL BIT(0) + #define GEPHY_MAC_SEL BIT(1) + ++/* Top misc registers */ ++#define USB_PHY_SWITCH_REG 0x218 ++#define QPHY_SEL_MASK GENMASK(1, 0) ++#define SGMII_QPHY_SEL 0x2 ++ + /* MT7628/88 specific stuff */ + #define MT7628_PDMA_OFFSET 0x0800 + #define MT7628_SDM_OFFSET 0x0c00 +@@ -741,6 +752,17 @@ enum mtk_clks_map { + BIT(MTK_CLK_SGMII2_CDR_FB) | \ + BIT(MTK_CLK_SGMII_CK) | \ + BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) ++#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ ++ BIT(MTK_CLK_WOCPU0) | \ ++ BIT(MTK_CLK_SGMII_TX_250M) | \ ++ BIT(MTK_CLK_SGMII_RX_250M) | \ ++ BIT(MTK_CLK_SGMII_CDR_REF) | \ ++ BIT(MTK_CLK_SGMII_CDR_FB) | \ ++ BIT(MTK_CLK_SGMII2_TX_250M) | \ ++ BIT(MTK_CLK_SGMII2_RX_250M) | \ ++ BIT(MTK_CLK_SGMII2_CDR_REF) | \ ++ BIT(MTK_CLK_SGMII2_CDR_FB) | \ ++ BIT(MTK_CLK_SGMII_CK)) + #define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ + BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ + BIT(MTK_CLK_SGMII_TX_250M) | \ +@@ -854,6 +876,7 @@ enum mkt_eth_capabilities { + MTK_NETSYS_V2_BIT, + MTK_SOC_MT7628_BIT, + MTK_RSTCTRL_PPE1_BIT, ++ MTK_U3_COPHY_V2_BIT, + + /* MUX BITS*/ + MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, +@@ -888,6 +911,7 @@ enum mkt_eth_capabilities { + #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) + #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) + #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) ++#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) + + #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ + BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) +@@ -966,6 +990,11 @@ enum mkt_eth_capabilities { + MTK_MUX_U3_GMAC2_TO_QPHY | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) + ++#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ ++ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ ++ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ ++ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) ++ + #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ + MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ + MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) +@@ -1079,12 +1108,14 @@ struct mtk_soc_data { + * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap + * @interface: Currently configured interface mode + * @pcs: Phylink PCS structure ++ * @flags: Flags indicating hardware properties + */ + struct mtk_pcs { + struct regmap *regmap; + u32 ana_rgc3; + phy_interface_t interface; + struct phylink_pcs pcs; ++ u32 flags; + }; + + /* struct mtk_sgmii - This is the structure holding sgmii regmap and its +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c +@@ -87,6 +87,11 @@ static int mtk_pcs_config(struct phylink + regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, + SGMII_PHYA_PWD, SGMII_PHYA_PWD); + ++ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) ++ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, ++ SGMII_PN_SWAP_MASK, ++ SGMII_PN_SWAP_TX_RX); ++ + /* Reset SGMII PCS state */ + regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, + SGMII_SW_RESET, SGMII_SW_RESET); +@@ -186,6 +191,11 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, + + ss->pcs[i].ana_rgc3 = ana_rgc3; + ss->pcs[i].regmap = syscon_node_to_regmap(np); ++ ++ ss->pcs[i].flags = 0; ++ if (of_property_read_bool(np, "mediatek,pnswap")) ++ ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP; ++ + of_node_put(np); + if (IS_ERR(ss->pcs[i].regmap)) + return PTR_ERR(ss->pcs[i].regmap); diff --git a/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch b/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch new file mode 100644 index 000000000..ea20bd87f --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch @@ -0,0 +1,76 @@ +From c0a440031d4314d1023c1b87f43a4233634eebdb Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 19 Mar 2023 12:57:15 +0000 +Subject: [PATCH] net: ethernet: mtk_eth_soc: set MDIO bus clock frequency +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Set MDIO bus clock frequency and allow setting a custom maximum +frequency from device tree. + +Reviewed-by: Andrew Lunn +Reviewed-by: Florian Fainelli +Tested-by: Bjørn Mork +Signed-off-by: Daniel Golle +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++++ + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 +++++++ + 2 files changed, 28 insertions(+) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -745,8 +745,10 @@ static const struct phylink_mac_ops mtk_ + + static int mtk_mdio_init(struct mtk_eth *eth) + { ++ unsigned int max_clk = 2500000, divider; + struct device_node *mii_np; + int ret; ++ u32 val; + + mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus"); + if (!mii_np) { +@@ -773,6 +775,25 @@ static int mtk_mdio_init(struct mtk_eth + eth->mii_bus->parent = eth->dev; + + snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np); ++ ++ if (!of_property_read_u32(mii_np, "clock-frequency", &val)) { ++ if (val > MDC_MAX_FREQ || val < MDC_MAX_FREQ / MDC_MAX_DIVIDER) { ++ dev_err(eth->dev, "MDIO clock frequency out of range"); ++ ret = -EINVAL; ++ goto err_put_node; ++ } ++ max_clk = val; ++ } ++ divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); ++ ++ /* Configure MDC Divider */ ++ val = mtk_r32(eth, MTK_PPSC); ++ val &= ~PPSC_MDC_CFG; ++ val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; ++ mtk_w32(eth, val, MTK_PPSC); ++ ++ dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); ++ + ret = of_mdiobus_register(eth->mii_bus, mii_np); + + err_put_node: +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -363,6 +363,13 @@ + #define RX_DMA_VTAG_V2 BIT(0) + #define RX_DMA_L4_VALID_V2 BIT(2) + ++/* PHY Polling and SMI Master Control registers */ ++#define MTK_PPSC 0x10000 ++#define PPSC_MDC_CFG GENMASK(29, 24) ++#define PPSC_MDC_TURBO BIT(20) ++#define MDC_MAX_FREQ 25000000 ++#define MDC_MAX_DIVIDER 63 ++ + /* PHY Indirect Access Control registers */ + #define MTK_PHY_IAC 0x10004 + #define PHY_IAC_ACCESS BIT(31) diff --git a/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch b/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch new file mode 100644 index 000000000..7a04753ce --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch @@ -0,0 +1,512 @@ +From 2a3ec7ae313310c1092e4256208cc04d1958e469 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 19 Mar 2023 12:58:02 +0000 +Subject: [PATCH] net: ethernet: mtk_eth_soc: switch to external PCS driver + +Now that we got a PCS driver, use it and remove the now redundant +PCS code and it's header macros from the Ethernet driver. + +Signed-off-by: Daniel Golle +Tested-by: Frank Wunderlich +Reviewed-by: Russell King (Oracle) +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/Kconfig | 2 + + drivers/net/ethernet/mediatek/Makefile | 2 +- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 61 +++++- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +-------- + drivers/net/ethernet/mediatek/mtk_sgmii.c | 217 -------------------- + 5 files changed, 56 insertions(+), 319 deletions(-) + delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c + +--- a/drivers/net/ethernet/mediatek/Kconfig ++++ b/drivers/net/ethernet/mediatek/Kconfig +@@ -19,6 +19,8 @@ config NET_MEDIATEK_SOC + select DIMLIB + select PAGE_POOL + select PAGE_POOL_STATS ++ select PCS_MTK_LYNXI ++ select REGMAP_MMIO + help + This driver supports the gigabit ethernet MACs in the + MediaTek SoC family. +--- a/drivers/net/ethernet/mediatek/Makefile ++++ b/drivers/net/ethernet/mediatek/Makefile +@@ -4,7 +4,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-y := mtk_eth_soc.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_wed_wo.o + ifdef CONFIG_DEBUG_FS + mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -400,7 +401,7 @@ static struct phylink_pcs *mtk_mac_selec + sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? + 0 : mac->id; + +- return mtk_sgmii_select_pcs(eth->sgmii, sid); ++ return eth->sgmii_pcs[sid]; + } + + return NULL; +@@ -4031,8 +4032,17 @@ static int mtk_unreg_dev(struct mtk_eth + return 0; + } + ++static void mtk_sgmii_destroy(struct mtk_eth *eth) ++{ ++ int i; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) ++ mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]); ++} ++ + static int mtk_cleanup(struct mtk_eth *eth) + { ++ mtk_sgmii_destroy(eth); + mtk_unreg_dev(eth); + mtk_free_dev(eth); + cancel_work_sync(ð->pending_work); +@@ -4462,6 +4472,36 @@ void mtk_eth_set_dma_device(struct mtk_e + rtnl_unlock(); + } + ++static int mtk_sgmii_init(struct mtk_eth *eth) ++{ ++ struct device_node *np; ++ struct regmap *regmap; ++ u32 flags; ++ int i; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i); ++ if (!np) ++ break; ++ ++ regmap = syscon_node_to_regmap(np); ++ flags = 0; ++ if (of_property_read_bool(np, "mediatek,pnswap")) ++ flags |= MTK_SGMII_FLAG_PN_SWAP; ++ ++ of_node_put(np); ++ ++ if (IS_ERR(regmap)) ++ return PTR_ERR(regmap); ++ ++ eth->sgmii_pcs[i] = mtk_pcs_lynxi_create(eth->dev, regmap, ++ eth->soc->ana_rgc3, ++ flags); ++ } ++ ++ return 0; ++} ++ + static int mtk_probe(struct platform_device *pdev) + { + struct resource *res = NULL; +@@ -4525,13 +4565,7 @@ static int mtk_probe(struct platform_dev + } + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { +- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii), +- GFP_KERNEL); +- if (!eth->sgmii) +- return -ENOMEM; +- +- err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node, +- eth->soc->ana_rgc3); ++ err = mtk_sgmii_init(eth); + + if (err) + return err; +@@ -4542,14 +4576,17 @@ static int mtk_probe(struct platform_dev + "mediatek,pctl"); + if (IS_ERR(eth->pctl)) { + dev_err(&pdev->dev, "no pctl regmap found\n"); +- return PTR_ERR(eth->pctl); ++ err = PTR_ERR(eth->pctl); ++ goto err_destroy_sgmii; + } + } + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) +- return -EINVAL; ++ if (!res) { ++ err = -EINVAL; ++ goto err_destroy_sgmii; ++ } + } + + if (eth->soc->offload_version) { +@@ -4708,6 +4745,8 @@ err_deinit_hw: + mtk_hw_deinit(eth); + err_wed_exit: + mtk_wed_exit(); ++err_destroy_sgmii: ++ mtk_sgmii_destroy(eth); + + return err; + } +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -510,65 +510,6 @@ + #define ETHSYS_DMA_AG_MAP_QDMA BIT(1) + #define ETHSYS_DMA_AG_MAP_PPE BIT(2) + +-/* SGMII subsystem config registers */ +-/* BMCR (low 16) BMSR (high 16) */ +-#define SGMSYS_PCS_CONTROL_1 0x0 +-#define SGMII_BMCR GENMASK(15, 0) +-#define SGMII_BMSR GENMASK(31, 16) +-#define SGMII_AN_RESTART BIT(9) +-#define SGMII_ISOLATE BIT(10) +-#define SGMII_AN_ENABLE BIT(12) +-#define SGMII_LINK_STATYS BIT(18) +-#define SGMII_AN_ABILITY BIT(19) +-#define SGMII_AN_COMPLETE BIT(21) +-#define SGMII_PCS_FAULT BIT(23) +-#define SGMII_AN_EXPANSION_CLR BIT(30) +- +-#define SGMSYS_PCS_ADVERTISE 0x8 +-#define SGMII_ADVERTISE GENMASK(15, 0) +-#define SGMII_LPA GENMASK(31, 16) +- +-/* Register to programmable link timer, the unit in 2 * 8ns */ +-#define SGMSYS_PCS_LINK_TIMER 0x18 +-#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) +-#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK) +- +-/* Register to control remote fault */ +-#define SGMSYS_SGMII_MODE 0x20 +-#define SGMII_IF_MODE_SGMII BIT(0) +-#define SGMII_SPEED_DUPLEX_AN BIT(1) +-#define SGMII_SPEED_MASK GENMASK(3, 2) +-#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) +-#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) +-#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) +-#define SGMII_DUPLEX_HALF BIT(4) +-#define SGMII_IF_MODE_BIT5 BIT(5) +-#define SGMII_REMOTE_FAULT_DIS BIT(8) +-#define SGMII_CODE_SYNC_SET_VAL BIT(9) +-#define SGMII_CODE_SYNC_SET_EN BIT(10) +-#define SGMII_SEND_AN_ERROR_EN BIT(11) +-#define SGMII_IF_MODE_MASK GENMASK(5, 1) +- +-/* Register to reset SGMII design */ +-#define SGMII_RESERVED_0 0x34 +-#define SGMII_SW_RESET BIT(0) +- +-/* Register to set SGMII speed, ANA RG_ Control Signals III*/ +-#define SGMSYS_ANA_RG_CS3 0x2028 +-#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3)) +-#define RG_PHY_SPEED_1_25G 0x0 +-#define RG_PHY_SPEED_3_125G BIT(2) +- +-/* Register to power up QPHY */ +-#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 +-#define SGMII_PHYA_PWD BIT(4) +- +-/* Register to QPHY wrapper control */ +-#define SGMSYS_QPHY_WRAP_CTRL 0xec +-#define SGMII_PN_SWAP_MASK GENMASK(1, 0) +-#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) +-#define MTK_SGMII_FLAG_PN_SWAP BIT(0) +- + /* Infrasys subsystem config registers */ + #define INFRA_MISC2 0x70c + #define CO_QPHY_SEL BIT(0) +@@ -1108,31 +1049,6 @@ struct mtk_soc_data { + /* currently no SoC has more than 2 macs */ + #define MTK_MAX_DEVS 2 + +-/* struct mtk_pcs - This structure holds each sgmii regmap and associated +- * data +- * @regmap: The register map pointing at the range used to setup +- * SGMII modes +- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap +- * @interface: Currently configured interface mode +- * @pcs: Phylink PCS structure +- * @flags: Flags indicating hardware properties +- */ +-struct mtk_pcs { +- struct regmap *regmap; +- u32 ana_rgc3; +- phy_interface_t interface; +- struct phylink_pcs pcs; +- u32 flags; +-}; +- +-/* struct mtk_sgmii - This is the structure holding sgmii regmap and its +- * characteristics +- * @pcs Array of individual PCS structures +- */ +-struct mtk_sgmii { +- struct mtk_pcs pcs[MTK_MAX_DEVS]; +-}; +- + /* struct mtk_eth - This is the main datasructure for holding the state + * of the driver + * @dev: The device pointer +@@ -1152,6 +1068,7 @@ struct mtk_sgmii { + * MII modes + * @infra: The register map pointing at the range used to setup + * SGMII and GePHY path ++ * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances + * @pctl: The register map pointing at the range used to setup + * GMAC port drive/slew values + * @dma_refcnt: track how many netdevs are using the DMA engine +@@ -1192,8 +1109,8 @@ struct mtk_eth { + u32 msg_enable; + unsigned long sysclk; + struct regmap *ethsys; +- struct regmap *infra; +- struct mtk_sgmii *sgmii; ++ struct regmap *infra; ++ struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS]; + struct regmap *pctl; + bool hwlro; + refcount_t dma_refcnt; +@@ -1355,10 +1272,6 @@ void mtk_stats_update_mac(struct mtk_mac + void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); + u32 mtk_r32(struct mtk_eth *eth, unsigned reg); + +-struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id); +-int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np, +- u32 ana_rgc3); +- + int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); + int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); +--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c ++++ /dev/null +@@ -1,217 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-// Copyright (c) 2018-2019 MediaTek Inc. +- +-/* A library for MediaTek SGMII circuit +- * +- * Author: Sean Wang +- * +- */ +- +-#include +-#include +-#include +-#include +- +-#include "mtk_eth_soc.h" +- +-static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs) +-{ +- return container_of(pcs, struct mtk_pcs, pcs); +-} +- +-static void mtk_pcs_get_state(struct phylink_pcs *pcs, +- struct phylink_link_state *state) +-{ +- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); +- unsigned int bm, adv; +- +- /* Read the BMSR and LPA */ +- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); +- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); +- +- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), +- FIELD_GET(SGMII_LPA, adv)); +-} +- +-static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, +- phy_interface_t interface, +- const unsigned long *advertising, +- bool permit_pause_to_mac) +-{ +- bool mode_changed = false, changed, use_an; +- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); +- unsigned int rgc3, sgm_mode, bmcr; +- int advertise, link_timer; +- +- advertise = phylink_mii_c22_pcs_encode_advertisement(interface, +- advertising); +- if (advertise < 0) +- return advertise; +- +- /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and +- * we assume that fixes it's speed at bitrate = line rate (in +- * other words, 1000Mbps or 2500Mbps). +- */ +- if (interface == PHY_INTERFACE_MODE_SGMII) { +- sgm_mode = SGMII_IF_MODE_SGMII; +- if (phylink_autoneg_inband(mode)) { +- sgm_mode |= SGMII_REMOTE_FAULT_DIS | +- SGMII_SPEED_DUPLEX_AN; +- use_an = true; +- } else { +- use_an = false; +- } +- } else if (phylink_autoneg_inband(mode)) { +- /* 1000base-X or 2500base-X autoneg */ +- sgm_mode = SGMII_REMOTE_FAULT_DIS; +- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, +- advertising); +- } else { +- /* 1000base-X or 2500base-X without autoneg */ +- sgm_mode = 0; +- use_an = false; +- } +- +- if (use_an) { +- bmcr = SGMII_AN_ENABLE; +- } else { +- bmcr = 0; +- } +- +- if (mpcs->interface != interface) { +- link_timer = phylink_get_link_timer_ns(interface); +- if (link_timer < 0) +- return link_timer; +- +- /* PHYA power down */ +- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, +- SGMII_PHYA_PWD, SGMII_PHYA_PWD); +- +- if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) +- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, +- SGMII_PN_SWAP_MASK, +- SGMII_PN_SWAP_TX_RX); +- +- /* Reset SGMII PCS state */ +- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, +- SGMII_SW_RESET, SGMII_SW_RESET); +- +- if (interface == PHY_INTERFACE_MODE_2500BASEX) +- rgc3 = RG_PHY_SPEED_3_125G; +- else +- rgc3 = 0; +- +- /* Configure the underlying interface speed */ +- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, +- RG_PHY_SPEED_3_125G, rgc3); +- +- /* Setup the link timer */ +- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); +- +- mpcs->interface = interface; +- mode_changed = true; +- } +- +- /* Update the advertisement, noting whether it has changed */ +- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, +- SGMII_ADVERTISE, advertise, &changed); +- +- /* Update the sgmsys mode register */ +- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, +- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | +- SGMII_IF_MODE_SGMII, sgm_mode); +- +- /* Update the BMCR */ +- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, +- SGMII_AN_ENABLE, bmcr); +- +- /* Release PHYA power down state +- * Only removing bit SGMII_PHYA_PWD isn't enough. +- * There are cases when the SGMII_PHYA_PWD register contains 0x9 which +- * prevents SGMII from working. The SGMII still shows link but no traffic +- * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was +- * taken from a good working state of the SGMII interface. +- * Unknown how much the QPHY needs but it is racy without a sleep. +- * Tested on mt7622 & mt7986. +- */ +- usleep_range(50, 100); +- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); +- +- return changed || mode_changed; +-} +- +-static void mtk_pcs_restart_an(struct phylink_pcs *pcs) +-{ +- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); +- +- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, +- SGMII_AN_RESTART, SGMII_AN_RESTART); +-} +- +-static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, +- phy_interface_t interface, int speed, int duplex) +-{ +- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); +- unsigned int sgm_mode; +- +- if (!phylink_autoneg_inband(mode)) { +- /* Force the speed and duplex setting */ +- if (speed == SPEED_10) +- sgm_mode = SGMII_SPEED_10; +- else if (speed == SPEED_100) +- sgm_mode = SGMII_SPEED_100; +- else +- sgm_mode = SGMII_SPEED_1000; +- +- if (duplex != DUPLEX_FULL) +- sgm_mode |= SGMII_DUPLEX_HALF; +- +- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, +- SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, +- sgm_mode); +- } +-} +- +-static const struct phylink_pcs_ops mtk_pcs_ops = { +- .pcs_get_state = mtk_pcs_get_state, +- .pcs_config = mtk_pcs_config, +- .pcs_an_restart = mtk_pcs_restart_an, +- .pcs_link_up = mtk_pcs_link_up, +-}; +- +-int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) +-{ +- struct device_node *np; +- int i; +- +- for (i = 0; i < MTK_MAX_DEVS; i++) { +- np = of_parse_phandle(r, "mediatek,sgmiisys", i); +- if (!np) +- break; +- +- ss->pcs[i].ana_rgc3 = ana_rgc3; +- ss->pcs[i].regmap = syscon_node_to_regmap(np); +- +- ss->pcs[i].flags = 0; +- if (of_property_read_bool(np, "mediatek,pnswap")) +- ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP; +- +- of_node_put(np); +- if (IS_ERR(ss->pcs[i].regmap)) +- return PTR_ERR(ss->pcs[i].regmap); +- +- ss->pcs[i].pcs.ops = &mtk_pcs_ops; +- ss->pcs[i].pcs.poll = true; +- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; +- } +- +- return 0; +-} +- +-struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id) +-{ +- if (!ss->pcs[id].regmap) +- return NULL; +- +- return &ss->pcs[id].pcs; +-} diff --git a/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch b/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch new file mode 100644 index 000000000..9ce273595 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch @@ -0,0 +1,46 @@ +From f5af7931d2a2cae66d0f9dad4ba517b1b00620b3 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 19 Apr 2023 19:07:23 +0100 +Subject: [PATCH] net: mtk_eth_soc: use WO firmware for MT7981 + +In order to support wireless offloading on MT7981 we need to load the +appropriate firmware. Recognize MT7981 and load mt7981_wo.bin. + +Signed-off-by: Daniel Golle +--- + drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 7 ++++++- + drivers/net/ethernet/mediatek/mtk_wed_wo.h | 1 + + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c +@@ -326,7 +326,11 @@ mtk_wed_mcu_load_firmware(struct mtk_wed + wo->hw->index + 1); + + /* load firmware */ +- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; ++ if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed")) ++ fw_name = MT7981_FIRMWARE_WO; ++ else ++ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; ++ + ret = request_firmware(&fw, fw_name, wo->hw->dev); + if (ret) + return ret; +@@ -386,5 +390,6 @@ int mtk_wed_mcu_init(struct mtk_wed_wo * + 100, MTK_FW_DL_TIMEOUT); + } + ++MODULE_FIRMWARE(MT7981_FIRMWARE_WO); + MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); + MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h +@@ -88,6 +88,7 @@ enum mtk_wed_dummy_cr_idx { + MTK_WED_DUMMY_CR_WO_STATUS, + }; + ++#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" + #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" + #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" + diff --git a/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch b/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch new file mode 100644 index 000000000..d715c4aa6 --- /dev/null +++ b/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch @@ -0,0 +1,28 @@ +From 7c83e28f10830aa5105c25eaabe890e3adac36aa Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 9 May 2023 03:20:06 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix NULL pointer dereference + +Check for NULL pointer to avoid kernel crashing in case of missing WO +firmware in case only a single WEDv2 device has been initialized, e.g. on +MT7981 which can connect just one wireless frontend. + +Fixes: 86ce0d09e424 ("net: ethernet: mtk_eth_soc: use WO firmware for MT7981") +Signed-off-by: Daniel Golle +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -647,7 +647,7 @@ __mtk_wed_detach(struct mtk_wed_device * + BIT(hw->index), BIT(hw->index)); + } + +- if (!hw_list[!hw->index]->wed_dev && ++ if ((!hw_list[!hw->index] || !hw_list[!hw->index]->wed_dev) && + hw->eth->dma_dev != hw->eth->dev) + mtk_eth_set_dma_device(hw->eth, hw->eth->dev); + diff --git a/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch b/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch new file mode 100644 index 000000000..c0320ad6f --- /dev/null +++ b/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch @@ -0,0 +1,150 @@ +From cfbd6de588ef659c198083205dc954a6d3ed2aec Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 29 Dec 2022 17:33:35 +0100 +Subject: [PATCH 4/5] net: dsa: qca8k: introduce single mii read/write lo/hi + +It may be useful to read/write just the lo or hi half of a reg. + +This is especially useful for phy poll with the use of mdio master. +The mdio master reg is composed by the first 16 bit related to setup and +the other half with the returned data or data to write. + +Refactor the mii function to permit single mii read/write of lo or hi +half of the reg. + +Tested-by: Ronald Wahl +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 106 ++++++++++++++++++++++++------- + 1 file changed, 84 insertions(+), 22 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -37,42 +37,104 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u + } + + static int +-qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) ++qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) + { + int ret; ++ u16 lo; + +- ret = bus->read(bus, phy_id, regnum); +- if (ret >= 0) { +- *val = ret; +- ret = bus->read(bus, phy_id, regnum + 1); +- *val |= ret << 16; +- } ++ lo = val & 0xffff; ++ ret = bus->write(bus, phy_id, regnum, lo); ++ if (ret < 0) ++ dev_err_ratelimited(&bus->dev, ++ "failed to write qca8k 32bit lo register\n"); ++ ++ return ret; ++} + +- if (ret < 0) { ++static int ++qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) ++{ ++ int ret; ++ u16 hi; ++ ++ hi = (u16)(val >> 16); ++ ret = bus->write(bus, phy_id, regnum, hi); ++ if (ret < 0) + dev_err_ratelimited(&bus->dev, +- "failed to read qca8k 32bit register\n"); +- *val = 0; +- return ret; +- } ++ "failed to write qca8k 32bit hi register\n"); + ++ return ret; ++} ++ ++static int ++qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) ++{ ++ int ret; ++ ++ ret = bus->read(bus, phy_id, regnum); ++ if (ret < 0) ++ goto err; ++ ++ *val = ret & 0xffff; + return 0; ++ ++err: ++ dev_err_ratelimited(&bus->dev, ++ "failed to read qca8k 32bit lo register\n"); ++ *val = 0; ++ ++ return ret; + } + +-static void +-qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) ++static int ++qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) + { +- u16 lo, hi; + int ret; + +- lo = val & 0xffff; +- hi = (u16)(val >> 16); ++ ret = bus->read(bus, phy_id, regnum); ++ if (ret < 0) ++ goto err; + +- ret = bus->write(bus, phy_id, regnum, lo); +- if (ret >= 0) +- ret = bus->write(bus, phy_id, regnum + 1, hi); ++ *val = ret << 16; ++ return 0; ++ ++err: ++ dev_err_ratelimited(&bus->dev, ++ "failed to read qca8k 32bit hi register\n"); ++ *val = 0; ++ ++ return ret; ++} ++ ++static int ++qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) ++{ ++ u32 hi, lo; ++ int ret; ++ ++ *val = 0; ++ ++ ret = qca8k_mii_read_lo(bus, phy_id, regnum, &lo); + if (ret < 0) +- dev_err_ratelimited(&bus->dev, +- "failed to write qca8k 32bit register\n"); ++ goto err; ++ ++ ret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, &hi); ++ if (ret < 0) ++ goto err; ++ ++ *val = lo | hi; ++ ++err: ++ return ret; ++} ++ ++static void ++qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) ++{ ++ if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0) ++ return; ++ ++ qca8k_mii_write_hi(bus, phy_id, regnum + 1, val); + } + + static int diff --git a/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch b/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch new file mode 100644 index 000000000..4cbb66cf3 --- /dev/null +++ b/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch @@ -0,0 +1,73 @@ +From a4165830ca237f2b3318faf62562bce8ce12a389 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 29 Dec 2022 17:33:36 +0100 +Subject: [PATCH 5/5] net: dsa: qca8k: improve mdio master read/write by using + single lo/hi + +Improve mdio master read/write by using singe mii read/write lo/hi. + +In a read and write we need to poll the mdio master regs in a busy loop +to check for a specific bit present in the upper half of the reg. We can +ignore the other half since it won't contain useful data. This will save +an additional useless read for each read and write operation. + +In a read operation the returned data is present in the mdio master reg +lower half. We can ignore the other half since it won't contain useful +data. This will save an additional useless read for each read operation. + +In a read operation it's needed to just set the hi half of the mdio +master reg as the lo half will be replaced by the result. This will save +an additional useless write for each read operation. + +Tested-by: Ronald Wahl +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -740,9 +740,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus + + qca8k_split_addr(reg, &r1, &r2, &page); + +- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, ++ ret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val & mask), 0, + QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, +- bus, 0x10 | r2, r1, &val); ++ bus, 0x10 | r2, r1 + 1, &val); + + /* Check if qca8k_read has failed for a different reason + * before returnting -ETIMEDOUT +@@ -784,7 +784,7 @@ qca8k_mdio_write(struct qca8k_priv *priv + + exit: + /* even if the busy_wait timeouts try to clear the MASTER_EN */ +- qca8k_mii_write32(bus, 0x10 | r2, r1, 0); ++ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0); + + mutex_unlock(&bus->mdio_lock); + +@@ -814,18 +814,18 @@ qca8k_mdio_read(struct qca8k_priv *priv, + if (ret) + goto exit; + +- qca8k_mii_write32(bus, 0x10 | r2, r1, val); ++ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, val); + + ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, + QCA8K_MDIO_MASTER_BUSY); + if (ret) + goto exit; + +- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); ++ ret = qca8k_mii_read_lo(bus, 0x10 | r2, r1, &val); + + exit: + /* even if the busy_wait timeouts try to clear the MASTER_EN */ +- qca8k_mii_write32(bus, 0x10 | r2, r1, 0); ++ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0); + + mutex_unlock(&bus->mdio_lock); + diff --git a/target/linux/generic/backport-6.1/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-6.1/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch new file mode 100644 index 000000000..be97c8ac3 --- /dev/null +++ b/target/linux/generic/backport-6.1/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch @@ -0,0 +1,514 @@ +From patchwork Thu Mar 9 10:57:44 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: Daniel Golle +X-Patchwork-Id: 13167235 +X-Patchwork-Delegate: kuba@kernel.org +Return-Path: +Date: Thu, 9 Mar 2023 10:57:44 +0000 +From: Daniel Golle +To: netdev@vger.kernel.org, linux-mediatek@lists.infradead.org, + linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, + Russell King , + Heiner Kallweit , + Lorenzo Bianconi , + Mark Lee , + John Crispin , Felix Fietkau , + AngeloGioacchino Del Regno + , + Matthias Brugger , + DENG Qingfang , + Landen Chao , + Sean Wang , + Paolo Abeni , + Jakub Kicinski , + Eric Dumazet , + "David S. Miller" , + Vladimir Oltean , + Florian Fainelli , + Andrew Lunn , + Vladimir Oltean +Cc: =?iso-8859-1?q?Bj=F8rn?= Mork , + Frank Wunderlich , + Alexander Couzens +Subject: [PATCH net-next v13 11/16] net: dsa: mt7530: use external PCS driver +Message-ID: + <2ac2ee40d3b0e705461b50613fda6a7edfdbc4b3.1678357225.git.daniel@makrotopia.org> +References: +MIME-Version: 1.0 +Content-Disposition: inline +In-Reply-To: +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +Implement regmap access wrappers, for now only to be used by the +pcs-mtk driver. +Make use of external PCS driver and drop the reduntant implementation +in mt7530.c. +As a nice side effect the SGMII registers can now also more easily be +inspected for debugging via /sys/kernel/debug/regmap. + +Reviewed-by: Russell King (Oracle) +Tested-by: Bjørn Mork +Signed-off-by: Daniel Golle +Tested-by: Frank Wunderlich +--- + drivers/net/dsa/Kconfig | 1 + + drivers/net/dsa/mt7530.c | 277 ++++++++++----------------------------- + drivers/net/dsa/mt7530.h | 47 +------ + 3 files changed, 71 insertions(+), 254 deletions(-) + +--- a/drivers/net/dsa/Kconfig ++++ b/drivers/net/dsa/Kconfig +@@ -37,6 +37,7 @@ config NET_DSA_MT7530 + tristate "MediaTek MT753x and MT7621 Ethernet switch support" + select NET_DSA_TAG_MTK + select MEDIATEK_GE_PHY ++ select PCS_MTK_LYNXI + help + This enables support for the MediaTek MT7530, MT7531, and MT7621 + Ethernet switch chips. +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2597,128 +2598,11 @@ static int mt7531_rgmii_setup(struct mt7 + return 0; + } + +-static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, +- phy_interface_t interface, int speed, int duplex) +-{ +- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; +- int port = pcs_to_mt753x_pcs(pcs)->port; +- unsigned int val; +- +- /* For adjusting speed and duplex of SGMII force mode. */ +- if (interface != PHY_INTERFACE_MODE_SGMII || +- phylink_autoneg_inband(mode)) +- return; +- +- /* SGMII force mode setting */ +- val = mt7530_read(priv, MT7531_SGMII_MODE(port)); +- val &= ~MT7531_SGMII_IF_MODE_MASK; +- +- switch (speed) { +- case SPEED_10: +- val |= MT7531_SGMII_FORCE_SPEED_10; +- break; +- case SPEED_100: +- val |= MT7531_SGMII_FORCE_SPEED_100; +- break; +- case SPEED_1000: +- val |= MT7531_SGMII_FORCE_SPEED_1000; +- break; +- } +- +- /* MT7531 SGMII 1G force mode can only work in full duplex mode, +- * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. +- * +- * The speed check is unnecessary as the MAC capabilities apply +- * this restriction. --rmk +- */ +- if ((speed == SPEED_10 || speed == SPEED_100) && +- duplex != DUPLEX_FULL) +- val |= MT7531_SGMII_FORCE_HALF_DUPLEX; +- +- mt7530_write(priv, MT7531_SGMII_MODE(port), val); +-} +- + static bool mt753x_is_mac_port(u32 port) + { + return (port == 5 || port == 6); + } + +-static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port, +- phy_interface_t interface) +-{ +- u32 val; +- +- if (!mt753x_is_mac_port(port)) +- return -EINVAL; +- +- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port), +- MT7531_SGMII_PHYA_PWD); +- +- val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port)); +- val &= ~MT7531_RG_TPHY_SPEED_MASK; +- /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B +- * encoding. +- */ +- val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ? +- MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G; +- mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val); +- +- mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE); +- +- /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex +- * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. +- */ +- mt7530_rmw(priv, MT7531_SGMII_MODE(port), +- MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS, +- MT7531_SGMII_FORCE_SPEED_1000); +- +- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0); +- +- return 0; +-} +- +-static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port, +- phy_interface_t interface) +-{ +- if (!mt753x_is_mac_port(port)) +- return -EINVAL; +- +- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port), +- MT7531_SGMII_PHYA_PWD); +- +- mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port), +- MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G); +- +- mt7530_set(priv, MT7531_SGMII_MODE(port), +- MT7531_SGMII_REMOTE_FAULT_DIS | +- MT7531_SGMII_SPEED_DUPLEX_AN); +- +- mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port), +- MT7531_SGMII_TX_CONFIG_MASK, 1); +- +- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE); +- +- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART); +- +- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0); +- +- return 0; +-} +- +-static void mt7531_pcs_an_restart(struct phylink_pcs *pcs) +-{ +- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; +- int port = pcs_to_mt753x_pcs(pcs)->port; +- u32 val; +- +- /* Only restart AN when AN is enabled */ +- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); +- if (val & MT7531_SGMII_AN_ENABLE) { +- val |= MT7531_SGMII_AN_RESTART; +- mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val); +- } +-} +- + static int + mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, + phy_interface_t interface) +@@ -2741,11 +2625,11 @@ mt7531_mac_config(struct dsa_switch *ds, + phydev = dp->slave->phydev; + return mt7531_rgmii_setup(priv, port, interface, phydev); + case PHY_INTERFACE_MODE_SGMII: +- return mt7531_sgmii_setup_mode_an(priv, port, interface); + case PHY_INTERFACE_MODE_NA: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: +- return mt7531_sgmii_setup_mode_force(priv, port, interface); ++ /* handled in SGMII PCS driver */ ++ return 0; + default: + return -EINVAL; + } +@@ -2770,11 +2654,11 @@ mt753x_phylink_mac_select_pcs(struct dsa + + switch (interface) { + case PHY_INTERFACE_MODE_TRGMII: ++ return &priv->pcs[port].pcs; + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: +- return &priv->pcs[port].pcs; +- ++ return priv->ports[port].sgmii_pcs; + default: + return NULL; + } +@@ -3015,86 +2899,6 @@ static void mt7530_pcs_get_state(struct + state->pause |= MLO_PAUSE_TX; + } + +-static int +-mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port, +- struct phylink_link_state *state) +-{ +- u32 status, val; +- u16 config_reg; +- +- status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); +- state->link = !!(status & MT7531_SGMII_LINK_STATUS); +- state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE); +- if (state->interface == PHY_INTERFACE_MODE_SGMII && +- (status & MT7531_SGMII_AN_ENABLE)) { +- val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); +- config_reg = val >> 16; +- +- switch (config_reg & LPA_SGMII_SPD_MASK) { +- case LPA_SGMII_1000: +- state->speed = SPEED_1000; +- break; +- case LPA_SGMII_100: +- state->speed = SPEED_100; +- break; +- case LPA_SGMII_10: +- state->speed = SPEED_10; +- break; +- default: +- dev_err(priv->dev, "invalid sgmii PHY speed\n"); +- state->link = false; +- return -EINVAL; +- } +- +- if (config_reg & LPA_SGMII_FULL_DUPLEX) +- state->duplex = DUPLEX_FULL; +- else +- state->duplex = DUPLEX_HALF; +- } +- +- 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; +- +- state->an_complete = state->link; +- +- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) +- state->speed = SPEED_2500; +- else +- state->speed = SPEED_1000; +- +- state->duplex = DUPLEX_FULL; +- state->pause = MLO_PAUSE_NONE; +-} +- +-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; +- +- if (state->interface == PHY_INTERFACE_MODE_SGMII) { +- mt7531_sgmii_pcs_get_state_an(priv, port, state); +- 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, + phy_interface_t interface, + const unsigned long *advertising, +@@ -3114,18 +2918,57 @@ static const struct phylink_pcs_ops mt75 + .pcs_an_restart = mt7530_pcs_an_restart, + }; + +-static const struct phylink_pcs_ops mt7531_pcs_ops = { +- .pcs_validate = mt753x_pcs_validate, +- .pcs_get_state = mt7531_pcs_get_state, +- .pcs_config = mt753x_pcs_config, +- .pcs_an_restart = mt7531_pcs_an_restart, +- .pcs_link_up = mt7531_pcs_link_up, ++static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) ++{ ++ struct mt7530_priv *priv = context; ++ ++ *val = mt7530_read(priv, reg); ++ return 0; ++}; ++ ++static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) ++{ ++ struct mt7530_priv *priv = context; ++ ++ mt7530_write(priv, reg, val); ++ return 0; ++}; ++ ++static int mt7530_regmap_update_bits(void *context, unsigned int reg, ++ unsigned int mask, unsigned int val) ++{ ++ struct mt7530_priv *priv = context; ++ ++ mt7530_rmw(priv, reg, mask, val); ++ return 0; ++}; ++ ++static const struct regmap_bus mt7531_regmap_bus = { ++ .reg_write = mt7530_regmap_write, ++ .reg_read = mt7530_regmap_read, ++ .reg_update_bits = mt7530_regmap_update_bits, ++}; ++ ++#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \ ++ { \ ++ .name = _name, \ ++ .reg_bits = 16, \ ++ .val_bits = 32, \ ++ .reg_stride = 4, \ ++ .reg_base = _reg_base, \ ++ .max_register = 0x17c, \ ++ } ++ ++static const struct regmap_config mt7531_pcs_config[] = { ++ MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)), ++ MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)), + }; + + static int + mt753x_setup(struct dsa_switch *ds) + { + struct mt7530_priv *priv = ds->priv; ++ struct regmap *regmap; + int i, ret; + + /* Initialise the PCS devices */ +@@ -3133,8 +2976,6 @@ 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); +@@ -3149,6 +2990,16 @@ mt753x_setup(struct dsa_switch *ds) + if (ret && priv->irq) + mt7530_free_irq_common(priv); + ++ if (priv->id == ID_MT7531) ++ for (i = 0; i < 2; i++) { ++ regmap = devm_regmap_init(ds->dev, ++ &mt7531_regmap_bus, priv, ++ &mt7531_pcs_config[i]); ++ priv->ports[5 + i].sgmii_pcs = ++ mtk_pcs_lynxi_create(ds->dev, regmap, ++ MT7531_PHYA_CTRL_SIGNAL3, 0); ++ } ++ + return ret; + } + +@@ -3240,7 +3091,7 @@ static const struct mt753x_info mt753x_t + }, + [ID_MT7531] = { + .id = ID_MT7531, +- .pcs_ops = &mt7531_pcs_ops, ++ .pcs_ops = &mt7530_pcs_ops, + .sw_setup = mt7531_setup, + .phy_read = mt7531_ind_phy_read, + .phy_write = mt7531_ind_phy_write, +@@ -3348,7 +3199,7 @@ static void + mt7530_remove(struct mdio_device *mdiodev) + { + struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); +- int ret = 0; ++ int ret = 0, i; + + if (!priv) + return; +@@ -3367,6 +3218,10 @@ mt7530_remove(struct mdio_device *mdiode + mt7530_free_irq(priv); + + dsa_unregister_switch(priv->ds); ++ ++ for (i = 0; i < 2; ++i) ++ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); ++ + mutex_destroy(&priv->reg_mutex); + } + +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -364,47 +364,8 @@ enum mt7530_vlan_port_acc_frm { + CCR_TX_OCT_CNT_BAD) + + /* MT7531 SGMII register group */ +-#define MT7531_SGMII_REG_BASE 0x5000 +-#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \ +- ((p) - 5) * 0x1000 + (r)) +- +-/* Register forSGMII PCS_CONTROL_1 */ +-#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00) +-#define MT7531_SGMII_LINK_STATUS BIT(18) +-#define MT7531_SGMII_AN_ENABLE BIT(12) +-#define MT7531_SGMII_AN_RESTART BIT(9) +-#define MT7531_SGMII_AN_COMPLETE BIT(21) +- +-/* Register for SGMII PCS_SPPED_ABILITY */ +-#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08) +-#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0) +-#define MT7531_SGMII_TX_CONFIG BIT(0) +- +-/* Register for SGMII_MODE */ +-#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20) +-#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8) +-#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1) +-#define MT7531_SGMII_FORCE_DUPLEX BIT(4) +-#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2) +-#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3) +-#define MT7531_SGMII_FORCE_SPEED_100 BIT(2) +-#define MT7531_SGMII_FORCE_SPEED_10 0 +-#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1) +- +-enum mt7531_sgmii_force_duplex { +- MT7531_SGMII_FORCE_FULL_DUPLEX = 0, +- MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10, +-}; +- +-/* Fields of QPHY_PWR_STATE_CTRL */ +-#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8) +-#define MT7531_SGMII_PHYA_PWD BIT(4) +- +-/* Values of SGMII SPEED */ +-#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128) +-#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3)) +-#define MT7531_RG_TPHY_SPEED_1_25G 0x0 +-#define MT7531_RG_TPHY_SPEED_3_125G BIT(2) ++#define MT7531_SGMII_REG_BASE(p) (0x5000 + ((p) - 5) * 0x1000) ++#define MT7531_PHYA_CTRL_SIGNAL3 0x128 + + /* Register for system reset */ + #define MT7530_SYS_CTRL 0x7000 +@@ -703,13 +664,13 @@ struct mt7530_fdb { + * @pm: The matrix used to show all connections with the port. + * @pvid: The VLAN specified is to be considered a PVID at ingress. Any + * untagged frames will be assigned to the related VLAN. +- * @vlan_filtering: The flags indicating whether the port that can recognize +- * VLAN-tagged frames. ++ * @sgmii_pcs: Pointer to PCS instance for SerDes ports + */ + struct mt7530_port { + bool enable; + u32 pm; + u16 pvid; ++ struct phylink_pcs *sgmii_pcs; + }; + + /* Port 5 interface select definitions */ diff --git a/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch b/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch new file mode 100644 index 000000000..33759632e --- /dev/null +++ b/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch @@ -0,0 +1,82 @@ +From fbfc4ca465a1f8d81bf2d67d95bf7fc67c3cf0c2 Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Fri, 18 Nov 2022 06:39:20 +0000 +Subject: [PATCH] nvmem: stm32: move STM32MP15_BSEC_NUM_LOWER in config + +Support STM32MP15_BSEC_NUM_LOWER in stm32 romem config to prepare +the next SoC in STM32MP family. + +Signed-off-by: Patrick Delaunay +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20221118063932.6418-2-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -22,16 +22,15 @@ + /* shadow registers offest */ + #define STM32MP15_BSEC_DATA0 0x200 + +-/* 32 (x 32-bits) lower shadow registers */ +-#define STM32MP15_BSEC_NUM_LOWER 32 +- + struct stm32_romem_cfg { + int size; ++ u8 lower; + }; + + struct stm32_romem_priv { + void __iomem *base; + struct nvmem_config cfg; ++ u8 lower; + }; + + static int stm32_romem_read(void *context, unsigned int offset, void *buf, +@@ -85,7 +84,7 @@ static int stm32_bsec_read(void *context + for (i = roffset; (i < roffset + rbytes); i += 4) { + u32 otp = i >> 2; + +- if (otp < STM32MP15_BSEC_NUM_LOWER) { ++ if (otp < priv->lower) { + /* read lower data from shadow registers */ + val = readl_relaxed( + priv->base + STM32MP15_BSEC_DATA0 + i); +@@ -159,6 +158,8 @@ static int stm32_romem_probe(struct plat + priv->cfg.priv = priv; + priv->cfg.owner = THIS_MODULE; + ++ priv->lower = 0; ++ + cfg = (const struct stm32_romem_cfg *) + of_match_device(dev->driver->of_match_table, dev)->data; + if (!cfg) { +@@ -167,6 +168,7 @@ static int stm32_romem_probe(struct plat + priv->cfg.reg_read = stm32_romem_read; + } else { + priv->cfg.size = cfg->size; ++ priv->lower = cfg->lower; + priv->cfg.reg_read = stm32_bsec_read; + priv->cfg.reg_write = stm32_bsec_write; + } +@@ -174,8 +176,17 @@ static int stm32_romem_probe(struct plat + return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); + } + ++/* ++ * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) ++ * => 96 x 32-bits data words ++ * - Lower: 1K bits, 2:1 redundancy, incremental bit programming ++ * => 32 (x 32-bits) lower shadow registers = words 0 to 31 ++ * - Upper: 2K bits, ECC protection, word programming only ++ * => 64 (x 32-bits) = words 32 to 95 ++ */ + static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { +- .size = 384, /* 96 x 32-bits data words */ ++ .size = 384, ++ .lower = 32, + }; + + static const struct of_device_id stm32_romem_of_match[] = { diff --git a/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch b/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch new file mode 100644 index 000000000..5791df260 --- /dev/null +++ b/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch @@ -0,0 +1,34 @@ +From d61784e6410f3df2028e6eb91b06ffed37a660e0 Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Fri, 18 Nov 2022 06:39:21 +0000 +Subject: [PATCH] nvmem: stm32: add warning when upper OTPs are updated + +As the upper OTPs are ECC protected, they support only one 32 bits word +programming. +For a second modification of this word, these ECC become invalid and +this OTP will be no more accessible, the shadowed value is invalid. + +This patch adds a warning to indicate an upper OTP update, because this +operation is dangerous as OTP is not locked by the driver after the first +update to avoid a second update. + +Signed-off-by: Patrick Delaunay +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20221118063932.6418-3-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -132,6 +132,9 @@ static int stm32_bsec_write(void *contex + } + } + ++ if (offset + bytes >= priv->lower * 4) ++ dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n"); ++ + return 0; + } + diff --git a/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch b/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch new file mode 100644 index 000000000..b83ad69c6 --- /dev/null +++ b/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch @@ -0,0 +1,26 @@ +From a3816a7d7c097c1da46aad5f5d1e229b607dce04 Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Fri, 18 Nov 2022 06:39:22 +0000 +Subject: [PATCH] nvmem: stm32: add nvmem type attribute + +Inform NVMEM framework of type attribute for stm32-romem as NVMEM_TYPE_OTP +so userspace is able to know how the data is stored in BSEC. + +Signed-off-by: Patrick Delaunay +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20221118063932.6418-4-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -160,6 +160,7 @@ static int stm32_romem_probe(struct plat + priv->cfg.dev = dev; + priv->cfg.priv = priv; + priv->cfg.owner = THIS_MODULE; ++ priv->cfg.type = NVMEM_TYPE_OTP; + + priv->lower = 0; + diff --git a/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch b/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch new file mode 100644 index 000000000..52ba1e65b --- /dev/null +++ b/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch @@ -0,0 +1,27 @@ +From 06aac0e11960a7ddccc1888326b5906d017e0f24 Mon Sep 17 00:00:00 2001 +From: Jiangshan Yi +Date: Fri, 18 Nov 2022 06:39:24 +0000 +Subject: [PATCH] nvmem: stm32: fix spelling typo in comment + +Fix spelling typo in comment. + +Reported-by: k2ci +Signed-off-by: Jiangshan Yi +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20221118063932.6418-6-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -19,7 +19,7 @@ + #define STM32_SMC_WRITE_SHADOW 0x03 + #define STM32_SMC_READ_OTP 0x04 + +-/* shadow registers offest */ ++/* shadow registers offset */ + #define STM32MP15_BSEC_DATA0 0x200 + + struct stm32_romem_cfg { diff --git a/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch b/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch new file mode 100644 index 000000000..8f024f4c1 --- /dev/null +++ b/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch @@ -0,0 +1,27 @@ +From fb817c4ef63e8cfb6e77ae4a2875ae854c80708f Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Fri, 18 Nov 2022 06:39:26 +0000 +Subject: [PATCH] nvmem: Kconfig: Fix spelling mistake "controlls" -> + "controls" + +There is a spelling mistake in a Kconfig description. Fix it. + +Signed-off-by: Colin Ian King +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20221118063932.6418-8-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -164,7 +164,7 @@ config NVMEM_MICROCHIP_OTPC + depends on ARCH_AT91 || COMPILE_TEST + help + This driver enable the OTP controller available on Microchip SAMA7G5 +- SoCs. It controlls the access to the OTP memory connected to it. ++ SoCs. It controls the access to the OTP memory connected to it. + + config NVMEM_MTK_EFUSE + tristate "Mediatek SoCs EFUSE support" diff --git a/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch b/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch new file mode 100644 index 000000000..861386ad3 --- /dev/null +++ b/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch @@ -0,0 +1,67 @@ +From ada84d07af6097b2addd18262668ce6cb9e15206 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 18 Nov 2022 06:39:27 +0000 +Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Broadcom uses U-Boot for a lot of their bcmbca familiy chipsets. They +decided to store U-Boot environment data inside U-Boot partition and to +use a custom header (with "uEnv" magic and env data length). + +Add support for Broadcom's specific binding and their custom format. + +Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding") +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20221118063932.6418-9-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/u-boot-env.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -16,6 +16,7 @@ + enum u_boot_env_format { + U_BOOT_FORMAT_SINGLE, + U_BOOT_FORMAT_REDUNDANT, ++ U_BOOT_FORMAT_BROADCOM, + }; + + struct u_boot_env { +@@ -40,6 +41,13 @@ struct u_boot_env_image_redundant { + uint8_t data[]; + } __packed; + ++struct u_boot_env_image_broadcom { ++ __le32 magic; ++ __le32 len; ++ __le32 crc32; ++ uint8_t data[0]; ++} __packed; ++ + static int u_boot_env_read(void *context, unsigned int offset, void *val, + size_t bytes) + { +@@ -138,6 +146,11 @@ static int u_boot_env_parse(struct u_boo + crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); + data_offset = offsetof(struct u_boot_env_image_redundant, data); + break; ++ case U_BOOT_FORMAT_BROADCOM: ++ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); ++ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); ++ data_offset = offsetof(struct u_boot_env_image_broadcom, data); ++ break; + } + crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); + crc32_data_len = priv->mtd->size - crc32_data_offset; +@@ -202,6 +215,7 @@ static const struct of_device_id u_boot_ + { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, }, + { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, + { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, ++ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, }, + {}, + }; + diff --git a/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch b/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch new file mode 100644 index 000000000..01400fd49 --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch @@ -0,0 +1,26 @@ +From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +Date: Mon, 6 Feb 2023 13:43:41 +0000 +Subject: [PATCH] nvmem: core: remove spurious white space + +Remove a spurious white space in for the ida_alloc() call. + +Signed-off-by: Russell King (Oracle) +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons + if (!nvmem) + return ERR_PTR(-ENOMEM); + +- rval = ida_alloc(&nvmem_ida, GFP_KERNEL); ++ rval = ida_alloc(&nvmem_ida, GFP_KERNEL); + if (rval < 0) { + kfree(nvmem); + return ERR_PTR(rval); diff --git a/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch b/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch new file mode 100644 index 000000000..454d3bf0e --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch @@ -0,0 +1,180 @@ +From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:46 +0000 +Subject: [PATCH] nvmem: core: add an index parameter to the cell + +Sometimes a cell can represend multiple values. For example, a base +ethernet address stored in the NVMEM can be expanded into multiple +discreet ones by adding an offset. + +For this use case, introduce an index parameter which is then used to +distiguish between values. This parameter will then be passed to the +post process hook which can then use it to create different values +during reading. + +At the moment, there is only support for the device tree path. You can +add the index to the phandle, e.g. + + &net { + nvmem-cells = <&base_mac_address 2>; + nvmem-cell-names = "mac-address"; + }; + + &nvmem_provider { + base_mac_address: base-mac-address@0 { + #nvmem-cell-cells = <1>; + reg = <0 6>; + }; + }; + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 37 ++++++++++++++++++++++++---------- + drivers/nvmem/imx-ocotp.c | 4 ++-- + include/linux/nvmem-provider.h | 4 ++-- + 3 files changed, 30 insertions(+), 15 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -60,6 +60,7 @@ struct nvmem_cell_entry { + struct nvmem_cell { + struct nvmem_cell_entry *entry; + const char *id; ++ int index; + }; + + static DEFINE_MUTEX(nvmem_mutex); +@@ -1122,7 +1123,8 @@ struct nvmem_device *devm_nvmem_device_g + } + EXPORT_SYMBOL_GPL(devm_nvmem_device_get); + +-static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) ++static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, ++ const char *id, int index) + { + struct nvmem_cell *cell; + const char *name = NULL; +@@ -1141,6 +1143,7 @@ static struct nvmem_cell *nvmem_create_c + + cell->id = name; + cell->entry = entry; ++ cell->index = index; + + return cell; + } +@@ -1179,7 +1182,7 @@ nvmem_cell_get_from_lookup(struct device + __nvmem_device_put(nvmem); + cell = ERR_PTR(-ENOENT); + } else { +- cell = nvmem_create_cell(cell_entry, con_id); ++ cell = nvmem_create_cell(cell_entry, con_id, 0); + if (IS_ERR(cell)) + __nvmem_device_put(nvmem); + } +@@ -1227,15 +1230,27 @@ struct nvmem_cell *of_nvmem_cell_get(str + struct nvmem_device *nvmem; + struct nvmem_cell_entry *cell_entry; + struct nvmem_cell *cell; ++ struct of_phandle_args cell_spec; + int index = 0; ++ int cell_index = 0; ++ int ret; + + /* if cell name exists, find index to the name */ + if (id) + index = of_property_match_string(np, "nvmem-cell-names", id); + +- cell_np = of_parse_phandle(np, "nvmem-cells", index); +- if (!cell_np) +- return ERR_PTR(-ENOENT); ++ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells", ++ "#nvmem-cell-cells", ++ index, &cell_spec); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ if (cell_spec.args_count > 1) ++ return ERR_PTR(-EINVAL); ++ ++ cell_np = cell_spec.np; ++ if (cell_spec.args_count) ++ cell_index = cell_spec.args[0]; + + nvmem_np = of_get_parent(cell_np); + if (!nvmem_np) { +@@ -1257,7 +1272,7 @@ struct nvmem_cell *of_nvmem_cell_get(str + return ERR_PTR(-ENOENT); + } + +- cell = nvmem_create_cell(cell_entry, id); ++ cell = nvmem_create_cell(cell_entry, id, cell_index); + if (IS_ERR(cell)) + __nvmem_device_put(nvmem); + +@@ -1410,8 +1425,8 @@ static void nvmem_shift_read_buffer_in_p + } + + static int __nvmem_cell_read(struct nvmem_device *nvmem, +- struct nvmem_cell_entry *cell, +- void *buf, size_t *len, const char *id) ++ struct nvmem_cell_entry *cell, ++ void *buf, size_t *len, const char *id, int index) + { + int rc; + +@@ -1425,7 +1440,7 @@ static int __nvmem_cell_read(struct nvme + nvmem_shift_read_buffer_in_place(cell, buf); + + if (nvmem->cell_post_process) { +- rc = nvmem->cell_post_process(nvmem->priv, id, ++ rc = nvmem->cell_post_process(nvmem->priv, id, index, + cell->offset, buf, cell->bytes); + if (rc) + return rc; +@@ -1460,7 +1475,7 @@ void *nvmem_cell_read(struct nvmem_cell + if (!buf) + return ERR_PTR(-ENOMEM); + +- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); ++ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index); + if (rc) { + kfree(buf); + return ERR_PTR(rc); +@@ -1773,7 +1788,7 @@ ssize_t nvmem_device_cell_read(struct nv + if (rc) + return rc; + +- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); ++ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0); + if (rc) + return rc; + +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -222,8 +222,8 @@ read_end: + return ret; + } + +-static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, +- void *data, size_t bytes) ++static int imx_ocotp_cell_pp(void *context, const char *id, int index, ++ unsigned int offset, void *data, size_t bytes) + { + struct ocotp_priv *priv = context; + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr + typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, + void *val, size_t bytes); + /* used for vendor specific post processing of cell data */ +-typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, +- void *buf, size_t bytes); ++typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, size_t bytes); + + enum nvmem_type { + NVMEM_TYPE_UNKNOWN = 0, diff --git a/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch b/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch new file mode 100644 index 000000000..f3829b3e1 --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch @@ -0,0 +1,78 @@ +From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:47 +0000 +Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h + +struct nvmem_cell_info is used to describe a cell. Thus this should +really be in the nvmem-provider's header. There are two (unused) nvmem +access methods which use the nvmem_cell_info to describe the cell to be +accesses. One can argue, that they will create a cell before accessing, +thus they are both a provider and a consumer. + +struct nvmem_cell_info will get used more and more by nvmem-providers, +don't force them to also include the consumer header, although they are +not. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nvmem-consumer.h | 10 +--------- + include/linux/nvmem-provider.h | 19 ++++++++++++++++++- + 2 files changed, 19 insertions(+), 10 deletions(-) + +--- a/include/linux/nvmem-consumer.h ++++ b/include/linux/nvmem-consumer.h +@@ -18,15 +18,7 @@ struct device_node; + /* consumer cookie */ + struct nvmem_cell; + struct nvmem_device; +- +-struct nvmem_cell_info { +- const char *name; +- unsigned int offset; +- unsigned int bytes; +- unsigned int bit_offset; +- unsigned int nbits; +- struct device_node *np; +-}; ++struct nvmem_cell_info; + + /** + * struct nvmem_cell_lookup - cell lookup entry +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -14,7 +14,6 @@ + #include + + struct nvmem_device; +-struct nvmem_cell_info; + typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, + void *val, size_t bytes); + typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, +@@ -48,6 +47,24 @@ struct nvmem_keepout { + }; + + /** ++ * struct nvmem_cell_info - NVMEM cell description ++ * @name: Name. ++ * @offset: Offset within the NVMEM device. ++ * @bytes: Length of the cell. ++ * @bit_offset: Bit offset if cell is smaller than a byte. ++ * @nbits: Number of bits. ++ * @np: Optional device_node pointer. ++ */ ++struct nvmem_cell_info { ++ const char *name; ++ unsigned int offset; ++ unsigned int bytes; ++ unsigned int bit_offset; ++ unsigned int nbits; ++ struct device_node *np; ++}; ++ ++/** + * struct nvmem_config - NVMEM device configuration + * + * @dev: Parent device. diff --git a/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch b/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch new file mode 100644 index 000000000..8f996eab3 --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch @@ -0,0 +1,65 @@ +From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:48 +0000 +Subject: [PATCH] nvmem: core: drop the removal of the cells in + nvmem_add_cells() + +If nvmem_add_cells() fails, the whole nvmem_register() will fail +and the cells will then be removed anyway. This is a preparation +to introduce a nvmem_add_one_cell() which can then be used by +nvmem_add_cells(). + +This is then the same to what nvmem_add_cells_from_table() and +nvmem_add_cells_from_of() do. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_ + int ncells) + { + struct nvmem_cell_entry **cells; +- int i, rval; ++ int i, rval = 0; + + cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); + if (!cells) +@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_ + cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); + if (!cells[i]) { + rval = -ENOMEM; +- goto err; ++ goto out; + } + + rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); + if (rval) { + kfree(cells[i]); +- goto err; ++ goto out; + } + + nvmem_cell_entry_add(cells[i]); + } + ++out: + /* remove tmp array */ + kfree(cells); + +- return 0; +-err: +- while (i--) +- nvmem_cell_entry_drop(cells[i]); +- +- kfree(cells); +- + return rval; + } + diff --git a/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch b/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch new file mode 100644 index 000000000..711ce229b --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch @@ -0,0 +1,122 @@ +From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:49 +0000 +Subject: [PATCH] nvmem: core: add nvmem_add_one_cell() + +Add a new function to add exactly one cell. This will be used by the +nvmem layout drivers to add custom cells. In contrast to the +nvmem_add_cells(), this has the advantage that we don't have to assemble +a list of cells on runtime. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 59 ++++++++++++++++++++-------------- + include/linux/nvmem-provider.h | 8 +++++ + 2 files changed, 43 insertions(+), 24 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell + } + + /** ++ * nvmem_add_one_cell() - Add one cell information to an nvmem device ++ * ++ * @nvmem: nvmem device to add cells to. ++ * @info: nvmem cell info to add to the device ++ * ++ * Return: 0 or negative error code on failure. ++ */ ++int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info) ++{ ++ struct nvmem_cell_entry *cell; ++ int rval; ++ ++ cell = kzalloc(sizeof(*cell), GFP_KERNEL); ++ if (!cell) ++ return -ENOMEM; ++ ++ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); ++ if (rval) { ++ kfree(cell); ++ return rval; ++ } ++ ++ nvmem_cell_entry_add(cell); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(nvmem_add_one_cell); ++ ++/** + * nvmem_add_cells() - Add cell information to an nvmem device + * + * @nvmem: nvmem device to add cells to. +@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_ + const struct nvmem_cell_info *info, + int ncells) + { +- struct nvmem_cell_entry **cells; +- int i, rval = 0; +- +- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); +- if (!cells) +- return -ENOMEM; ++ int i, rval; + + for (i = 0; i < ncells; i++) { +- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); +- if (!cells[i]) { +- rval = -ENOMEM; +- goto out; +- } +- +- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); +- if (rval) { +- kfree(cells[i]); +- goto out; +- } +- +- nvmem_cell_entry_add(cells[i]); ++ rval = nvmem_add_one_cell(nvmem, &info[i]); ++ if (rval) ++ return rval; + } + +-out: +- /* remove tmp array */ +- kfree(cells); +- +- return rval; ++ return 0; + } + + /** +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -153,6 +153,9 @@ struct nvmem_device *devm_nvmem_register + void nvmem_add_cell_table(struct nvmem_cell_table *table); + void nvmem_del_cell_table(struct nvmem_cell_table *table); + ++int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info); ++ + #else + + static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) +@@ -170,6 +173,11 @@ devm_nvmem_register(struct device *dev, + + static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} + static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} ++static inline int nvmem_add_one_cell(struct nvmem_device *nvmem, ++ const struct nvmem_cell_info *info) ++{ ++ return -EOPNOTSUPP; ++} + + #endif /* CONFIG_NVMEM */ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch b/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch new file mode 100644 index 000000000..e1791e5c8 --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch @@ -0,0 +1,93 @@ +From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:50 +0000 +Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in + nvmem_add_cells_from_of() + +Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell(). +This will remove duplicate code and it will make it possible to add a +hook to a nvmem layout in between, which can change fields before the +cell is finally added. + +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 45 ++++++++++++++------------------------------ + 1 file changed, 14 insertions(+), 31 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc + + static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) + { +- struct device_node *parent, *child; + struct device *dev = &nvmem->dev; +- struct nvmem_cell_entry *cell; ++ struct device_node *child; + const __be32 *addr; +- int len; ++ int len, ret; + +- parent = dev->of_node; ++ for_each_child_of_node(dev->of_node, child) { ++ struct nvmem_cell_info info = {0}; + +- for_each_child_of_node(parent, child) { + addr = of_get_property(child, "reg", &len); + if (!addr) + continue; +@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc + return -EINVAL; + } + +- cell = kzalloc(sizeof(*cell), GFP_KERNEL); +- if (!cell) { +- of_node_put(child); +- return -ENOMEM; +- } +- +- cell->nvmem = nvmem; +- cell->offset = be32_to_cpup(addr++); +- cell->bytes = be32_to_cpup(addr); +- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); ++ info.offset = be32_to_cpup(addr++); ++ info.bytes = be32_to_cpup(addr); ++ info.name = kasprintf(GFP_KERNEL, "%pOFn", child); + + addr = of_get_property(child, "bits", &len); + if (addr && len == (2 * sizeof(u32))) { +- cell->bit_offset = be32_to_cpup(addr++); +- cell->nbits = be32_to_cpup(addr); ++ info.bit_offset = be32_to_cpup(addr++); ++ info.nbits = be32_to_cpup(addr); + } + +- if (cell->nbits) +- cell->bytes = DIV_ROUND_UP( +- cell->nbits + cell->bit_offset, +- BITS_PER_BYTE); +- +- if (!IS_ALIGNED(cell->offset, nvmem->stride)) { +- dev_err(dev, "cell %s unaligned to nvmem stride %d\n", +- cell->name, nvmem->stride); +- /* Cells already added will be freed later. */ +- kfree_const(cell->name); +- kfree(cell); ++ info.np = of_node_get(child); ++ ++ ret = nvmem_add_one_cell(nvmem, &info); ++ kfree(info.name); ++ if (ret) { + of_node_put(child); +- return -EINVAL; ++ return ret; + } +- +- cell->np = of_node_get(child); +- nvmem_cell_entry_add(cell); + } + + return 0; diff --git a/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch b/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch new file mode 100644 index 000000000..172a78b76 --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch @@ -0,0 +1,562 @@ +From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Mon, 6 Feb 2023 13:43:51 +0000 +Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x + +For boot with OP-TEE on STM32MP13, the communication with the secure +world no more use STMicroelectronics SMC but communication with the +STM32MP BSEC TA, for data access (read/write) or lock operation: +- all the request are sent to OP-TEE trusted application, +- for upper OTP with ECC protection and with word programming only + each OTP are permanently locked when programmed to avoid ECC error + on the second write operation + +Signed-off-by: Patrick Delaunay +Reviewed-by: Etienne Carriere +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 11 + + drivers/nvmem/Makefile | 1 + + drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++ + drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++ + drivers/nvmem/stm32-romem.c | 54 ++++- + 5 files changed, 441 insertions(+), 3 deletions(-) + create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c + create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE + This driver can also be built as a module. If so, the module + will be called nvmem-sprd-efuse. + ++config NVMEM_STM32_BSEC_OPTEE_TA ++ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" ++ depends on OPTEE ++ help ++ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE ++ trusted application STM32MP BSEC. ++ ++ This library is a used by stm32-romem driver or included in the module ++ called nvmem-stm32-romem. ++ + config NVMEM_STM32_ROMEM + tristate "STMicroelectronics STM32 factory-programmed memory support" + depends on ARCH_STM32 || COMPILE_TEST ++ imply NVMEM_STM32_BSEC_OPTEE_TA + help + Say y here to enable read-only access for STMicroelectronics STM32 + factory-programmed memory area. +--- a/drivers/nvmem/Makefile ++++ b/drivers/nvmem/Makefile +@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem + nvmem_sprd_efuse-y := sprd-efuse.o + obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o + nvmem_stm32_romem-y := stm32-romem.o ++nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o + obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o + nvmem_sunplus_ocotp-y := sunplus-ocotp.o + obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o +--- /dev/null ++++ b/drivers/nvmem/stm32-bsec-optee-ta.c +@@ -0,0 +1,298 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver ++ * ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++ ++#include "stm32-bsec-optee-ta.h" ++ ++/* ++ * Read OTP memory ++ * ++ * [in] value[0].a OTP start offset in byte ++ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) ++ * [out] memref[1].buffer Output buffer to store read values ++ * [out] memref[1].size Size of OTP to be read ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller ++ */ ++#define PTA_BSEC_READ_MEM 0x0 ++ ++/* ++ * Write OTP memory ++ * ++ * [in] value[0].a OTP start offset in byte ++ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) ++ * [in] memref[1].buffer Input buffer to read values ++ * [in] memref[1].size Size of OTP to be written ++ * ++ * Return codes: ++ * TEE_SUCCESS - Invoke command success ++ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param ++ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller ++ */ ++#define PTA_BSEC_WRITE_MEM 0x1 ++ ++/* value of PTA_BSEC access type = value[in] b */ ++#define SHADOW_ACCESS 0 ++#define FUSE_ACCESS 1 ++#define LOCK_ACCESS 2 ++ ++/* Bitfield definition for LOCK status */ ++#define LOCK_PERM BIT(30) ++ ++/* OP-TEE STM32MP BSEC TA UUID */ ++static const uuid_t stm32mp_bsec_ta_uuid = ++ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5, ++ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03); ++ ++/* ++ * Check whether this driver supports the BSEC TA in the TEE instance ++ * represented by the params (ver/data) to this function. ++ */ ++static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver, ++ const void *data) ++{ ++ /* Currently this driver only supports GP compliant, OP-TEE based TA */ ++ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) && ++ (ver->gen_caps & TEE_GEN_CAP_GP)) ++ return 1; ++ else ++ return 0; ++} ++ ++/* Open a session to OP-TEE for STM32MP BSEC TA */ ++static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id) ++{ ++ struct tee_ioctl_open_session_arg sess_arg; ++ int rc; ++ ++ memset(&sess_arg, 0, sizeof(sess_arg)); ++ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid); ++ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; ++ sess_arg.num_params = 0; ++ ++ rc = tee_client_open_session(ctx, &sess_arg, NULL); ++ if ((rc < 0) || (sess_arg.ret != 0)) { ++ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n", ++ __func__, sess_arg.ret, rc); ++ if (!rc) ++ rc = -EINVAL; ++ } else { ++ *id = sess_arg.session; ++ } ++ ++ return rc; ++} ++ ++/* close a session to OP-TEE for STM32MP BSEC TA */ ++static void stm32_bsec_ta_close_session(void *ctx, u32 id) ++{ ++ tee_client_close_session(ctx, id); ++} ++ ++/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */ ++int stm32_bsec_optee_ta_open(struct tee_context **ctx) ++{ ++ struct tee_context *tee_ctx; ++ u32 session_id; ++ int rc; ++ ++ /* Open context with TEE driver */ ++ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL); ++ if (IS_ERR(tee_ctx)) { ++ rc = PTR_ERR(tee_ctx); ++ if (rc == -ENOENT) ++ return -EPROBE_DEFER; ++ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc); ++ ++ return rc; ++ } ++ ++ /* Check STM32MP BSEC TA presence */ ++ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id); ++ if (rc) { ++ tee_client_close_context(tee_ctx); ++ return rc; ++ } ++ ++ stm32_bsec_ta_close_session(tee_ctx, session_id); ++ ++ *ctx = tee_ctx; ++ ++ return 0; ++} ++ ++/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */ ++void stm32_bsec_optee_ta_close(void *ctx) ++{ ++ tee_client_close_context(ctx); ++} ++ ++/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */ ++int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, ++ void *buf, size_t bytes) ++{ ++ struct tee_shm *shm; ++ struct tee_ioctl_invoke_arg arg; ++ struct tee_param param[2]; ++ u8 *shm_buf; ++ u32 start, num_bytes; ++ int ret; ++ u32 session_id; ++ ++ ret = stm32_bsec_ta_open_session(ctx, &session_id); ++ if (ret) ++ return ret; ++ ++ memset(&arg, 0, sizeof(arg)); ++ memset(¶m, 0, sizeof(param)); ++ ++ arg.func = PTA_BSEC_READ_MEM; ++ arg.session = session_id; ++ arg.num_params = 2; ++ ++ /* align access on 32bits */ ++ start = ALIGN_DOWN(offset, 4); ++ num_bytes = round_up(offset + bytes - start, 4); ++ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = start; ++ param[0].u.value.b = SHADOW_ACCESS; ++ ++ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes); ++ if (IS_ERR(shm)) { ++ ret = PTR_ERR(shm); ++ goto out_tee_session; ++ } ++ ++ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; ++ param[1].u.memref.shm = shm; ++ param[1].u.memref.size = num_bytes; ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", ++ arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ if (!ret) { ++ shm_buf = tee_shm_get_va(shm, 0); ++ if (IS_ERR(shm_buf)) { ++ ret = PTR_ERR(shm_buf); ++ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); ++ } else { ++ /* read data from 32 bits aligned buffer */ ++ memcpy(buf, &shm_buf[offset % 4], bytes); ++ } ++ } ++ ++ tee_shm_free(shm); ++ ++out_tee_session: ++ stm32_bsec_ta_close_session(ctx, session_id); ++ ++ return ret; ++} ++ ++/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */ ++int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, ++ unsigned int offset, void *buf, size_t bytes) ++{ struct tee_shm *shm; ++ struct tee_ioctl_invoke_arg arg; ++ struct tee_param param[2]; ++ u8 *shm_buf; ++ int ret; ++ u32 session_id; ++ ++ ret = stm32_bsec_ta_open_session(ctx, &session_id); ++ if (ret) ++ return ret; ++ ++ /* Allow only writing complete 32-bits aligned words */ ++ if ((bytes % 4) || (offset % 4)) ++ return -EINVAL; ++ ++ memset(&arg, 0, sizeof(arg)); ++ memset(¶m, 0, sizeof(param)); ++ ++ arg.func = PTA_BSEC_WRITE_MEM; ++ arg.session = session_id; ++ arg.num_params = 2; ++ ++ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; ++ param[0].u.value.a = offset; ++ param[0].u.value.b = FUSE_ACCESS; ++ ++ shm = tee_shm_alloc_kernel_buf(ctx, bytes); ++ if (IS_ERR(shm)) { ++ ret = PTR_ERR(shm); ++ goto out_tee_session; ++ } ++ ++ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; ++ param[1].u.memref.shm = shm; ++ param[1].u.memref.size = bytes; ++ ++ shm_buf = tee_shm_get_va(shm, 0); ++ if (IS_ERR(shm_buf)) { ++ ret = PTR_ERR(shm_buf); ++ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); ++ tee_shm_free(shm); ++ ++ goto out_tee_session; ++ } ++ ++ memcpy(shm_buf, buf, bytes); ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret); ++ ++ /* Lock the upper OTPs with ECC protection, word programming only */ ++ if (!ret && ((offset + bytes) >= (lower * 4))) { ++ u32 start, nb_lock; ++ u32 *lock = (u32 *)shm_buf; ++ int i; ++ ++ /* ++ * don't lock the lower OTPs, no ECC protection and incremental ++ * bit programming, a second write is allowed ++ */ ++ start = max_t(u32, offset, lower * 4); ++ nb_lock = (offset + bytes - start) / 4; ++ ++ param[0].u.value.a = start; ++ param[0].u.value.b = LOCK_ACCESS; ++ param[1].u.memref.size = nb_lock * 4; ++ ++ for (i = 0; i < nb_lock; i++) ++ lock[i] = LOCK_PERM; ++ ++ ret = tee_client_invoke_func(ctx, &arg, param); ++ if (ret < 0 || arg.ret != 0) { ++ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); ++ if (!ret) ++ ret = -EIO; ++ } ++ pr_debug("Lock upper OTPs %d to %d, ret=%d\n", ++ start / 4, start / 4 + nb_lock, ret); ++ } ++ ++ tee_shm_free(shm); ++ ++out_tee_session: ++ stm32_bsec_ta_close_session(ctx, session_id); ++ ++ return ret; ++} +--- /dev/null ++++ b/drivers/nvmem/stm32-bsec-optee-ta.h +@@ -0,0 +1,80 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver ++ * ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ */ ++ ++#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) ++/** ++ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA ++ * @ctx: the OP-TEE context on success ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_open(struct tee_context **ctx); ++ ++/** ++ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA ++ * @ctx: the OP-TEE context ++ * ++ * This function used to clean the OP-TEE resources initialized in ++ * stm32_bsec_optee_ta_open(); it can be used as callback to ++ * devm_add_action_or_reset() ++ */ ++void stm32_bsec_optee_ta_close(void *ctx); ++ ++/** ++ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver ++ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open ++ * @offset: nvmem offset ++ * @buf: buffer to fill with nvem values ++ * @bytes: number of bytes to read ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, ++ void *buf, size_t bytes); ++ ++/** ++ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver ++ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open ++ * @lower: number of lower OTP, not protected by ECC ++ * @offset: nvmem offset ++ * @buf: buffer with nvem values ++ * @bytes: number of bytes to write ++ * ++ * Return: ++ * On success, 0. On failure, -errno. ++ */ ++int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, ++ unsigned int offset, void *buf, size_t bytes); ++ ++#else ++ ++static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void stm32_bsec_optee_ta_close(void *ctx) ++{ ++} ++ ++static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx, ++ unsigned int lower, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ return -EOPNOTSUPP; ++} ++#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */ +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -11,6 +11,9 @@ + #include + #include + #include ++#include ++ ++#include "stm32-bsec-optee-ta.h" + + /* BSEC secure service access from non-secure */ + #define STM32_SMC_BSEC 0x82001003 +@@ -25,12 +28,14 @@ + struct stm32_romem_cfg { + int size; + u8 lower; ++ bool ta; + }; + + struct stm32_romem_priv { + void __iomem *base; + struct nvmem_config cfg; + u8 lower; ++ struct tee_context *ctx; + }; + + static int stm32_romem_read(void *context, unsigned int offset, void *buf, +@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex + return 0; + } + ++static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ struct stm32_romem_priv *priv = context; ++ ++ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes); ++} ++ ++static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ struct stm32_romem_priv *priv = context; ++ ++ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); ++} ++ + static int stm32_romem_probe(struct platform_device *pdev) + { + const struct stm32_romem_cfg *cfg; + struct device *dev = &pdev->dev; + struct stm32_romem_priv *priv; + struct resource *res; ++ int rc; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) +@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat + } else { + priv->cfg.size = cfg->size; + priv->lower = cfg->lower; +- priv->cfg.reg_read = stm32_bsec_read; +- priv->cfg.reg_write = stm32_bsec_write; ++ if (cfg->ta) { ++ rc = stm32_bsec_optee_ta_open(&priv->ctx); ++ /* wait for OP-TEE client driver to be up and ready */ ++ if (rc) ++ return rc; ++ } ++ if (priv->ctx) { ++ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); ++ if (rc) { ++ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc); ++ return rc; ++ } ++ priv->cfg.reg_read = stm32_bsec_pta_read; ++ priv->cfg.reg_write = stm32_bsec_pta_write; ++ } else { ++ priv->cfg.reg_read = stm32_bsec_read; ++ priv->cfg.reg_write = stm32_bsec_write; ++ } + } + + return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); + } + + /* +- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) ++ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) + * => 96 x 32-bits data words + * - Lower: 1K bits, 2:1 redundancy, incremental bit programming + * => 32 (x 32-bits) lower shadow registers = words 0 to 31 +@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat + static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { + .size = 384, + .lower = 32, ++ .ta = false, ++}; ++ ++static const struct stm32_romem_cfg stm32mp13_bsec_cfg = { ++ .size = 384, ++ .lower = 32, ++ .ta = true, + }; + + static const struct of_device_id stm32_romem_of_match[] = { +@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r + .compatible = "st,stm32mp15-bsec", + .data = (void *)&stm32mp15_bsec_cfg, + }, { ++ .compatible = "st,stm32mp13-bsec", ++ .data = (void *)&stm32mp13_bsec_cfg, + }, ++ { /* sentinel */ }, + }; + MODULE_DEVICE_TABLE(of, stm32_romem_of_match); + diff --git a/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch b/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch new file mode 100644 index 000000000..cea8e9385 --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch @@ -0,0 +1,85 @@ +From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001 +From: Patrick Delaunay +Date: Mon, 6 Feb 2023 13:43:52 +0000 +Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x + +On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used; +the PTA BSEC should be used as it is done on STM32MP13x platform, +but the BSEC SMC can be also used: it is a legacy mode in OP-TEE, +not recommended but used in previous OP-TEE firmware. + +The presence of OP-TEE is dynamically detected in STM32MP15x device tree +and the supported NVMEM backend is dynamically detected: +- PTA with stm32_bsec_pta_find +- SMC with stm32_bsec_check + +With OP-TEE but without PTA and SMC detection, the probe is deferred for +STM32MP15x devices. + +On STM32MP13x platform, only the PTA is supported with cfg->ta = true +and this detection is skipped. + +Signed-off-by: Patrick Delaunay +Reviewed-by: Etienne Carriere +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++---- + 1 file changed, 34 insertions(+), 4 deletions(-) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co + return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); + } + ++static bool stm32_bsec_smc_check(void) ++{ ++ u32 val; ++ int ret; ++ ++ /* check that the OP-TEE support the BSEC SMC (legacy mode) */ ++ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val); ++ ++ return !ret; ++} ++ ++static bool optee_presence_check(void) ++{ ++ struct device_node *np; ++ bool tee_detected = false; ++ ++ /* check that the OP-TEE node is present and available. */ ++ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz"); ++ if (np && of_device_is_available(np)) ++ tee_detected = true; ++ of_node_put(np); ++ ++ return tee_detected; ++} ++ + static int stm32_romem_probe(struct platform_device *pdev) + { + const struct stm32_romem_cfg *cfg; +@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat + } else { + priv->cfg.size = cfg->size; + priv->lower = cfg->lower; +- if (cfg->ta) { ++ if (cfg->ta || optee_presence_check()) { + rc = stm32_bsec_optee_ta_open(&priv->ctx); +- /* wait for OP-TEE client driver to be up and ready */ +- if (rc) +- return rc; ++ if (rc) { ++ /* wait for OP-TEE client driver to be up and ready */ ++ if (rc == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ /* BSEC PTA is required or SMC not supported */ ++ if (cfg->ta || !stm32_bsec_smc_check()) ++ return rc; ++ } + } + if (priv->ctx) { + rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); diff --git a/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch b/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch new file mode 100644 index 000000000..9d6275a73 --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch @@ -0,0 +1,32 @@ +From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Mon, 6 Feb 2023 13:43:53 +0000 +Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning + +Convert an empty line to " *" to avoid a kernel-doc warning: + +drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line: + +Signed-off-by: Randy Dunlap +Cc: Srinivas Kandagatla +Cc: Andrey Vostrikov +Cc: Nikita Yushchenko +Cc: Andrey Smirnov +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/rave-sp-eeprom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/rave-sp-eeprom.c ++++ b/drivers/nvmem/rave-sp-eeprom.c +@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size { + * @type: Access type (see enum rave_sp_eeprom_access_type) + * @success: Success flag (Success = 1, Failure = 0) + * @data: Read data +- ++ * + * Note this structure corresponds to RSP_*_EEPROM payload from RAVE + * SP ICD + */ diff --git a/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch b/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch new file mode 100644 index 000000000..1ab9e609d --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch @@ -0,0 +1,43 @@ +From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 6 Feb 2023 13:43:54 +0000 +Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time + +There are currently no in-tree users of the Qualcomm SDAM nvmem driver +and there is generally no point in registering a driver that can be +built as a module at subsys init time. + +Register the driver at the normal device init time instead and let +driver core sort out the probe order. + +Signed-off-by: Johan Hovold +Reviewed-by: Bjorn Andersson +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/qcom-spmi-sdam.c | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +--- a/drivers/nvmem/qcom-spmi-sdam.c ++++ b/drivers/nvmem/qcom-spmi-sdam.c +@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive + }, + .probe = sdam_probe, + }; +- +-static int __init sdam_init(void) +-{ +- return platform_driver_register(&sdam_driver); +-} +-subsys_initcall(sdam_init); +- +-static void __exit sdam_exit(void) +-{ +- return platform_driver_unregister(&sdam_driver); +-} +-module_exit(sdam_exit); ++module_platform_driver(sdam_driver); + + MODULE_DESCRIPTION("QCOM SPMI SDAM driver"); + MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch b/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch new file mode 100644 index 000000000..dcf704c6f --- /dev/null +++ b/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch @@ -0,0 +1,46 @@ +From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 6 Feb 2023 13:43:56 +0000 +Subject: [PATCH] nvmem: stm32: fix OPTEE dependency + +The stm32 nvmem driver fails to link as built-in when OPTEE +is a loadable module: + +aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: +stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session' +aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: +stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context' + +Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only +be built-in if OPTEE is either built-in or disabled, and +make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE + will be called nvmem-sprd-efuse. + + config NVMEM_STM32_BSEC_OPTEE_TA +- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" +- depends on OPTEE ++ def_bool NVMEM_STM32_ROMEM && OPTEE + help + Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE + trusted application STM32MP BSEC. +@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA + config NVMEM_STM32_ROMEM + tristate "STMicroelectronics STM32 factory-programmed memory support" + depends on ARCH_STM32 || COMPILE_TEST +- imply NVMEM_STM32_BSEC_OPTEE_TA ++ depends on OPTEE || !OPTEE + help + Say y here to enable read-only access for STMicroelectronics STM32 + factory-programmed memory area. diff --git a/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch b/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch new file mode 100644 index 000000000..8328e87c0 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch @@ -0,0 +1,35 @@ +From bcd1fe07def0f070eb5f31594620aaee6f81d31a Mon Sep 17 00:00:00 2001 +From: Nick Alcock +Date: Tue, 4 Apr 2023 18:21:11 +0100 +Subject: [PATCH] nvmem: xilinx: zynqmp: make modular + +This driver has a MODULE_LICENSE but is not tristate so cannot be +built as a module, unlike all its peers: make it modular to match. + +Signed-off-by: Nick Alcock +Suggested-by: Michal Simek +Cc: Luis Chamberlain +Cc: linux-modules@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Cc: Hitomi Hasegawa +Cc: Srinivas Kandagatla +Cc: Michal Simek +Cc: linux-arm-kernel@lists.infradead.org +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-4-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -368,7 +368,7 @@ config NVMEM_VF610_OCOTP + be called nvmem-vf610-ocotp. + + config NVMEM_ZYNQMP +- bool "Xilinx ZYNQMP SoC nvmem firmware support" ++ tristate "Xilinx ZYNQMP SoC nvmem firmware support" + depends on ARCH_ZYNQMP + help + This is a driver to access hardware related data like diff --git a/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch b/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch new file mode 100644 index 000000000..94cd23c18 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch @@ -0,0 +1,387 @@ +From 266570f496b90dea8fda893c2cf7c28d63ae2bd9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:21 +0100 +Subject: [PATCH] nvmem: core: introduce NVMEM layouts + +NVMEM layouts are used to generate NVMEM cells during runtime. Think of +an EEPROM with a well-defined conent. For now, the content can be +described by a device tree or a board file. But this only works if the +offsets and lengths are static and don't change. One could also argue +that putting the layout of the EEPROM in the device tree is the wrong +place. Instead, the device tree should just have a specific compatible +string. + +Right now there are two use cases: + (1) The NVMEM cell needs special processing. E.g. if it only specifies + a base MAC address offset and you need to add an offset, or it + needs to parse a MAC from ASCII format or some proprietary format. + (Post processing of cells is added in a later commit). + (2) u-boot environment parsing. The cells don't have a particular + offset but it needs parsing the content to determine the offsets + and length. + +Co-developed-by: Miquel Raynal +Signed-off-by: Miquel Raynal +Signed-off-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-14-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/driver-api/nvmem.rst | 15 ++++ + drivers/nvmem/Kconfig | 4 + + drivers/nvmem/Makefile | 1 + + drivers/nvmem/core.c | 120 +++++++++++++++++++++++++++++ + drivers/nvmem/layouts/Kconfig | 5 ++ + drivers/nvmem/layouts/Makefile | 4 + + include/linux/nvmem-consumer.h | 7 ++ + include/linux/nvmem-provider.h | 51 ++++++++++++ + 8 files changed, 207 insertions(+) + create mode 100644 drivers/nvmem/layouts/Kconfig + create mode 100644 drivers/nvmem/layouts/Makefile + +--- a/Documentation/driver-api/nvmem.rst ++++ b/Documentation/driver-api/nvmem.rst +@@ -185,3 +185,18 @@ ex:: + ===================== + + See Documentation/devicetree/bindings/nvmem/nvmem.txt ++ ++8. NVMEM layouts ++================ ++ ++NVMEM layouts are yet another mechanism to create cells. With the device ++tree binding it is possible to specify simple cells by using an offset ++and a length. Sometimes, the cells doesn't have a static offset, but ++the content is still well defined, e.g. tag-length-values. In this case, ++the NVMEM device content has to be first parsed and the cells need to ++be added accordingly. Layouts let you read the content of the NVMEM device ++and let you add cells dynamically. ++ ++Another use case for layouts is the post processing of cells. With layouts, ++it is possible to associate a custom post processing hook to a cell. It ++even possible to add this hook to cells not created by the layout itself. +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -21,6 +21,10 @@ config NVMEM_SYSFS + This interface is mostly used by userspace applications to + read/write directly into nvmem. + ++# Layouts ++ ++source "drivers/nvmem/layouts/Kconfig" ++ + # Devices + + config NVMEM_APPLE_EFUSES +--- a/drivers/nvmem/Makefile ++++ b/drivers/nvmem/Makefile +@@ -5,6 +5,7 @@ + + obj-$(CONFIG_NVMEM) += nvmem_core.o + nvmem_core-y := core.o ++obj-y += layouts/ + + # Devices + obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -40,6 +40,7 @@ struct nvmem_device { + nvmem_reg_write_t reg_write; + nvmem_cell_post_process_t cell_post_process; + struct gpio_desc *wp_gpio; ++ struct nvmem_layout *layout; + void *priv; + }; + +@@ -74,6 +75,9 @@ static LIST_HEAD(nvmem_lookup_list); + + static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); + ++static DEFINE_SPINLOCK(nvmem_layout_lock); ++static LIST_HEAD(nvmem_layouts); ++ + static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, + void *val, size_t bytes) + { +@@ -728,6 +732,101 @@ static int nvmem_add_cells_from_of(struc + return 0; + } + ++int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) ++{ ++ layout->owner = owner; ++ ++ spin_lock(&nvmem_layout_lock); ++ list_add(&layout->node, &nvmem_layouts); ++ spin_unlock(&nvmem_layout_lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__nvmem_layout_register); ++ ++void nvmem_layout_unregister(struct nvmem_layout *layout) ++{ ++ spin_lock(&nvmem_layout_lock); ++ list_del(&layout->node); ++ spin_unlock(&nvmem_layout_lock); ++} ++EXPORT_SYMBOL_GPL(nvmem_layout_unregister); ++ ++static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) ++{ ++ struct device_node *layout_np, *np = nvmem->dev.of_node; ++ struct nvmem_layout *l, *layout = NULL; ++ ++ layout_np = of_get_child_by_name(np, "nvmem-layout"); ++ if (!layout_np) ++ return NULL; ++ ++ spin_lock(&nvmem_layout_lock); ++ ++ list_for_each_entry(l, &nvmem_layouts, node) { ++ if (of_match_node(l->of_match_table, layout_np)) { ++ if (try_module_get(l->owner)) ++ layout = l; ++ ++ break; ++ } ++ } ++ ++ spin_unlock(&nvmem_layout_lock); ++ of_node_put(layout_np); ++ ++ return layout; ++} ++ ++static void nvmem_layout_put(struct nvmem_layout *layout) ++{ ++ if (layout) ++ module_put(layout->owner); ++} ++ ++static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem) ++{ ++ struct nvmem_layout *layout = nvmem->layout; ++ int ret; ++ ++ if (layout && layout->add_cells) { ++ ret = layout->add_cells(&nvmem->dev, nvmem, layout); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++#if IS_ENABLED(CONFIG_OF) ++/** ++ * of_nvmem_layout_get_container() - Get OF node to layout container. ++ * ++ * @nvmem: nvmem device. ++ * ++ * Return: a node pointer with refcount incremented or NULL if no ++ * container exists. Use of_node_put() on it when done. ++ */ ++struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) ++{ ++ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); ++} ++EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); ++#endif ++ ++const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ struct device_node __maybe_unused *layout_np; ++ const struct of_device_id *match; ++ ++ layout_np = of_nvmem_layout_get_container(nvmem); ++ match = of_match_node(layout->of_match_table, layout_np); ++ ++ return match ? match->data : NULL; ++} ++EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data); ++ + /** + * nvmem_register() - Register a nvmem device for given nvmem_config. + * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem +@@ -834,6 +933,12 @@ struct nvmem_device *nvmem_register(cons + goto err_put_device; + } + ++ /* ++ * If the driver supplied a layout by config->layout, the module ++ * pointer will be NULL and nvmem_layout_put() will be a noop. ++ */ ++ nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); ++ + if (config->cells) { + rval = nvmem_add_cells(nvmem, config->cells, config->ncells); + if (rval) +@@ -854,12 +959,17 @@ struct nvmem_device *nvmem_register(cons + if (rval) + goto err_remove_cells; + ++ rval = nvmem_add_cells_from_layout(nvmem); ++ if (rval) ++ goto err_remove_cells; ++ + blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); + + return nvmem; + + err_remove_cells: + nvmem_device_remove_all_cells(nvmem); ++ nvmem_layout_put(nvmem->layout); + if (config->compat) + nvmem_sysfs_remove_compat(nvmem, config); + err_put_device: +@@ -881,6 +991,7 @@ static void nvmem_device_release(struct + device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); + + nvmem_device_remove_all_cells(nvmem); ++ nvmem_layout_put(nvmem->layout); + device_unregister(&nvmem->dev); + } + +@@ -1246,6 +1357,15 @@ struct nvmem_cell *of_nvmem_cell_get(str + return ERR_PTR(-EINVAL); + } + ++ /* nvmem layouts produce cells within the nvmem-layout container */ ++ if (of_node_name_eq(nvmem_np, "nvmem-layout")) { ++ nvmem_np = of_get_next_parent(nvmem_np); ++ if (!nvmem_np) { ++ of_node_put(cell_np); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ + nvmem = __nvmem_device_get(nvmem_np, device_match_of_node); + of_node_put(nvmem_np); + if (IS_ERR(nvmem)) { +--- /dev/null ++++ b/drivers/nvmem/layouts/Kconfig +@@ -0,0 +1,5 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++menu "Layout Types" ++ ++endmenu +--- /dev/null ++++ b/drivers/nvmem/layouts/Makefile +@@ -0,0 +1,4 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Makefile for nvmem layouts. ++# +--- a/include/linux/nvmem-consumer.h ++++ b/include/linux/nvmem-consumer.h +@@ -239,6 +239,7 @@ struct nvmem_cell *of_nvmem_cell_get(str + const char *id); + struct nvmem_device *of_nvmem_device_get(struct device_node *np, + const char *name); ++struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); + #else + static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, + const char *id) +@@ -251,6 +252,12 @@ static inline struct nvmem_device *of_nv + { + return ERR_PTR(-EOPNOTSUPP); + } ++ ++static inline struct device_node * ++of_nvmem_layout_get_container(struct nvmem_device *nvmem) ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} + #endif /* CONFIG_NVMEM && CONFIG_OF */ + + #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */ +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -88,6 +88,7 @@ struct nvmem_cell_info { + * @stride: Minimum read/write access stride. + * @priv: User context passed to read/write callbacks. + * @ignore_wp: Write Protect pin is managed by the provider. ++ * @layout: Fixed layout associated with this nvmem device. + * + * Note: A default "nvmem" name will be assigned to the device if + * no name is specified in its configuration. In such case "" is +@@ -109,6 +110,7 @@ struct nvmem_config { + bool read_only; + bool root_only; + bool ignore_wp; ++ struct nvmem_layout *layout; + struct device_node *of_node; + bool no_of_node; + nvmem_reg_read_t reg_read; +@@ -142,6 +144,33 @@ struct nvmem_cell_table { + struct list_head node; + }; + ++/** ++ * struct nvmem_layout - NVMEM layout definitions ++ * ++ * @name: Layout name. ++ * @of_match_table: Open firmware match table. ++ * @add_cells: Will be called if a nvmem device is found which ++ * has this layout. The function will add layout ++ * specific cells with nvmem_add_one_cell(). ++ * @owner: Pointer to struct module. ++ * @node: List node. ++ * ++ * A nvmem device can hold a well defined structure which can just be ++ * evaluated during runtime. For example a TLV list, or a list of "name=val" ++ * pairs. A nvmem layout can parse the nvmem device and add appropriate ++ * cells. ++ */ ++struct nvmem_layout { ++ const char *name; ++ const struct of_device_id *of_match_table; ++ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout); ++ ++ /* private */ ++ struct module *owner; ++ struct list_head node; ++}; ++ + #if IS_ENABLED(CONFIG_NVMEM) + + struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); +@@ -156,6 +185,14 @@ void nvmem_del_cell_table(struct nvmem_c + int nvmem_add_one_cell(struct nvmem_device *nvmem, + const struct nvmem_cell_info *info); + ++int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner); ++#define nvmem_layout_register(layout) \ ++ __nvmem_layout_register(layout, THIS_MODULE) ++void nvmem_layout_unregister(struct nvmem_layout *layout); ++ ++const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout); ++ + #else + + static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) +@@ -179,5 +216,19 @@ static inline int nvmem_add_one_cell(str + return -EOPNOTSUPP; + } + ++static inline int nvmem_layout_register(struct nvmem_layout *layout) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} ++ ++static inline const void * ++nvmem_layout_get_match_data(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ return NULL; ++} ++ + #endif /* CONFIG_NVMEM */ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch new file mode 100644 index 000000000..6fa7b6382 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch @@ -0,0 +1,61 @@ +From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:22 +0100 +Subject: [PATCH] nvmem: core: handle the absence of expected layouts + +Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout +is not available. This condition cannot be triggered today as nvmem +layout drivers are initialed as part of an early init call, but soon +these drivers will be converted into modules and be initialized with a +standard priority, so the unavailability of the drivers might become a +reality that must be taken care of. + +Let's anticipate this by telling the caller the layout might not yet be +available. A probe deferral is requested in this case. + +Please note this does not affect any nvmem device not using layouts, +because an early check against the "nvmem-layout" container presence +will return NULL in this case. + +Signed-off-by: Miquel Raynal +Tested-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste + static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) + { + struct device_node *layout_np, *np = nvmem->dev.of_node; +- struct nvmem_layout *l, *layout = NULL; ++ struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); + + layout_np = of_get_child_by_name(np, "nvmem-layout"); + if (!layout_np) +@@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons + * pointer will be NULL and nvmem_layout_put() will be a noop. + */ + nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); ++ if (IS_ERR(nvmem->layout)) { ++ rval = PTR_ERR(nvmem->layout); ++ nvmem->layout = NULL; ++ ++ if (rval == -EPROBE_DEFER) ++ goto err_teardown_compat; ++ } + + if (config->cells) { + rval = nvmem_add_cells(nvmem, config->cells, config->ncells); +@@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons + err_remove_cells: + nvmem_device_remove_all_cells(nvmem); + nvmem_layout_put(nvmem->layout); ++err_teardown_compat: + if (config->compat) + nvmem_sysfs_remove_compat(nvmem, config); + err_put_device: diff --git a/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch b/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch new file mode 100644 index 000000000..b9341666f --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch @@ -0,0 +1,52 @@ +From b1c37bec1ccfe5ccab72bc0ddc0dfa45c43e2de2 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:23 +0100 +Subject: [PATCH] nvmem: core: request layout modules loading + +When a storage device like an eeprom or an mtd device probes, it +registers an nvmem device if the nvmem subsystem has been enabled (bool +symbol). During nvmem registration, if the device is using layouts to +expose dynamic nvmem cells, the core will first try to get a reference +over the layout driver callbacks. In practice there is not relationship +that can be described between the storage driver and the nvmem +layout. So there is no way we can enforce both drivers will be built-in +or both will be modules. If the storage device driver is built-in but +the layout is built as a module, instead of badly failing with an +endless probe deferral loop, lets just make a modprobe call in case the +driver was made available in an initramfs with +of_device_node_request_module(), and offer a fully functional system to +the user. + +Signed-off-by: Miquel Raynal +Tested-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-16-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + + struct nvmem_device { +@@ -761,6 +762,13 @@ static struct nvmem_layout *nvmem_layout + if (!layout_np) + return NULL; + ++ /* ++ * In case the nvmem device was built-in while the layout was built as a ++ * module, we shall manually request the layout driver loading otherwise ++ * we'll never have any match. ++ */ ++ of_request_module(layout_np); ++ + spin_lock(&nvmem_layout_lock); + + list_for_each_entry(l, &nvmem_layouts, node) { diff --git a/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch b/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch new file mode 100644 index 000000000..53628cd4e --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch @@ -0,0 +1,86 @@ +From 345ec382cd4b736c36e01f155d08c913b225b736 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:24 +0100 +Subject: [PATCH] nvmem: core: add per-cell post processing + +Instead of relying on the name the consumer is using for the cell, like +it is done for the nvmem .cell_post_process configuration parameter, +provide a per-cell post processing hook. This can then be populated by +the NVMEM provider (or the NVMEM layout) when adding the cell. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-17-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 17 +++++++++++++++++ + include/linux/nvmem-provider.h | 3 +++ + 2 files changed, 20 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -54,6 +54,7 @@ struct nvmem_cell_entry { + int bytes; + int bit_offset; + int nbits; ++ nvmem_cell_post_process_t read_post_process; + struct device_node *np; + struct nvmem_device *nvmem; + struct list_head node; +@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell + cell->offset = info->offset; + cell->bytes = info->bytes; + cell->name = info->name; ++ cell->read_post_process = info->read_post_process; + + cell->bit_offset = info->bit_offset; + cell->nbits = info->nbits; +@@ -1563,6 +1565,13 @@ static int __nvmem_cell_read(struct nvme + if (cell->bit_offset || cell->nbits) + nvmem_shift_read_buffer_in_place(cell, buf); + ++ if (cell->read_post_process) { ++ rc = cell->read_post_process(nvmem->priv, id, index, ++ cell->offset, buf, cell->bytes); ++ if (rc) ++ return rc; ++ } ++ + if (nvmem->cell_post_process) { + rc = nvmem->cell_post_process(nvmem->priv, id, index, + cell->offset, buf, cell->bytes); +@@ -1671,6 +1680,14 @@ static int __nvmem_cell_entry_write(stru + (cell->bit_offset == 0 && len != cell->bytes)) + return -EINVAL; + ++ /* ++ * Any cells which have a read_post_process hook are read-only because ++ * we cannot reverse the operation and it might affect other cells, ++ * too. ++ */ ++ if (cell->read_post_process) ++ return -EINVAL; ++ + if (cell->bit_offset || cell->nbits) { + buf = nvmem_cell_prepare_write_buffer(cell, buf, len); + if (IS_ERR(buf)) +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -54,6 +54,8 @@ struct nvmem_keepout { + * @bit_offset: Bit offset if cell is smaller than a byte. + * @nbits: Number of bits. + * @np: Optional device_node pointer. ++ * @read_post_process: Callback for optional post processing of cell data ++ * on reads. + */ + struct nvmem_cell_info { + const char *name; +@@ -62,6 +64,7 @@ struct nvmem_cell_info { + unsigned int bit_offset; + unsigned int nbits; + struct device_node *np; ++ nvmem_cell_post_process_t read_post_process; + }; + + /** diff --git a/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch b/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch new file mode 100644 index 000000000..32990148c --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch @@ -0,0 +1,59 @@ +From de12c9691501ccba41a154c223869f82be4c12fd Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:25 +0100 +Subject: [PATCH] nvmem: core: allow to modify a cell before adding it + +Provide a way to modify a cell before it will get added. This is useful +to attach a custom post processing hook via a layout. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-18-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 4 ++++ + include/linux/nvmem-provider.h | 5 +++++ + 2 files changed, 9 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -695,6 +695,7 @@ static int nvmem_validate_keepouts(struc + + static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) + { ++ struct nvmem_layout *layout = nvmem->layout; + struct device *dev = &nvmem->dev; + struct device_node *child; + const __be32 *addr; +@@ -724,6 +725,9 @@ static int nvmem_add_cells_from_of(struc + + info.np = of_node_get(child); + ++ if (layout && layout->fixup_cell_info) ++ layout->fixup_cell_info(nvmem, layout, &info); ++ + ret = nvmem_add_one_cell(nvmem, &info); + kfree(info.name); + if (ret) { +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -155,6 +155,8 @@ struct nvmem_cell_table { + * @add_cells: Will be called if a nvmem device is found which + * has this layout. The function will add layout + * specific cells with nvmem_add_one_cell(). ++ * @fixup_cell_info: Will be called before a cell is added. Can be ++ * used to modify the nvmem_cell_info. + * @owner: Pointer to struct module. + * @node: List node. + * +@@ -168,6 +170,9 @@ struct nvmem_layout { + const struct of_device_id *of_match_table; + int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, + struct nvmem_layout *layout); ++ void (*fixup_cell_info)(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell); + + /* private */ + struct module *owner; diff --git a/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch b/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch new file mode 100644 index 000000000..2a5fa618e --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch @@ -0,0 +1,81 @@ +From 6c56a82d7895a213a43182a5d01a21a906a79847 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:26 +0100 +Subject: [PATCH] nvmem: imx-ocotp: replace global post processing with layouts + +In preparation of retiring the global post processing hook change this +driver to use layouts. The layout will be supplied during registration +and will be used to add the post processing hook to all added cells. + +Signed-off-by: Michael Walle +Tested-by: Michael Walle # on kontron-pitx-imx8m +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-19-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/imx-ocotp.c | 30 +++++++++++++++++++----------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -225,18 +225,13 @@ read_end: + static int imx_ocotp_cell_pp(void *context, const char *id, int index, + unsigned int offset, void *data, size_t bytes) + { +- struct ocotp_priv *priv = context; ++ u8 *buf = data; ++ int i; + + /* Deal with some post processing of nvmem cell data */ +- if (id && !strcmp(id, "mac-address")) { +- if (priv->params->reverse_mac_address) { +- u8 *buf = data; +- int i; +- +- for (i = 0; i < bytes/2; i++) +- swap(buf[i], buf[bytes - i - 1]); +- } +- } ++ if (id && !strcmp(id, "mac-address")) ++ for (i = 0; i < bytes / 2; i++) ++ swap(buf[i], buf[bytes - i - 1]); + + return 0; + } +@@ -488,7 +483,6 @@ static struct nvmem_config imx_ocotp_nvm + .stride = 1, + .reg_read = imx_ocotp_read, + .reg_write = imx_ocotp_write, +- .cell_post_process = imx_ocotp_cell_pp, + }; + + static const struct ocotp_params imx6q_params = { +@@ -595,6 +589,17 @@ static const struct of_device_id imx_oco + }; + MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); + ++static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell) ++{ ++ cell->read_post_process = imx_ocotp_cell_pp; ++} ++ ++struct nvmem_layout imx_ocotp_layout = { ++ .fixup_cell_info = imx_ocotp_fixup_cell_info, ++}; ++ + static int imx_ocotp_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -619,6 +624,9 @@ static int imx_ocotp_probe(struct platfo + imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; + imx_ocotp_nvmem_config.dev = dev; + imx_ocotp_nvmem_config.priv = priv; ++ if (priv->params->reverse_mac_address) ++ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; ++ + priv->config = &imx_ocotp_nvmem_config; + + clk_prepare_enable(priv->clk); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch b/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch new file mode 100644 index 000000000..eac202b88 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch @@ -0,0 +1,68 @@ +From 011e40a166fdaa65fb9946b7cd91efec85b70dbb Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:27 +0100 +Subject: [PATCH] nvmem: cell: drop global cell_post_process + +There are no users anymore for the global cell_post_process callback +anymore. New users should use proper nvmem layouts. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-20-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 9 --------- + include/linux/nvmem-provider.h | 2 -- + 2 files changed, 11 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -39,7 +39,6 @@ struct nvmem_device { + unsigned int nkeepout; + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; +- nvmem_cell_post_process_t cell_post_process; + struct gpio_desc *wp_gpio; + struct nvmem_layout *layout; + void *priv; +@@ -903,7 +902,6 @@ struct nvmem_device *nvmem_register(cons + nvmem->type = config->type; + nvmem->reg_read = config->reg_read; + nvmem->reg_write = config->reg_write; +- nvmem->cell_post_process = config->cell_post_process; + nvmem->keepout = config->keepout; + nvmem->nkeepout = config->nkeepout; + if (config->of_node) +@@ -1575,13 +1573,6 @@ static int __nvmem_cell_read(struct nvme + if (rc) + return rc; + } +- +- if (nvmem->cell_post_process) { +- rc = nvmem->cell_post_process(nvmem->priv, id, index, +- cell->offset, buf, cell->bytes); +- if (rc) +- return rc; +- } + + if (len) + *len = cell->bytes; +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -85,7 +85,6 @@ struct nvmem_cell_info { + * @no_of_node: Device should not use the parent's of_node even if it's !NULL. + * @reg_read: Callback to read data. + * @reg_write: Callback to write data. +- * @cell_post_process: Callback for vendor specific post processing of cell data + * @size: Device size. + * @word_size: Minimum read/write access granularity. + * @stride: Minimum read/write access stride. +@@ -118,7 +117,6 @@ struct nvmem_config { + bool no_of_node; + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; +- nvmem_cell_post_process_t cell_post_process; + int size; + int word_size; + int stride; diff --git a/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch b/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch new file mode 100644 index 000000000..46b30a2ed --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch @@ -0,0 +1,76 @@ +From 8a134fd9f9323f4c39ec27055b3d3723cfb5c1e9 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:28 +0100 +Subject: [PATCH] nvmem: core: provide own priv pointer in post process + callback + +It doesn't make any more sense to have a opaque pointer set up by the +nvmem device. Usually, the layout isn't associated with a particular +nvmem device. Instead, let the caller who set the post process callback +provide the priv pointer. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-21-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 4 +++- + include/linux/nvmem-provider.h | 5 ++++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -54,6 +54,7 @@ struct nvmem_cell_entry { + int bit_offset; + int nbits; + nvmem_cell_post_process_t read_post_process; ++ void *priv; + struct device_node *np; + struct nvmem_device *nvmem; + struct list_head node; +@@ -471,6 +472,7 @@ static int nvmem_cell_info_to_nvmem_cell + cell->bytes = info->bytes; + cell->name = info->name; + cell->read_post_process = info->read_post_process; ++ cell->priv = info->priv; + + cell->bit_offset = info->bit_offset; + cell->nbits = info->nbits; +@@ -1568,7 +1570,7 @@ static int __nvmem_cell_read(struct nvme + nvmem_shift_read_buffer_in_place(cell, buf); + + if (cell->read_post_process) { +- rc = cell->read_post_process(nvmem->priv, id, index, ++ rc = cell->read_post_process(cell->priv, id, index, + cell->offset, buf, cell->bytes); + if (rc) + return rc; +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -20,7 +20,8 @@ typedef int (*nvmem_reg_write_t)(void *p + void *val, size_t bytes); + /* used for vendor specific post processing of cell data */ + typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, +- unsigned int offset, void *buf, size_t bytes); ++ unsigned int offset, void *buf, ++ size_t bytes); + + enum nvmem_type { + NVMEM_TYPE_UNKNOWN = 0, +@@ -56,6 +57,7 @@ struct nvmem_keepout { + * @np: Optional device_node pointer. + * @read_post_process: Callback for optional post processing of cell data + * on reads. ++ * @priv: Opaque data passed to the read_post_process hook. + */ + struct nvmem_cell_info { + const char *name; +@@ -65,6 +67,7 @@ struct nvmem_cell_info { + unsigned int nbits; + struct device_node *np; + nvmem_cell_post_process_t read_post_process; ++ void *priv; + }; + + /** diff --git a/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch new file mode 100644 index 000000000..7d97658b6 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch @@ -0,0 +1,215 @@ +From d9fae023fe86069750092fc1c2f3a73e2fb18512 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 4 Apr 2023 18:21:29 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: Add new layout driver + +This layout applies to the VPD of the Kontron sl28 boards. The VPD only +contains a base MAC address. Therefore, we have to add an individual +offset to it. This is done by taking the second argument of the nvmem +phandle into account. Also this let us checking the VPD version and the +checksum. + +Signed-off-by: Michael Walle +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-22-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/Kconfig | 9 ++ + drivers/nvmem/layouts/Makefile | 2 + + drivers/nvmem/layouts/sl28vpd.c | 165 ++++++++++++++++++++++++++++++++ + 3 files changed, 176 insertions(+) + create mode 100644 drivers/nvmem/layouts/sl28vpd.c + +--- a/drivers/nvmem/layouts/Kconfig ++++ b/drivers/nvmem/layouts/Kconfig +@@ -2,4 +2,13 @@ + + menu "Layout Types" + ++config NVMEM_LAYOUT_SL28_VPD ++ tristate "Kontron sl28 VPD layout support" ++ select CRC8 ++ help ++ Say Y here if you want to support the VPD layout of the Kontron ++ SMARC-sAL28 boards. ++ ++ If unsure, say N. ++ + endmenu +--- a/drivers/nvmem/layouts/Makefile ++++ b/drivers/nvmem/layouts/Makefile +@@ -2,3 +2,5 @@ + # + # Makefile for nvmem layouts. + # ++ ++obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o +--- /dev/null ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -0,0 +1,165 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SL28VPD_MAGIC 'V' ++ ++struct sl28vpd_header { ++ u8 magic; ++ u8 version; ++} __packed; ++ ++struct sl28vpd_v1 { ++ struct sl28vpd_header header; ++ char serial_number[15]; ++ u8 base_mac_address[ETH_ALEN]; ++ u8 crc8; ++} __packed; ++ ++static int sl28vpd_mac_address_pp(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ if (bytes != ETH_ALEN) ++ return -EINVAL; ++ ++ if (index < 0) ++ return -EINVAL; ++ ++ if (!is_valid_ether_addr(buf)) ++ return -EINVAL; ++ ++ eth_addr_add(buf, index); ++ ++ return 0; ++} ++ ++static const struct nvmem_cell_info sl28vpd_v1_entries[] = { ++ { ++ .name = "serial-number", ++ .offset = offsetof(struct sl28vpd_v1, serial_number), ++ .bytes = sizeof_field(struct sl28vpd_v1, serial_number), ++ }, ++ { ++ .name = "base-mac-address", ++ .offset = offsetof(struct sl28vpd_v1, base_mac_address), ++ .bytes = sizeof_field(struct sl28vpd_v1, base_mac_address), ++ .read_post_process = sl28vpd_mac_address_pp, ++ }, ++}; ++ ++static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem) ++{ ++ struct sl28vpd_v1 data_v1; ++ u8 table[CRC8_TABLE_SIZE]; ++ int ret; ++ u8 crc; ++ ++ crc8_populate_msb(table, 0x07); ++ ++ ret = nvmem_device_read(nvmem, 0, sizeof(data_v1), &data_v1); ++ if (ret < 0) ++ return ret; ++ else if (ret != sizeof(data_v1)) ++ return -EIO; ++ ++ crc = crc8(table, (void *)&data_v1, sizeof(data_v1) - 1, 0); ++ ++ if (crc != data_v1.crc8) { ++ dev_err(dev, ++ "Checksum is invalid (got %02x, expected %02x).\n", ++ crc, data_v1.crc8); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ const struct nvmem_cell_info *pinfo; ++ struct nvmem_cell_info info = {0}; ++ struct device_node *layout_np; ++ struct sl28vpd_header hdr; ++ int ret, i; ++ ++ /* check header */ ++ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); ++ if (ret < 0) ++ return ret; ++ else if (ret != sizeof(hdr)) ++ return -EIO; ++ ++ if (hdr.magic != SL28VPD_MAGIC) { ++ dev_err(dev, "Invalid magic value (%02x)\n", hdr.magic); ++ return -EINVAL; ++ } ++ ++ if (hdr.version != 1) { ++ dev_err(dev, "Version %d is unsupported.\n", hdr.version); ++ return -EINVAL; ++ } ++ ++ ret = sl28vpd_v1_check_crc(dev, nvmem); ++ if (ret) ++ return ret; ++ ++ layout_np = of_nvmem_layout_get_container(nvmem); ++ if (!layout_np) ++ return -ENOENT; ++ ++ for (i = 0; i < ARRAY_SIZE(sl28vpd_v1_entries); i++) { ++ pinfo = &sl28vpd_v1_entries[i]; ++ ++ info.name = pinfo->name; ++ info.offset = pinfo->offset; ++ info.bytes = pinfo->bytes; ++ info.read_post_process = pinfo->read_post_process; ++ info.np = of_get_child_by_name(layout_np, pinfo->name); ++ ++ ret = nvmem_add_one_cell(nvmem, &info); ++ if (ret) { ++ of_node_put(layout_np); ++ return ret; ++ } ++ } ++ ++ of_node_put(layout_np); ++ ++ return 0; ++} ++ ++static const struct of_device_id sl28vpd_of_match_table[] = { ++ { .compatible = "kontron,sl28-vpd" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); ++ ++struct nvmem_layout sl28vpd_layout = { ++ .name = "sl28-vpd", ++ .of_match_table = sl28vpd_of_match_table, ++ .add_cells = sl28vpd_add_cells, ++}; ++ ++static int __init sl28vpd_init(void) ++{ ++ return nvmem_layout_register(&sl28vpd_layout); ++} ++ ++static void __exit sl28vpd_exit(void) ++{ ++ nvmem_layout_unregister(&sl28vpd_layout); ++} ++ ++module_init(sl28vpd_init); ++module_exit(sl28vpd_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Michael Walle "); ++MODULE_DESCRIPTION("NVMEM layout driver for the VPD of Kontron sl28 boards"); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch new file mode 100644 index 000000000..ca8b4bc06 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch @@ -0,0 +1,306 @@ +From d3c0d12f6474216bf386101e2449cc73e5c5b61d Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:31 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Add new layout driver + +This layout applies on top of any non volatile storage device containing +an ONIE table factory flashed. This table follows the tlv +(type-length-value) organization described in the link below. We cannot +afford using regular parsers because the content of these tables is +manufacturer specific and must be dynamically discovered. + +Link: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-24-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/Kconfig | 9 ++ + drivers/nvmem/layouts/Makefile | 1 + + drivers/nvmem/layouts/onie-tlv.c | 257 +++++++++++++++++++++++++++++++ + 3 files changed, 267 insertions(+) + create mode 100644 drivers/nvmem/layouts/onie-tlv.c + +--- a/drivers/nvmem/layouts/Kconfig ++++ b/drivers/nvmem/layouts/Kconfig +@@ -11,4 +11,13 @@ config NVMEM_LAYOUT_SL28_VPD + + If unsure, say N. + ++config NVMEM_LAYOUT_ONIE_TLV ++ tristate "ONIE tlv support" ++ select CRC32 ++ help ++ Say Y here if you want to support the Open Compute Project ONIE ++ Type-Length-Value standard table. ++ ++ If unsure, say N. ++ + endmenu +--- a/drivers/nvmem/layouts/Makefile ++++ b/drivers/nvmem/layouts/Makefile +@@ -4,3 +4,4 @@ + # + + obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o ++obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o +--- /dev/null ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -0,0 +1,257 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * ONIE tlv NVMEM cells provider ++ * ++ * Copyright (C) 2022 Open Compute Group ONIE ++ * Author: Miquel Raynal ++ * Based on the nvmem driver written by: Vadym Kochan ++ * Inspired by the first layout written by: Rafał Miłecki ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define ONIE_TLV_MAX_LEN 2048 ++#define ONIE_TLV_CRC_FIELD_SZ 6 ++#define ONIE_TLV_CRC_SZ 4 ++#define ONIE_TLV_HDR_ID "TlvInfo" ++ ++struct onie_tlv_hdr { ++ u8 id[8]; ++ u8 version; ++ __be16 data_len; ++} __packed; ++ ++struct onie_tlv { ++ u8 type; ++ u8 len; ++} __packed; ++ ++static const char *onie_tlv_cell_name(u8 type) ++{ ++ switch (type) { ++ case 0x21: ++ return "product-name"; ++ case 0x22: ++ return "part-number"; ++ case 0x23: ++ return "serial-number"; ++ case 0x24: ++ return "mac-address"; ++ case 0x25: ++ return "manufacture-date"; ++ case 0x26: ++ return "device-version"; ++ case 0x27: ++ return "label-revision"; ++ case 0x28: ++ return "platform-name"; ++ case 0x29: ++ return "onie-version"; ++ case 0x2A: ++ return "num-macs"; ++ case 0x2B: ++ return "manufacturer"; ++ case 0x2C: ++ return "country-code"; ++ case 0x2D: ++ return "vendor"; ++ case 0x2E: ++ return "diag-version"; ++ case 0x2F: ++ return "service-tag"; ++ case 0xFD: ++ return "vendor-extension"; ++ case 0xFE: ++ return "crc32"; ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++static int onie_tlv_mac_read_cb(void *priv, const char *id, int index, ++ unsigned int offset, void *buf, ++ size_t bytes) ++{ ++ eth_addr_add(buf, index); ++ ++ return 0; ++} ++ ++static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf) ++{ ++ switch (type) { ++ case 0x24: ++ return &onie_tlv_mac_read_cb; ++ default: ++ break; ++ } ++ ++ return NULL; ++} ++ ++static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem, ++ size_t data_len, u8 *data) ++{ ++ struct nvmem_cell_info cell = {}; ++ struct device_node *layout; ++ struct onie_tlv tlv; ++ unsigned int hdr_len = sizeof(struct onie_tlv_hdr); ++ unsigned int offset = 0; ++ int ret; ++ ++ layout = of_nvmem_layout_get_container(nvmem); ++ if (!layout) ++ return -ENOENT; ++ ++ while (offset < data_len) { ++ memcpy(&tlv, data + offset, sizeof(tlv)); ++ if (offset + tlv.len >= data_len) { ++ dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n", ++ tlv.len, hdr_len + offset); ++ break; ++ } ++ ++ cell.name = onie_tlv_cell_name(tlv.type); ++ if (!cell.name) ++ continue; ++ ++ cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len); ++ cell.bytes = tlv.len; ++ cell.np = of_get_child_by_name(layout, cell.name); ++ cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv)); ++ ++ ret = nvmem_add_one_cell(nvmem, &cell); ++ if (ret) { ++ of_node_put(layout); ++ return ret; ++ } ++ ++ offset += sizeof(tlv) + tlv.len; ++ } ++ ++ of_node_put(layout); ++ ++ return 0; ++} ++ ++static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr) ++{ ++ if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) { ++ dev_err(dev, "Invalid header\n"); ++ return false; ++ } ++ ++ if (hdr->version != 0x1) { ++ dev_err(dev, "Invalid version number\n"); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table) ++{ ++ struct onie_tlv crc_hdr; ++ u32 read_crc, calc_crc; ++ __be32 crc_be; ++ ++ memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr)); ++ if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) { ++ dev_err(dev, "Invalid CRC field\n"); ++ return false; ++ } ++ ++ /* The table contains a JAMCRC, which is XOR'ed compared to the original ++ * CRC32 implementation as known in the Ethernet world. ++ */ ++ memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ); ++ read_crc = be32_to_cpu(crc_be); ++ calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF; ++ if (read_crc != calc_crc) { ++ dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n", ++ read_crc, calc_crc); ++ return false; ++ } ++ ++ return true; ++} ++ ++static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem, ++ struct nvmem_layout *layout) ++{ ++ struct onie_tlv_hdr hdr; ++ size_t table_len, data_len, hdr_len; ++ u8 *table, *data; ++ int ret; ++ ++ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); ++ if (ret < 0) ++ return ret; ++ ++ if (!onie_tlv_hdr_is_valid(dev, &hdr)) { ++ dev_err(dev, "Invalid ONIE TLV header\n"); ++ return -EINVAL; ++ } ++ ++ hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len); ++ data_len = be16_to_cpu(hdr.data_len); ++ table_len = hdr_len + data_len; ++ if (table_len > ONIE_TLV_MAX_LEN) { ++ dev_err(dev, "Invalid ONIE TLV data length\n"); ++ return -EINVAL; ++ } ++ ++ table = devm_kmalloc(dev, table_len, GFP_KERNEL); ++ if (!table) ++ return -ENOMEM; ++ ++ ret = nvmem_device_read(nvmem, 0, table_len, table); ++ if (ret != table_len) ++ return ret; ++ ++ if (!onie_tlv_crc_is_valid(dev, table_len, table)) ++ return -EINVAL; ++ ++ data = table + hdr_len; ++ ret = onie_tlv_add_cells(dev, nvmem, data_len, data); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static const struct of_device_id onie_tlv_of_match_table[] = { ++ { .compatible = "onie,tlv-layout", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table); ++ ++static struct nvmem_layout onie_tlv_layout = { ++ .name = "ONIE tlv layout", ++ .of_match_table = onie_tlv_of_match_table, ++ .add_cells = onie_tlv_parse_table, ++}; ++ ++static int __init onie_tlv_init(void) ++{ ++ return nvmem_layout_register(&onie_tlv_layout); ++} ++ ++static void __exit onie_tlv_exit(void) ++{ ++ nvmem_layout_unregister(&onie_tlv_layout); ++} ++ ++module_init(onie_tlv_init); ++module_exit(onie_tlv_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Miquel Raynal "); ++MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); ++MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch b/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch new file mode 100644 index 000000000..94a0911d7 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch @@ -0,0 +1,32 @@ +From a4fb434ef96ace5af758ca2c52c3a3f8f3abc87c Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Tue, 4 Apr 2023 18:21:34 +0100 +Subject: [PATCH] nvmem: stm32-romem: mark OF related data as maybe unused +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The driver can be compile tested with !CONFIG_OF making certain data +unused: + + drivers/nvmem/stm32-romem.c:271:34: error: ‘stm32_romem_of_match’ defined but not used [-Werror=unused-const-variable=] + +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-27-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/stm32-romem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/stm32-romem.c ++++ b/drivers/nvmem/stm32-romem.c +@@ -268,7 +268,7 @@ static const struct stm32_romem_cfg stm3 + .ta = true, + }; + +-static const struct of_device_id stm32_romem_of_match[] = { ++static const struct of_device_id stm32_romem_of_match[] __maybe_unused = { + { .compatible = "st,stm32f4-otp", }, { + .compatible = "st,stm32mp15-bsec", + .data = (void *)&stm32mp15_bsec_cfg, diff --git a/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch b/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch new file mode 100644 index 000000000..abda402bd --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch @@ -0,0 +1,120 @@ +From de6e05097f7db066afb0ad4c88b730949f7b7749 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +Date: Tue, 4 Apr 2023 18:21:35 +0100 +Subject: [PATCH] nvmem: mtk-efuse: Support postprocessing for GPU speed + binning data + +On some MediaTek SoCs GPU speed binning data is available for read +in the SoC's eFuse array but it has a format that is incompatible +with what the OPP API expects, as we read a number from 0 to 7 but +opp-supported-hw is expecting a bitmask to enable an OPP entry: +being what we read limited to 0-7, it's straightforward to simply +convert the value to BIT(value) as a post-processing action. + +So, introduce post-processing support and enable it by evaluating +the newly introduced platform data's `uses_post_processing` member, +currently enabled only for MT8186. + +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-28-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/mtk-efuse.c | 53 +++++++++++++++++++++++++++++++++++++-- + 1 file changed, 51 insertions(+), 2 deletions(-) + +--- a/drivers/nvmem/mtk-efuse.c ++++ b/drivers/nvmem/mtk-efuse.c +@@ -10,6 +10,11 @@ + #include + #include + #include ++#include ++ ++struct mtk_efuse_pdata { ++ bool uses_post_processing; ++}; + + struct mtk_efuse_priv { + void __iomem *base; +@@ -29,6 +34,37 @@ static int mtk_reg_read(void *context, + return 0; + } + ++static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index, ++ unsigned int offset, void *data, size_t bytes) ++{ ++ u8 *val = data; ++ ++ if (val[0] < 8) ++ val[0] = BIT(val[0]); ++ ++ return 0; ++} ++ ++static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_layout *layout, ++ struct nvmem_cell_info *cell) ++{ ++ size_t sz = strlen(cell->name); ++ ++ /* ++ * On some SoCs, the GPU speedbin is not read as bitmask but as ++ * a number with range [0-7] (max 3 bits): post process to use ++ * it in OPP tables to describe supported-hw. ++ */ ++ if (cell->nbits <= 3 && ++ strncmp(cell->name, "gpu-speedbin", min(sz, strlen("gpu-speedbin"))) == 0) ++ cell->read_post_process = mtk_efuse_gpu_speedbin_pp; ++} ++ ++static struct nvmem_layout mtk_efuse_layout = { ++ .fixup_cell_info = mtk_efuse_fixup_cell_info, ++}; ++ + static int mtk_efuse_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -36,6 +72,7 @@ static int mtk_efuse_probe(struct platfo + struct nvmem_device *nvmem; + struct nvmem_config econfig = {}; + struct mtk_efuse_priv *priv; ++ const struct mtk_efuse_pdata *pdata; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) +@@ -45,20 +82,32 @@ static int mtk_efuse_probe(struct platfo + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + ++ pdata = device_get_match_data(dev); + econfig.stride = 1; + econfig.word_size = 1; + econfig.reg_read = mtk_reg_read; + econfig.size = resource_size(res); + econfig.priv = priv; + econfig.dev = dev; ++ if (pdata->uses_post_processing) ++ econfig.layout = &mtk_efuse_layout; + nvmem = devm_nvmem_register(dev, &econfig); + + return PTR_ERR_OR_ZERO(nvmem); + } + ++static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = { ++ .uses_post_processing = true, ++}; ++ ++static const struct mtk_efuse_pdata mtk_efuse_pdata = { ++ .uses_post_processing = false, ++}; ++ + static const struct of_device_id mtk_efuse_of_match[] = { +- { .compatible = "mediatek,mt8173-efuse",}, +- { .compatible = "mediatek,efuse",}, ++ { .compatible = "mediatek,mt8173-efuse", .data = &mtk_efuse_pdata }, ++ { .compatible = "mediatek,mt8186-efuse", .data = &mtk_mt8186_efuse_pdata }, ++ { .compatible = "mediatek,efuse", .data = &mtk_efuse_pdata }, + {/* sentinel */}, + }; + MODULE_DEVICE_TABLE(of, mtk_efuse_of_match); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch b/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch new file mode 100644 index 000000000..200eb1928 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch @@ -0,0 +1,39 @@ +From 1dc552fa33cf98af3e784dbc0500da93cae3b24a Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:38 +0100 +Subject: [PATCH] nvmem: bcm-ocotp: Use devm_platform_ioremap_resource() + +According to commit 7945f929f1a7 ("drivers: provide +devm_platform_ioremap_resource()"), convert platform_get_resource(), +devm_ioremap_resource() to a single call to use +devm_platform_ioremap_resource(), as this is exactly what this function +does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-31-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/bcm-ocotp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/nvmem/bcm-ocotp.c ++++ b/drivers/nvmem/bcm-ocotp.c +@@ -244,7 +244,6 @@ MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_ + static int bcm_otpc_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- struct resource *res; + struct otpc_priv *priv; + struct nvmem_device *nvmem; + int err; +@@ -259,8 +258,7 @@ static int bcm_otpc_probe(struct platfor + return -ENODEV; + + /* Get OTP base address register. */ +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- priv->base = devm_ioremap_resource(dev, res); ++ priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) { + dev_err(dev, "unable to map I/O memory\n"); + return PTR_ERR(priv->base); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch b/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch new file mode 100644 index 000000000..890dacd08 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch @@ -0,0 +1,39 @@ +From 649409990d2e93fac657be7c6960c28a2c601d65 Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:39 +0100 +Subject: [PATCH] nvmem: nintendo-otp: Use devm_platform_ioremap_resource() + +According to commit 7945f929f1a7 ("drivers: provide +devm_platform_ioremap_resource()"), convert platform_get_resource(), +devm_ioremap_resource() to a single call to use +devm_platform_ioremap_resource(), as this is exactly what this function +does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-32-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/nintendo-otp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/nvmem/nintendo-otp.c ++++ b/drivers/nvmem/nintendo-otp.c +@@ -76,7 +76,6 @@ static int nintendo_otp_probe(struct pla + struct device *dev = &pdev->dev; + const struct of_device_id *of_id = + of_match_device(nintendo_otp_of_table, dev); +- struct resource *res; + struct nvmem_device *nvmem; + struct nintendo_otp_priv *priv; + +@@ -92,8 +91,7 @@ static int nintendo_otp_probe(struct pla + if (!priv) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- priv->regs = devm_ioremap_resource(dev, res); ++ priv->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + diff --git a/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch new file mode 100644 index 000000000..3f5d3c1ad --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch @@ -0,0 +1,32 @@ +From c2367aa60d5e34d48582362c6de34b4131d92be7 Mon Sep 17 00:00:00 2001 +From: Yang Li +Date: Tue, 4 Apr 2023 18:21:40 +0100 +Subject: [PATCH] nvmem: vf610-ocotp: Use + devm_platform_get_and_ioremap_resource() + +According to commit 890cc39a8799 ("drivers: provide +devm_platform_get_and_ioremap_resource()"), convert +platform_get_resource(), devm_ioremap_resource() to a single +call to devm_platform_get_and_ioremap_resource(), as this is exactly +what this function does. + +Signed-off-by: Yang Li +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-33-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/vf610-ocotp.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/nvmem/vf610-ocotp.c ++++ b/drivers/nvmem/vf610-ocotp.c +@@ -219,8 +219,7 @@ static int vf610_ocotp_probe(struct plat + if (!ocotp_dev) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- ocotp_dev->base = devm_ioremap_resource(dev, res); ++ ocotp_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(ocotp_dev->base)) + return PTR_ERR(ocotp_dev->base); + diff --git a/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch b/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch new file mode 100644 index 000000000..eeb407e9b --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch @@ -0,0 +1,115 @@ +From 55d4980ce55b6bb4be66877de4dbec513911b988 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 4 Apr 2023 18:21:42 +0100 +Subject: [PATCH] nvmem: core: support specifying both: cell raw data & post + read lengths +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Callback .read_post_process() is designed to modify raw cell content +before providing it to the consumer. So far we were dealing with +modifications that didn't affect cell size (length). In some cases +however cell content needs to be reformatted and resized. + +It's required e.g. to provide properly formatted MAC address in case +it's stored in a non-binary format (e.g. using ASCII). + +There were few discussions how to optimally handle that. Following +possible solutions were considered: +1. Allow .read_post_process() to realloc (resize) content buffer +2. Allow .read_post_process() to adjust (decrease) just buffer length +3. Register NVMEM cells using post-read sizes + +The preferred solution was the last one. The problem is that simply +adjusting "bytes" in NVMEM providers would result in core code NOT +passing whole raw data to .read_post_process() callbacks. It means +callback functions couldn't do their job without somehow manually +reading original cell content on their own. + +This patch deals with that by registering NVMEM cells with both lengths: +raw content one and post read one. It allows: +1. Core code to read whole raw cell content +2. Callbacks to return content they want + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-35-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 11 +++++++---- + include/linux/nvmem-provider.h | 2 ++ + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -50,6 +50,7 @@ struct nvmem_device { + struct nvmem_cell_entry { + const char *name; + int offset; ++ size_t raw_len; + int bytes; + int bit_offset; + int nbits; +@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell + { + cell->nvmem = nvmem; + cell->offset = info->offset; ++ cell->raw_len = info->raw_len ?: info->bytes; + cell->bytes = info->bytes; + cell->name = info->name; + cell->read_post_process = info->read_post_process; +@@ -1560,7 +1562,7 @@ static int __nvmem_cell_read(struct nvme + { + int rc; + +- rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes); ++ rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->raw_len); + + if (rc) + return rc; +@@ -1571,7 +1573,7 @@ static int __nvmem_cell_read(struct nvme + + if (cell->read_post_process) { + rc = cell->read_post_process(cell->priv, id, index, +- cell->offset, buf, cell->bytes); ++ cell->offset, buf, cell->raw_len); + if (rc) + return rc; + } +@@ -1594,14 +1596,15 @@ static int __nvmem_cell_read(struct nvme + */ + void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) + { +- struct nvmem_device *nvmem = cell->entry->nvmem; ++ struct nvmem_cell_entry *entry = cell->entry; ++ struct nvmem_device *nvmem = entry->nvmem; + u8 *buf; + int rc; + + if (!nvmem) + return ERR_PTR(-EINVAL); + +- buf = kzalloc(cell->entry->bytes, GFP_KERNEL); ++ buf = kzalloc(max_t(size_t, entry->raw_len, entry->bytes), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -51,6 +51,7 @@ struct nvmem_keepout { + * struct nvmem_cell_info - NVMEM cell description + * @name: Name. + * @offset: Offset within the NVMEM device. ++ * @raw_len: Length of raw data (without post processing). + * @bytes: Length of the cell. + * @bit_offset: Bit offset if cell is smaller than a byte. + * @nbits: Number of bits. +@@ -62,6 +63,7 @@ struct nvmem_keepout { + struct nvmem_cell_info { + const char *name; + unsigned int offset; ++ size_t raw_len; + unsigned int bytes; + unsigned int bit_offset; + unsigned int nbits; diff --git a/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch b/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch new file mode 100644 index 000000000..adde0ffc4 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch @@ -0,0 +1,81 @@ +From c49f1a8af6bcf6d18576bca898f8083ca4b129e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 4 Apr 2023 18:21:43 +0100 +Subject: [PATCH] nvmem: u-boot-env: post-process "ethaddr" env variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +U-Boot environment variables are stored in ASCII format so "ethaddr" +requires parsing into binary to make it work with Ethernet interfaces. + +This includes support for indexes to support #nvmem-cell-cells = <1>. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-36-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 1 + + drivers/nvmem/u-boot-env.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 27 insertions(+) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -340,6 +340,7 @@ config NVMEM_U_BOOT_ENV + tristate "U-Boot environment variables support" + depends on OF && MTD + select CRC32 ++ select GENERIC_NET_UTILS + help + U-Boot stores its setup as environment variables. This driver adds + support for verifying & exporting such data. It also exposes variables +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -4,6 +4,8 @@ + */ + + #include ++#include ++#include + #include + #include + #include +@@ -70,6 +72,25 @@ static int u_boot_env_read(void *context + return 0; + } + ++static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, ++ unsigned int offset, void *buf, size_t bytes) ++{ ++ u8 mac[ETH_ALEN]; ++ ++ if (bytes != 3 * ETH_ALEN - 1) ++ return -EINVAL; ++ ++ if (!mac_pton(buf, mac)) ++ return -EINVAL; ++ ++ if (index) ++ eth_addr_add(mac, index); ++ ++ ether_addr_copy(buf, mac); ++ ++ return 0; ++} ++ + static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, + size_t data_offset, size_t data_len) + { +@@ -101,6 +122,11 @@ static int u_boot_env_add_cells(struct u + priv->cells[idx].offset = data_offset + value - data; + priv->cells[idx].bytes = strlen(value); + priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); ++ if (!strcmp(var, "ethaddr")) { ++ priv->cells[idx].raw_len = strlen(value); ++ priv->cells[idx].bytes = ETH_ALEN; ++ priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr; ++ } + } + + if (WARN_ON(idx != priv->ncells)) diff --git a/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch b/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch new file mode 100644 index 000000000..7c6fe22b5 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch @@ -0,0 +1,42 @@ +From 814c978f02db17f16e6aa2efa2a929372f06da09 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:44 +0100 +Subject: [PATCH] nvmem: Add macro to register nvmem layout drivers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Provide a module_nvmem_layout_driver() macro at the end of the +nvmem-provider.h header to reduce the boilerplate when registering nvmem +layout drivers. + +Suggested-by: Srinivas Kandagatla +Signed-off-by: Miquel Raynal +Acked-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-37-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nvmem-provider.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -9,6 +9,7 @@ + #ifndef _LINUX_NVMEM_PROVIDER_H + #define _LINUX_NVMEM_PROVIDER_H + ++#include + #include + #include + #include +@@ -242,4 +243,9 @@ nvmem_layout_get_match_data(struct nvmem + } + + #endif /* CONFIG_NVMEM */ ++ ++#define module_nvmem_layout_driver(__layout_driver) \ ++ module_driver(__layout_driver, nvmem_layout_register, \ ++ nvmem_layout_unregister) ++ + #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch new file mode 100644 index 000000000..06646dd68 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch @@ -0,0 +1,39 @@ +From 0abdf99fe0c86252ba274703425f8d543d7e7f0d Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:45 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: Use module_nvmem_layout_driver() + +Stop open-coding the module init/exit functions. Use the +module_nvmem_layout_driver() instead. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-38-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/sl28vpd.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +--- a/drivers/nvmem/layouts/sl28vpd.c ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -146,19 +146,7 @@ struct nvmem_layout sl28vpd_layout = { + .of_match_table = sl28vpd_of_match_table, + .add_cells = sl28vpd_add_cells, + }; +- +-static int __init sl28vpd_init(void) +-{ +- return nvmem_layout_register(&sl28vpd_layout); +-} +- +-static void __exit sl28vpd_exit(void) +-{ +- nvmem_layout_unregister(&sl28vpd_layout); +-} +- +-module_init(sl28vpd_init); +-module_exit(sl28vpd_exit); ++module_nvmem_layout_driver(sl28vpd_layout); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Michael Walle "); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch b/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch new file mode 100644 index 000000000..826f4378c --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch @@ -0,0 +1,39 @@ +From d119eb38faab61125aaa4f63c74eef61585cf34c Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:46 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Use module_nvmem_layout_driver() + +Stop open-coding the module init/exit functions. Use the +module_nvmem_layout_driver() instead. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-39-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/onie-tlv.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +--- a/drivers/nvmem/layouts/onie-tlv.c ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -237,19 +237,7 @@ static struct nvmem_layout onie_tlv_layo + .of_match_table = onie_tlv_of_match_table, + .add_cells = onie_tlv_parse_table, + }; +- +-static int __init onie_tlv_init(void) +-{ +- return nvmem_layout_register(&onie_tlv_layout); +-} +- +-static void __exit onie_tlv_exit(void) +-{ +- nvmem_layout_unregister(&onie_tlv_layout); +-} +- +-module_init(onie_tlv_init); +-module_exit(onie_tlv_exit); ++module_nvmem_layout_driver(onie_tlv_layout); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Miquel Raynal "); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch b/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch new file mode 100644 index 000000000..f20db85ce --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch @@ -0,0 +1,24 @@ +From 6b13e4b6a9a45028ac730e550380077df1845912 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:47 +0100 +Subject: [PATCH] nvmem: layouts: onie-tlv: Drop wrong module alias + +The MODULE_ALIAS macro is misused here as it carries the +description. There is currently no relevant alias to provide so let's +just drop it. + +Signed-off-by: Miquel Raynal +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-40-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/onie-tlv.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/nvmem/layouts/onie-tlv.c ++++ b/drivers/nvmem/layouts/onie-tlv.c +@@ -242,4 +242,3 @@ module_nvmem_layout_driver(onie_tlv_layo + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Miquel Raynal "); + MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); +-MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch b/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch new file mode 100644 index 000000000..5cf847b57 --- /dev/null +++ b/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch @@ -0,0 +1,31 @@ +From a8642cd11635a35a5f1dc31857887900d6610778 Mon Sep 17 00:00:00 2001 +From: Tom Rix +Date: Tue, 4 Apr 2023 18:21:48 +0100 +Subject: [PATCH] nvmem: layouts: sl28vpd: set varaiable sl28vpd_layout + storage-class-specifier to static + +smatch reports +drivers/nvmem/layouts/sl28vpd.c:144:21: warning: symbol + 'sl28vpd_layout' was not declared. Should it be static? + +This variable is only used in one file so it should be static. + +Signed-off-by: Tom Rix +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-41-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/layouts/sl28vpd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/layouts/sl28vpd.c ++++ b/drivers/nvmem/layouts/sl28vpd.c +@@ -141,7 +141,7 @@ static const struct of_device_id sl28vpd + }; + MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); + +-struct nvmem_layout sl28vpd_layout = { ++static struct nvmem_layout sl28vpd_layout = { + .name = "sl28-vpd", + .of_match_table = sl28vpd_of_match_table, + .add_cells = sl28vpd_add_cells, diff --git a/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch b/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch new file mode 100644 index 000000000..13ee2d422 --- /dev/null +++ b/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch @@ -0,0 +1,100 @@ +From a5be5ce0e25439fae3cd42e3d775979547926812 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 3 Nov 2022 09:25:29 +0100 +Subject: [PATCH] firmware/nvram: bcm47xx: support init from IO memory +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Provide NVMEM content to the NVRAM driver from a simple +memory resource. This is necessary to use NVRAM in a memory- +mapped flash device. Patch taken from OpenWrts development +tree. + +This patch makes it possible to use memory-mapped NVRAM +on the D-Link DWL-8610AP and the D-Link DIR-890L. + +Cc: Hauke Mehrtens +Cc: linux-mips@vger.kernel.org +Cc: Florian Fainelli +Cc: bcm-kernel-feedback-list@broadcom.com +Cc: Thomas Bogendoerfer +Signed-off-by: Rafał Miłecki +[Added an export for modules potentially using the init symbol] +Signed-off-by: Linus Walleij +Link: https://lore.kernel.org/r/20221103082529.359084-1-linus.walleij@linaro.org +Signed-off-by: Florian Fainelli +--- + drivers/firmware/broadcom/bcm47xx_nvram.c | 18 ++++++++++++++++++ + drivers/nvmem/brcm_nvram.c | 3 +++ + include/linux/bcm47xx_nvram.h | 6 ++++++ + 3 files changed, 27 insertions(+) + +--- a/drivers/firmware/broadcom/bcm47xx_nvram.c ++++ b/drivers/firmware/broadcom/bcm47xx_nvram.c +@@ -110,6 +110,24 @@ found: + return 0; + } + ++int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size) ++{ ++ if (nvram_len) { ++ pr_warn("nvram already initialized\n"); ++ return -EEXIST; ++ } ++ ++ if (!bcm47xx_nvram_is_valid(nvram_start)) { ++ pr_err("No valid NVRAM found\n"); ++ return -ENOENT; ++ } ++ ++ bcm47xx_nvram_copy(nvram_start, res_size); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(bcm47xx_nvram_init_from_iomem); ++ + /* + * On bcm47xx we need access to the NVRAM very early, so we can't use mtd + * subsystem to access flash. We can't even use platform device / driver to +--- a/drivers/nvmem/brcm_nvram.c ++++ b/drivers/nvmem/brcm_nvram.c +@@ -3,6 +3,7 @@ + * Copyright (C) 2021 Rafał Miłecki + */ + ++#include + #include + #include + #include +@@ -139,6 +140,8 @@ static int brcm_nvram_probe(struct platf + if (err) + return err; + ++ bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res)); ++ + config.dev = dev; + config.cells = priv->cells; + config.ncells = priv->ncells; +--- a/include/linux/bcm47xx_nvram.h ++++ b/include/linux/bcm47xx_nvram.h +@@ -11,6 +11,7 @@ + #include + + #ifdef CONFIG_BCM47XX_NVRAM ++int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size); + int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); + int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); + int bcm47xx_nvram_gpio_pin(const char *name); +@@ -20,6 +21,11 @@ static inline void bcm47xx_nvram_release + vfree(nvram); + }; + #else ++static inline int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, ++ size_t res_size) ++{ ++ return -ENOTSUPP; ++} + static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) + { + return -ENOTSUPP; diff --git a/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch b/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch new file mode 100644 index 000000000..38cfccd5e --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch @@ -0,0 +1,31 @@ +From eebc6573ad940b62a87776db3917e912b4f52d78 Mon Sep 17 00:00:00 2001 +From: Tom Rix +Date: Sun, 11 Jun 2023 15:03:05 +0100 +Subject: [PATCH] nvmem: imx-ocotp: set varaiable imx_ocotp_layout + storage-class-specifier to static + +smatch reports +drivers/nvmem/imx-ocotp.c:599:21: warning: symbol + 'imx_ocotp_layout' was not declared. Should it be static? + +This variable is only used in one file so should be static. + +Signed-off-by: Tom Rix +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-2-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/imx-ocotp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -596,7 +596,7 @@ static void imx_ocotp_fixup_cell_info(st + cell->read_post_process = imx_ocotp_cell_pp; + } + +-struct nvmem_layout imx_ocotp_layout = { ++static struct nvmem_layout imx_ocotp_layout = { + .fixup_cell_info = imx_ocotp_fixup_cell_info, + }; + diff --git a/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch b/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch new file mode 100644 index 000000000..7523e5ebf --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch @@ -0,0 +1,71 @@ +From 8a00fc606312c68b98add8fe8e6f7a013ce29e78 Mon Sep 17 00:00:00 2001 +From: Alexander Stein +Date: Sun, 11 Jun 2023 15:03:06 +0100 +Subject: [PATCH] nvmem: imx-ocotp: Reverse MAC addresses on all i.MX derivates + +Not just i.MX8M, but all i.MX6/7 (and subtypes) need to reverse the +MAC address read from fuses. Exceptions are i.MX6SLL and i.MX7ULP which +do not support ethernet at all. + +Fixes: d0221a780cbc ("nvmem: imx-ocotp: add support for post processing") +Signed-off-by: Alexander Stein +Tested-by: Richard Leitner # imx6q +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-3-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/imx-ocotp.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/nvmem/imx-ocotp.c ++++ b/drivers/nvmem/imx-ocotp.c +@@ -97,7 +97,6 @@ struct ocotp_params { + unsigned int bank_address_words; + void (*set_timing)(struct ocotp_priv *priv); + struct ocotp_ctrl_reg ctrl; +- bool reverse_mac_address; + }; + + static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags) +@@ -545,7 +544,6 @@ static const struct ocotp_params imx8mq_ + .bank_address_words = 0, + .set_timing = imx_ocotp_set_imx6_timing, + .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, +- .reverse_mac_address = true, + }; + + static const struct ocotp_params imx8mm_params = { +@@ -553,7 +551,6 @@ static const struct ocotp_params imx8mm_ + .bank_address_words = 0, + .set_timing = imx_ocotp_set_imx6_timing, + .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, +- .reverse_mac_address = true, + }; + + static const struct ocotp_params imx8mn_params = { +@@ -561,7 +558,6 @@ static const struct ocotp_params imx8mn_ + .bank_address_words = 0, + .set_timing = imx_ocotp_set_imx6_timing, + .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, +- .reverse_mac_address = true, + }; + + static const struct ocotp_params imx8mp_params = { +@@ -569,7 +565,6 @@ static const struct ocotp_params imx8mp_ + .bank_address_words = 0, + .set_timing = imx_ocotp_set_imx6_timing, + .ctrl = IMX_OCOTP_BM_CTRL_8MP, +- .reverse_mac_address = true, + }; + + static const struct of_device_id imx_ocotp_dt_ids[] = { +@@ -624,8 +619,7 @@ static int imx_ocotp_probe(struct platfo + imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; + imx_ocotp_nvmem_config.dev = dev; + imx_ocotp_nvmem_config.priv = priv; +- if (priv->params->reverse_mac_address) +- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; ++ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; + + priv->config = &imx_ocotp_nvmem_config; + diff --git a/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch b/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch new file mode 100644 index 000000000..fb4d346a9 --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch @@ -0,0 +1,81 @@ +From 73bcd133c910bff3b6d3b3834d0d14be9444e90a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 11 Jun 2023 15:03:08 +0100 +Subject: [PATCH] nvmem: brcm_nvram: add .read_post_process() for MACs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1. Parse ASCII MAC format into byte based +2. Calculate relative addresses based on index argument + +Signed-off-by: Rafał Miłecki +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-5-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 1 + + drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 29 insertions(+) + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -55,6 +55,7 @@ config NVMEM_BRCM_NVRAM + tristate "Broadcom's NVRAM support" + depends on ARCH_BCM_5301X || COMPILE_TEST + depends on HAS_IOMEM ++ select GENERIC_NET_UTILS + help + This driver provides support for Broadcom's NVRAM that can be accessed + using I/O mapping. +--- a/drivers/nvmem/brcm_nvram.c ++++ b/drivers/nvmem/brcm_nvram.c +@@ -4,6 +4,8 @@ + */ + + #include ++#include ++#include + #include + #include + #include +@@ -42,6 +44,25 @@ static int brcm_nvram_read(void *context + return 0; + } + ++static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, int index, ++ unsigned int offset, void *buf, size_t bytes) ++{ ++ u8 mac[ETH_ALEN]; ++ ++ if (bytes != 3 * ETH_ALEN - 1) ++ return -EINVAL; ++ ++ if (!mac_pton(buf, mac)) ++ return -EINVAL; ++ ++ if (index) ++ eth_addr_add(mac, index); ++ ++ ether_addr_copy(buf, mac); ++ ++ return 0; ++} ++ + static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data, + size_t len) + { +@@ -75,6 +96,13 @@ static int brcm_nvram_add_cells(struct b + priv->cells[idx].offset = value - (char *)data; + priv->cells[idx].bytes = strlen(value); + priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); ++ if (!strcmp(var, "et0macaddr") || ++ !strcmp(var, "et1macaddr") || ++ !strcmp(var, "et2macaddr")) { ++ priv->cells[idx].raw_len = strlen(value); ++ priv->cells[idx].bytes = ETH_ALEN; ++ priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr; ++ } + } + + return 0; diff --git a/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch b/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch new file mode 100644 index 000000000..3b6e6e57f --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch @@ -0,0 +1,166 @@ +From 8dc61364164e79e44c07fa2ac0a7b6939f00d5db Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Sun, 11 Jun 2023 15:03:13 +0100 +Subject: [PATCH] nvmem: rockchip-otp: Add clks and reg_read to rockchip_data + +In preparation to support new Rockchip OTP memory devices with different +clock configurations and register layout, extend rockchip_data struct +with the related members: clks, num_clks, reg_read. + +Additionally, to avoid managing redundant driver data, drop num_clks +member from rockchip_otp struct and update all references to point to +the equivalent member in rockchip_data. + +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-10-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++-------------- + 1 file changed, 49 insertions(+), 30 deletions(-) + +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -54,21 +54,19 @@ + + #define OTPC_TIMEOUT 10000 + ++struct rockchip_data { ++ int size; ++ const char * const *clks; ++ int num_clks; ++ nvmem_reg_read_t reg_read; ++}; ++ + struct rockchip_otp { + struct device *dev; + void __iomem *base; +- struct clk_bulk_data *clks; +- int num_clks; ++ struct clk_bulk_data *clks; + struct reset_control *rst; +-}; +- +-/* list of required clocks */ +-static const char * const rockchip_otp_clocks[] = { +- "otp", "apb_pclk", "phy", +-}; +- +-struct rockchip_data { +- int size; ++ const struct rockchip_data *data; + }; + + static int rockchip_otp_reset(struct rockchip_otp *otp) +@@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struc + return ret; + } + +-static int rockchip_otp_read(void *context, unsigned int offset, +- void *val, size_t bytes) ++static int px30_otp_read(void *context, unsigned int offset, ++ void *val, size_t bytes) + { + struct rockchip_otp *otp = context; + u8 *buf = val; +- int ret = 0; +- +- ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks); +- if (ret < 0) { +- dev_err(otp->dev, "failed to prepare/enable clks\n"); +- return ret; +- } ++ int ret; + + ret = rockchip_otp_reset(otp); + if (ret) { + dev_err(otp->dev, "failed to reset otp phy\n"); +- goto disable_clks; ++ return ret; + } + + ret = rockchip_otp_ecc_enable(otp, false); + if (ret < 0) { + dev_err(otp->dev, "rockchip_otp_ecc_enable err\n"); +- goto disable_clks; ++ return ret; + } + + writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); +@@ -174,8 +166,28 @@ static int rockchip_otp_read(void *conte + + read_end: + writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); +-disable_clks: +- clk_bulk_disable_unprepare(otp->num_clks, otp->clks); ++ ++ return ret; ++} ++ ++static int rockchip_otp_read(void *context, unsigned int offset, ++ void *val, size_t bytes) ++{ ++ struct rockchip_otp *otp = context; ++ int ret; ++ ++ if (!otp->data || !otp->data->reg_read) ++ return -EINVAL; ++ ++ ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks); ++ if (ret < 0) { ++ dev_err(otp->dev, "failed to prepare/enable clks\n"); ++ return ret; ++ } ++ ++ ret = otp->data->reg_read(context, offset, val, bytes); ++ ++ clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks); + + return ret; + } +@@ -189,8 +201,15 @@ static struct nvmem_config otp_config = + .reg_read = rockchip_otp_read, + }; + ++static const char * const px30_otp_clocks[] = { ++ "otp", "apb_pclk", "phy", ++}; ++ + static const struct rockchip_data px30_data = { + .size = 0x40, ++ .clks = px30_otp_clocks, ++ .num_clks = ARRAY_SIZE(px30_otp_clocks), ++ .reg_read = px30_otp_read, + }; + + static const struct of_device_id rockchip_otp_match[] = { +@@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct pla + if (!otp) + return -ENOMEM; + ++ otp->data = data; + otp->dev = dev; + otp->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(otp->base)) + return PTR_ERR(otp->base); + +- otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks); +- otp->clks = devm_kcalloc(dev, otp->num_clks, +- sizeof(*otp->clks), GFP_KERNEL); ++ otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks), ++ GFP_KERNEL); + if (!otp->clks) + return -ENOMEM; + +- for (i = 0; i < otp->num_clks; ++i) +- otp->clks[i].id = rockchip_otp_clocks[i]; ++ for (i = 0; i < data->num_clks; ++i) ++ otp->clks[i].id = data->clks[i]; + +- ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks); ++ ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks); + if (ret) + return ret; + diff --git a/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch b/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch new file mode 100644 index 000000000..b5b66cfc5 --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch @@ -0,0 +1,62 @@ +From 30fd21cfb1e64ef20035559a8246f5fbf682c40e Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Sun, 11 Jun 2023 15:03:14 +0100 +Subject: [PATCH] nvmem: rockchip-otp: Generalize rockchip_otp_wait_status() + +In preparation to support additional Rockchip OTP memory devices with +different register layout, generalize rockchip_otp_wait_status() to +accept a new parameter for specifying the offset of the status register. + +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-11-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/rockchip-otp.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -90,18 +90,19 @@ static int rockchip_otp_reset(struct roc + return 0; + } + +-static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag) ++static int rockchip_otp_wait_status(struct rockchip_otp *otp, ++ unsigned int reg, u32 flag) + { + u32 status = 0; + int ret; + +- ret = readl_poll_timeout_atomic(otp->base + OTPC_INT_STATUS, status, ++ ret = readl_poll_timeout_atomic(otp->base + reg, status, + (status & flag), 1, OTPC_TIMEOUT); + if (ret) + return ret; + + /* clean int status */ +- writel(flag, otp->base + OTPC_INT_STATUS); ++ writel(flag, otp->base + reg); + + return 0; + } +@@ -123,7 +124,7 @@ static int rockchip_otp_ecc_enable(struc + + writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); + +- ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); ++ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE); + if (ret < 0) + dev_err(otp->dev, "timeout during ecc_enable\n"); + +@@ -156,7 +157,7 @@ static int px30_otp_read(void *context, + otp->base + OTPC_USER_ADDR); + writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, + otp->base + OTPC_USER_ENABLE); +- ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); ++ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE); + if (ret < 0) { + dev_err(otp->dev, "timeout during read setup\n"); + goto read_end; diff --git a/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch b/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch new file mode 100644 index 000000000..3a17479d9 --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch @@ -0,0 +1,31 @@ +From d325c9dd2b6e94040ca722ddcadcd6af358dd2be Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Sun, 11 Jun 2023 15:03:15 +0100 +Subject: [PATCH] nvmem: rockchip-otp: Use + devm_reset_control_array_get_exclusive() + +In preparation to support new Rockchip OTP memory devices having +specific reset configurations, switch devm_reset_control_get() to +devm_reset_control_array_get_exclusive(). + +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-12-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/rockchip-otp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -263,7 +263,7 @@ static int rockchip_otp_probe(struct pla + if (ret) + return ret; + +- otp->rst = devm_reset_control_get(dev, "phy"); ++ otp->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(otp->rst)) + return PTR_ERR(otp->rst); + diff --git a/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch b/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch new file mode 100644 index 000000000..37cb927b1 --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch @@ -0,0 +1,71 @@ +From 912517345b867a69542dc9f5c2cc3e9d8beaccf5 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Sun, 11 Jun 2023 15:03:16 +0100 +Subject: [PATCH] nvmem: rockchip-otp: Improve probe error handling + +Enhance error handling in the probe function by making use of +dev_err_probe(), which ensures the error code is always printed, in +addition to the specified error message. + +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-13-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/rockchip-otp.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -235,10 +235,8 @@ static int rockchip_otp_probe(struct pla + int ret, i; + + data = of_device_get_match_data(dev); +- if (!data) { +- dev_err(dev, "failed to get match data\n"); +- return -EINVAL; +- } ++ if (!data) ++ return dev_err_probe(dev, -EINVAL, "failed to get match data\n"); + + otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp), + GFP_KERNEL); +@@ -249,7 +247,8 @@ static int rockchip_otp_probe(struct pla + otp->dev = dev; + otp->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(otp->base)) +- return PTR_ERR(otp->base); ++ return dev_err_probe(dev, PTR_ERR(otp->base), ++ "failed to ioremap resource\n"); + + otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks), + GFP_KERNEL); +@@ -261,18 +260,22 @@ static int rockchip_otp_probe(struct pla + + ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks); + if (ret) +- return ret; ++ return dev_err_probe(dev, ret, "failed to get clocks\n"); + + otp->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(otp->rst)) +- return PTR_ERR(otp->rst); ++ return dev_err_probe(dev, PTR_ERR(otp->rst), ++ "failed to get resets\n"); + + otp_config.size = data->size; + otp_config.priv = otp; + otp_config.dev = dev; +- nvmem = devm_nvmem_register(dev, &otp_config); + +- return PTR_ERR_OR_ZERO(nvmem); ++ nvmem = devm_nvmem_register(dev, &otp_config); ++ if (IS_ERR(nvmem)) ++ return dev_err_probe(dev, PTR_ERR(nvmem), ++ "failed to register nvmem device\n"); ++ return 0; + } + + static struct platform_driver rockchip_otp_driver = { diff --git a/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch b/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch new file mode 100644 index 000000000..c1e2231c9 --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch @@ -0,0 +1,129 @@ +From 8ab099fafbbc8c9607c399d21a774784a6cb8b45 Mon Sep 17 00:00:00 2001 +From: Cristian Ciocaltea +Date: Sun, 11 Jun 2023 15:03:17 +0100 +Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3588 + +Add support for the OTP memory device found on the Rockchip RK3588 SoC. + +While here, remove the unnecessary 'void *' casts in the OF device ID +table. + +Co-developed-by: Finley Xiao +Signed-off-by: Finley Xiao +Signed-off-by: Cristian Ciocaltea +Tested-by: Vincent Legoll +Reviewed-by: Heiko Stuebner +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-14-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++- + 1 file changed, 76 insertions(+), 2 deletions(-) + +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -54,6 +54,19 @@ + + #define OTPC_TIMEOUT 10000 + ++/* RK3588 Register */ ++#define RK3588_OTPC_AUTO_CTRL 0x04 ++#define RK3588_OTPC_AUTO_EN 0x08 ++#define RK3588_OTPC_INT_ST 0x84 ++#define RK3588_OTPC_DOUT0 0x20 ++#define RK3588_NO_SECURE_OFFSET 0x300 ++#define RK3588_NBYTES 4 ++#define RK3588_BURST_NUM 1 ++#define RK3588_BURST_SHIFT 8 ++#define RK3588_ADDR_SHIFT 16 ++#define RK3588_AUTO_EN BIT(0) ++#define RK3588_RD_DONE BIT(1) ++ + struct rockchip_data { + int size; + const char * const *clks; +@@ -171,6 +184,52 @@ read_end: + return ret; + } + ++static int rk3588_otp_read(void *context, unsigned int offset, ++ void *val, size_t bytes) ++{ ++ struct rockchip_otp *otp = context; ++ unsigned int addr_start, addr_end, addr_len; ++ int ret, i = 0; ++ u32 data; ++ u8 *buf; ++ ++ addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES; ++ addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES; ++ addr_len = addr_end - addr_start; ++ addr_start += RK3588_NO_SECURE_OFFSET; ++ ++ buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ while (addr_len--) { ++ writel((addr_start << RK3588_ADDR_SHIFT) | ++ (RK3588_BURST_NUM << RK3588_BURST_SHIFT), ++ otp->base + RK3588_OTPC_AUTO_CTRL); ++ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN); ++ ++ ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST, ++ RK3588_RD_DONE); ++ if (ret < 0) { ++ dev_err(otp->dev, "timeout during read setup\n"); ++ goto read_end; ++ } ++ ++ data = readl(otp->base + RK3588_OTPC_DOUT0); ++ memcpy(&buf[i], &data, RK3588_NBYTES); ++ ++ i += RK3588_NBYTES; ++ addr_start++; ++ } ++ ++ memcpy(val, buf + offset % RK3588_NBYTES, bytes); ++ ++read_end: ++ kfree(buf); ++ ++ return ret; ++} ++ + static int rockchip_otp_read(void *context, unsigned int offset, + void *val, size_t bytes) + { +@@ -213,14 +272,29 @@ static const struct rockchip_data px30_d + .reg_read = px30_otp_read, + }; + ++static const char * const rk3588_otp_clocks[] = { ++ "otp", "apb_pclk", "phy", "arb", ++}; ++ ++static const struct rockchip_data rk3588_data = { ++ .size = 0x400, ++ .clks = rk3588_otp_clocks, ++ .num_clks = ARRAY_SIZE(rk3588_otp_clocks), ++ .reg_read = rk3588_otp_read, ++}; ++ + static const struct of_device_id rockchip_otp_match[] = { + { + .compatible = "rockchip,px30-otp", +- .data = (void *)&px30_data, ++ .data = &px30_data, + }, + { + .compatible = "rockchip,rk3308-otp", +- .data = (void *)&px30_data, ++ .data = &px30_data, ++ }, ++ { ++ .compatible = "rockchip,rk3588-otp", ++ .data = &rk3588_data, + }, + { /* sentinel */ }, + }; diff --git a/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch b/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch new file mode 100644 index 000000000..220e3e9a0 --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch @@ -0,0 +1,26 @@ +From 9734408969e978a1c0d5d752be63dd638288e374 Mon Sep 17 00:00:00 2001 +From: Michal Simek +Date: Sun, 11 Jun 2023 15:03:23 +0100 +Subject: [PATCH] nvmem: zynqmp: Switch @xilinx.com emails to @amd.com + +@xilinx.com is still working but better to switch to new amd.com after +AMD/Xilinx acquisition. + +Signed-off-by: Michal Simek +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-20-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/zynqmp_nvmem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/zynqmp_nvmem.c ++++ b/drivers/nvmem/zynqmp_nvmem.c +@@ -76,6 +76,6 @@ static struct platform_driver zynqmp_nvm + + module_platform_driver(zynqmp_nvmem_driver); + +-MODULE_AUTHOR("Michal Simek , Nava kishore Manne "); ++MODULE_AUTHOR("Michal Simek , Nava kishore Manne "); + MODULE_DESCRIPTION("ZynqMP NVMEM driver"); + MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch b/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch new file mode 100644 index 000000000..f8e6be424 --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch @@ -0,0 +1,230 @@ +From 22e9e6fcfb5042cb6d6c7874c459b034800092f1 Mon Sep 17 00:00:00 2001 +From: Peng Fan +Date: Sun, 11 Jun 2023 15:03:25 +0100 +Subject: [PATCH] nvmem: imx: support i.MX93 OCOTP + +Add i.MX93 OCOTP support. i.MX93 OCOTP has two parts: Fuse shadow +block(fsb) and fuse managed by ELE. The FSB part could be directly +accessed with MMIO, the ELE could only be accessed with ELE API. + +Currently the ELE API is not ready, so NULL function callback is used, +but it was tested with downstream ELE API. + +Signed-off-by: Peng Fan +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-22-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/Kconfig | 9 ++ + drivers/nvmem/Makefile | 2 + + drivers/nvmem/imx-ocotp-ele.c | 175 ++++++++++++++++++++++++++++++++++ + 3 files changed, 186 insertions(+) + create mode 100644 drivers/nvmem/imx-ocotp-ele.c + +--- a/drivers/nvmem/Kconfig ++++ b/drivers/nvmem/Kconfig +@@ -83,6 +83,15 @@ config NVMEM_IMX_OCOTP + This driver can also be built as a module. If so, the module + will be called nvmem-imx-ocotp. + ++config NVMEM_IMX_OCOTP_ELE ++ tristate "i.MX On-Chip OTP Controller support" ++ depends on ARCH_MXC || COMPILE_TEST ++ depends on HAS_IOMEM ++ depends on OF ++ help ++ This is a driver for the On-Chip OTP Controller (OCOTP) ++ available on i.MX SoCs which has ELE. ++ + config NVMEM_IMX_OCOTP_SCU + tristate "i.MX8 SCU On-Chip OTP Controller support" + depends on IMX_SCU +--- a/drivers/nvmem/Makefile ++++ b/drivers/nvmem/Makefile +@@ -18,6 +18,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-im + nvmem-imx-iim-y := imx-iim.o + obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o + nvmem-imx-ocotp-y := imx-ocotp.o ++obj-$(CONFIG_NVMEM_IMX_OCOTP_ELE) += nvmem-imx-ocotp-ele.o ++nvmem-imx-ocotp-ele-y := imx-ocotp-ele.o + obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o + nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o + obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o +--- /dev/null ++++ b/drivers/nvmem/imx-ocotp-ele.c +@@ -0,0 +1,175 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * i.MX9 OCOTP fusebox driver ++ * ++ * Copyright 2023 NXP ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++enum fuse_type { ++ FUSE_FSB = 1, ++ FUSE_ELE = 2, ++ FUSE_INVALID = -1 ++}; ++ ++struct ocotp_map_entry { ++ u32 start; /* start word */ ++ u32 num; /* num words */ ++ enum fuse_type type; ++}; ++ ++struct ocotp_devtype_data { ++ u32 reg_off; ++ char *name; ++ u32 size; ++ u32 num_entry; ++ u32 flag; ++ nvmem_reg_read_t reg_read; ++ struct ocotp_map_entry entry[]; ++}; ++ ++struct imx_ocotp_priv { ++ struct device *dev; ++ void __iomem *base; ++ struct nvmem_config config; ++ struct mutex lock; ++ const struct ocotp_devtype_data *data; ++}; ++ ++static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index) ++{ ++ struct imx_ocotp_priv *priv = context; ++ const struct ocotp_devtype_data *data = priv->data; ++ u32 start, end; ++ int i; ++ ++ for (i = 0; i < data->num_entry; i++) { ++ start = data->entry[i].start; ++ end = data->entry[i].start + data->entry[i].num; ++ ++ if (index >= start && index < end) ++ return data->entry[i].type; ++ } ++ ++ return FUSE_INVALID; ++} ++ ++static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, size_t bytes) ++{ ++ struct imx_ocotp_priv *priv = context; ++ void __iomem *reg = priv->base + priv->data->reg_off; ++ u32 count, index, num_bytes; ++ enum fuse_type type; ++ u32 *buf; ++ void *p; ++ int i; ++ ++ index = offset; ++ num_bytes = round_up(bytes, 4); ++ count = num_bytes >> 2; ++ ++ if (count > ((priv->data->size >> 2) - index)) ++ count = (priv->data->size >> 2) - index; ++ ++ p = kzalloc(num_bytes, GFP_KERNEL); ++ if (!p) ++ return -ENOMEM; ++ ++ mutex_lock(&priv->lock); ++ ++ buf = p; ++ ++ for (i = index; i < (index + count); i++) { ++ type = imx_ocotp_fuse_type(context, i); ++ if (type == FUSE_INVALID || type == FUSE_ELE) { ++ *buf++ = 0; ++ continue; ++ } ++ ++ *buf++ = readl_relaxed(reg + (i << 2)); ++ } ++ ++ memcpy(val, (u8 *)p, bytes); ++ ++ mutex_unlock(&priv->lock); ++ ++ kfree(p); ++ ++ return 0; ++}; ++ ++static int imx_ele_ocotp_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct imx_ocotp_priv *priv; ++ struct nvmem_device *nvmem; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->data = of_device_get_match_data(dev); ++ ++ priv->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(priv->base)) ++ return PTR_ERR(priv->base); ++ ++ priv->config.dev = dev; ++ priv->config.name = "ELE-OCOTP"; ++ priv->config.id = NVMEM_DEVID_AUTO; ++ priv->config.owner = THIS_MODULE; ++ priv->config.size = priv->data->size; ++ priv->config.reg_read = priv->data->reg_read; ++ priv->config.word_size = 4; ++ priv->config.stride = 1; ++ priv->config.priv = priv; ++ priv->config.read_only = true; ++ mutex_init(&priv->lock); ++ ++ nvmem = devm_nvmem_register(dev, &priv->config); ++ if (IS_ERR(nvmem)) ++ return PTR_ERR(nvmem); ++ ++ return 0; ++} ++ ++static const struct ocotp_devtype_data imx93_ocotp_data = { ++ .reg_off = 0x8000, ++ .reg_read = imx_ocotp_reg_read, ++ .size = 2048, ++ .num_entry = 6, ++ .entry = { ++ { 0, 52, FUSE_FSB }, ++ { 63, 1, FUSE_ELE}, ++ { 128, 16, FUSE_ELE }, ++ { 182, 1, FUSE_ELE }, ++ { 188, 1, FUSE_ELE }, ++ { 312, 200, FUSE_FSB } ++ }, ++}; ++ ++static const struct of_device_id imx_ele_ocotp_dt_ids[] = { ++ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids); ++ ++static struct platform_driver imx_ele_ocotp_driver = { ++ .driver = { ++ .name = "imx_ele_ocotp", ++ .of_match_table = imx_ele_ocotp_dt_ids, ++ }, ++ .probe = imx_ele_ocotp_probe, ++}; ++module_platform_driver(imx_ele_ocotp_driver); ++ ++MODULE_DESCRIPTION("i.MX OCOTP/ELE driver"); ++MODULE_AUTHOR("Peng Fan "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch b/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch new file mode 100644 index 000000000..59b2f9fa2 --- /dev/null +++ b/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch @@ -0,0 +1,96 @@ +From 27f699e578b1a72df89dfa3bc42e093a01dc8d10 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 11 Jun 2023 15:03:29 +0100 +Subject: [PATCH] nvmem: core: add support for fixed cells *layout* +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This adds support for the "fixed-layout" NVMEM layout binding. It allows +defining NVMEM cells in a layout DT node named "nvmem-layout". + +While NVMEM subsystem supports layout drivers it has been discussed that +"fixed-layout" may actually be supperted internally. It's because: +1. It's a very basic layout +2. It allows sharing code with legacy syntax parsing +3. It's safer for soc_device_match() due to -EPROBE_DEFER +4. This will make the syntax transition easier + +Signed-off-by: Rafał Miłecki +Reviewed-by: Michael Walle +Signed-off-by: Srinivas Kandagatla +Message-ID: <20230611140330.154222-26-srinivas.kandagatla@linaro.org> +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 32 +++++++++++++++++++++++++++++--- + 1 file changed, 29 insertions(+), 3 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -696,7 +696,7 @@ static int nvmem_validate_keepouts(struc + return 0; + } + +-static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) ++static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) + { + struct nvmem_layout *layout = nvmem->layout; + struct device *dev = &nvmem->dev; +@@ -704,7 +704,7 @@ static int nvmem_add_cells_from_of(struc + const __be32 *addr; + int len, ret; + +- for_each_child_of_node(dev->of_node, child) { ++ for_each_child_of_node(np, child) { + struct nvmem_cell_info info = {0}; + + addr = of_get_property(child, "reg", &len); +@@ -742,6 +742,28 @@ static int nvmem_add_cells_from_of(struc + return 0; + } + ++static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem) ++{ ++ return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node); ++} ++ ++static int nvmem_add_cells_from_fixed_layout(struct nvmem_device *nvmem) ++{ ++ struct device_node *layout_np; ++ int err = 0; ++ ++ layout_np = of_nvmem_layout_get_container(nvmem); ++ if (!layout_np) ++ return 0; ++ ++ if (of_device_is_compatible(layout_np, "fixed-layout")) ++ err = nvmem_add_cells_from_dt(nvmem, layout_np); ++ ++ of_node_put(layout_np); ++ ++ return err; ++} ++ + int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) + { + layout->owner = owner; +@@ -972,7 +994,7 @@ struct nvmem_device *nvmem_register(cons + if (rval) + goto err_remove_cells; + +- rval = nvmem_add_cells_from_of(nvmem); ++ rval = nvmem_add_cells_from_legacy_of(nvmem); + if (rval) + goto err_remove_cells; + +@@ -982,6 +1004,10 @@ struct nvmem_device *nvmem_register(cons + if (rval) + goto err_remove_cells; + ++ rval = nvmem_add_cells_from_fixed_layout(nvmem); ++ if (rval) ++ goto err_remove_cells; ++ + rval = nvmem_add_cells_from_layout(nvmem); + if (rval) + goto err_remove_cells; diff --git a/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch b/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch new file mode 100644 index 000000000..f568c3f6c --- /dev/null +++ b/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch @@ -0,0 +1,58 @@ +From c5d264d4b527c96ae8903376a4b195df47b05203 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:43 +0000 +Subject: [PATCH] of: base: add of_parse_phandle_with_optional_args() + +Add a new variant of the of_parse_phandle_with_args() which treats the +cells name as optional. If it's missing, it is assumed that the phandle +has no arguments. + +Up until now, a nvmem node didn't have any arguments, so all the device +trees haven't any '#*-cells' property. But there is a need for an +additional argument for the phandle, for which we need a '#*-cells' +property. Therefore, we need to support nvmem nodes with and without +this property. + +Signed-off-by: Michael Walle +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-10-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/of.h | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -1009,6 +1009,31 @@ static inline int of_parse_phandle_with_ + } + + /** ++ * of_parse_phandle_with_optional_args() - Find a node pointed by phandle in a list ++ * @np: pointer to a device tree node containing a list ++ * @list_name: property name that contains a list ++ * @cells_name: property name that specifies phandles' arguments count ++ * @index: index of a phandle to parse out ++ * @out_args: optional pointer to output arguments structure (will be filled) ++ * ++ * Same as of_parse_phandle_with_args() except that if the cells_name property ++ * is not found, cell_count of 0 is assumed. ++ * ++ * This is used to useful, if you have a phandle which didn't have arguments ++ * before and thus doesn't have a '#*-cells' property but is now migrated to ++ * having arguments while retaining backwards compatibility. ++ */ ++static inline int of_parse_phandle_with_optional_args(const struct device_node *np, ++ const char *list_name, ++ const char *cells_name, ++ int index, ++ struct of_phandle_args *out_args) ++{ ++ return __of_parse_phandle_with_args(np, list_name, cells_name, ++ 0, index, out_args); ++} ++ ++/** + * of_property_count_u8_elems - Count the number of u8 elements in a property + * + * @np: device node from which the property value is to be read. diff --git a/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch b/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch new file mode 100644 index 000000000..c4f44b87a --- /dev/null +++ b/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch @@ -0,0 +1,34 @@ +From ff24fed10ba414d19579e26e60b126fad2f2bb07 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:44 +0000 +Subject: [PATCH] of: property: make #.*-cells optional for simple props + +Sometimes, future bindings for phandles will get additional arguments. +Thus the target node of the phandle will need a new #.*-cells property. +To be backwards compatible, this needs to be optional. + +Prepare the DEFINE_SIMPLE_PROPS() to handle the cells name as optional. + +Signed-off-by: Michael Walle +Tested-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-11-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/property.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/of/property.c ++++ b/drivers/of/property.c +@@ -1202,8 +1202,8 @@ static struct device_node *parse_prop_ce + if (strcmp(prop_name, list_name)) + return NULL; + +- if (of_parse_phandle_with_args(np, list_name, cells_name, index, +- &sup_args)) ++ if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index, ++ &sup_args)) + return NULL; + + return sup_args.np; diff --git a/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch b/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch new file mode 100644 index 000000000..c2b86de9b --- /dev/null +++ b/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch @@ -0,0 +1,30 @@ +From e2d8172043d2e50df19fcd59c11e5593de8188d7 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Mon, 6 Feb 2023 13:43:45 +0000 +Subject: [PATCH] of: property: add #nvmem-cell-cells property + +Bindings describe the new '#nvmem-cell-cells' property. Now that the +arguments count property is optional, we just add this property to the +nvmem-cells. + +Signed-off-by: Michael Walle +Tested-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230206134356.839737-12-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/property.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/of/property.c ++++ b/drivers/of/property.c +@@ -1307,7 +1307,7 @@ DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-c + DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells") + DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells") + DEFINE_SIMPLE_PROP(extcon, "extcon", NULL) +-DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", NULL) ++DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", "#nvmem-cell-cells") + DEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells") + DEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL) + DEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL) diff --git a/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch b/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch new file mode 100644 index 000000000..8dc370618 --- /dev/null +++ b/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch @@ -0,0 +1,37 @@ +From 553bd29700145e1849698985e9800f14e967da49 Mon Sep 17 00:00:00 2001 +From: Alexander Stein +Date: Tue, 7 Feb 2023 12:05:29 +0100 +Subject: [PATCH] of: device: Ignore modalias of reused nodes + +If of_node is reused, do not use that node's modalias. This will hide +the name of the actual device. This is rather prominent in USB glue +drivers creating a platform device for the host controller. + +Signed-off-by: Alexander Stein +Reviewed-by: Rob Herring +Link: https://lore.kernel.org/r/20230207110531.1060252-2-alexander.stein@ew.tq-group.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -256,7 +256,7 @@ static ssize_t of_device_get_modalias(st + ssize_t csize; + ssize_t tsize; + +- if ((!dev) || (!dev->of_node)) ++ if ((!dev) || (!dev->of_node) || dev->of_node_reused) + return -ENODEV; + + /* Name & Type */ +@@ -379,7 +379,7 @@ int of_device_uevent_modalias(struct dev + { + int sl; + +- if ((!dev) || (!dev->of_node)) ++ if ((!dev) || (!dev->of_node) || dev->of_node_reused) + return -ENODEV; + + /* Devicetree modalias is tricky, we add it in 2 steps */ diff --git a/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch b/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch new file mode 100644 index 000000000..dcdc2313b --- /dev/null +++ b/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch @@ -0,0 +1,29 @@ +From 2295bed9bebe8d1eef276194fed5b5fbe89c5363 Mon Sep 17 00:00:00 2001 +From: Alexander Stein +Date: Tue, 7 Feb 2023 12:05:30 +0100 +Subject: [PATCH] of: device: Do not ignore error code in + of_device_uevent_modalias + +of_device_get_modalias might return an error code, propagate that one. +Otherwise the negative, signed integer is propagated to unsigned integer +for the comparison resulting in a huge 'sl' size. + +Signed-off-by: Alexander Stein +Reviewed-by: Rob Herring +Link: https://lore.kernel.org/r/20230207110531.1060252-3-alexander.stein@ew.tq-group.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -388,6 +388,8 @@ int of_device_uevent_modalias(struct dev + + sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], + sizeof(env->buf) - env->buflen); ++ if (sl < 0) ++ return sl; + if (sl >= (sizeof(env->buf) - env->buflen)) + return -ENOMEM; + env->buflen += sl; diff --git a/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch b/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch new file mode 100644 index 000000000..280ed9085 --- /dev/null +++ b/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch @@ -0,0 +1,103 @@ +From 5c3d15e127ebfc0754cd18def7124633b6d46672 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:15 +0100 +Subject: [PATCH] of: Update of_device_get_modalias() + +This function only needs a "struct device_node" to work, but for +convenience the author (and only user) of this helper did use a "struct +device" and put it in device.c. + +Let's convert this helper to take a "struct device node" instead. This +change asks for two additional changes: renaming it "of_modalias()" +to fit the current naming, and moving it outside of device.c which will +be done in a follow-up commit. + +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-8-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -248,7 +248,7 @@ const void *of_device_get_match_data(con + } + EXPORT_SYMBOL(of_device_get_match_data); + +-static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) ++static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) + { + const char *compat; + char *c; +@@ -256,19 +256,16 @@ static ssize_t of_device_get_modalias(st + ssize_t csize; + ssize_t tsize; + +- if ((!dev) || (!dev->of_node) || dev->of_node_reused) +- return -ENODEV; +- + /* Name & Type */ + /* %p eats all alphanum characters, so %c must be used here */ +- csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T', +- of_node_get_device_type(dev->of_node)); ++ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', ++ of_node_get_device_type(np)); + tsize = csize; + len -= csize; + if (str) + str += csize; + +- of_property_for_each_string(dev->of_node, "compatible", p, compat) { ++ of_property_for_each_string(np, "compatible", p, compat) { + csize = strlen(compat) + 1; + tsize += csize; + if (csize > len) +@@ -293,7 +290,10 @@ int of_device_request_module(struct devi + ssize_t size; + int ret; + +- size = of_device_get_modalias(dev, NULL, 0); ++ if (!dev || !dev->of_node) ++ return -ENODEV; ++ ++ size = of_modalias(dev->of_node, NULL, 0); + if (size < 0) + return size; + +@@ -304,7 +304,7 @@ int of_device_request_module(struct devi + if (!str) + return -ENOMEM; + +- of_device_get_modalias(dev, str, size); ++ of_modalias(dev->of_node, str, size); + str[size - 1] = '\0'; + ret = request_module(str); + kfree(str); +@@ -321,7 +321,12 @@ EXPORT_SYMBOL_GPL(of_device_request_modu + */ + ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) + { +- ssize_t sl = of_device_get_modalias(dev, str, len - 2); ++ ssize_t sl; ++ ++ if (!dev || !dev->of_node || dev->of_node_reused) ++ return -ENODEV; ++ ++ sl = of_modalias(dev->of_node, str, len - 2); + if (sl < 0) + return sl; + if (sl > len - 2) +@@ -386,8 +391,8 @@ int of_device_uevent_modalias(struct dev + if (add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + +- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], +- sizeof(env->buf) - env->buflen); ++ sl = of_modalias(dev->of_node, &env->buf[env->buflen-1], ++ sizeof(env->buf) - env->buflen); + if (sl < 0) + return sl; + if (sl >= (sizeof(env->buf) - env->buflen)) diff --git a/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch b/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch new file mode 100644 index 000000000..f82dc1428 --- /dev/null +++ b/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch @@ -0,0 +1,173 @@ +From 673aa1ed1c9b6710bf24e3f0957d85e2f46c77db Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:16 +0100 +Subject: [PATCH] of: Rename of_modalias_node() + +This helper does not produce a real modalias, but tries to get the +"product" compatible part of the "vendor,product" compatibles only. It +is far from creating a purely useful modalias string and does not seem +to be used like that directly anyway, so let's try to give this helper a +more meaningful name before moving there a real modalias helper (already +existing under of/device.c). + +Also update the various documentations to refer to the strings as +"aliases" rather than "modaliases" which has a real meaning in the Linux +kernel. + +There is no functional change. + +Cc: Rafael J. Wysocki +Cc: Len Brown +Cc: Maarten Lankhorst +Cc: Maxime Ripard +Cc: Thomas Zimmermann +Cc: Sebastian Reichel +Cc: Wolfram Sang +Cc: Mark Brown +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Acked-by: Mark Brown +Signed-off-by: Srinivas Kandagatla +Acked-by: Sebastian Reichel +Link: https://lore.kernel.org/r/20230404172148.82422-9-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/bus.c | 7 ++++--- + drivers/gpu/drm/drm_mipi_dsi.c | 2 +- + drivers/hsi/hsi_core.c | 2 +- + drivers/i2c/busses/i2c-powermac.c | 2 +- + drivers/i2c/i2c-core-of.c | 2 +- + drivers/of/base.c | 18 +++++++++++------- + drivers/spi/spi.c | 4 ++-- + include/linux/of.h | 3 ++- + 8 files changed, 23 insertions(+), 17 deletions(-) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -806,9 +806,10 @@ static bool acpi_of_modalias(struct acpi + * @modalias: Pointer to buffer that modalias value will be copied into + * @len: Length of modalias buffer + * +- * This is a counterpart of of_modalias_node() for struct acpi_device objects. +- * If there is a compatible string for @adev, it will be copied to @modalias +- * with the vendor prefix stripped; otherwise, @default_id will be used. ++ * This is a counterpart of of_alias_from_compatible() for struct acpi_device ++ * objects. If there is a compatible string for @adev, it will be copied to ++ * @modalias with the vendor prefix stripped; otherwise, @default_id will be ++ * used. + */ + void acpi_set_modalias(struct acpi_device *adev, const char *default_id, + char *modalias, size_t len) +--- a/drivers/gpu/drm/drm_mipi_dsi.c ++++ b/drivers/gpu/drm/drm_mipi_dsi.c +@@ -160,7 +160,7 @@ of_mipi_dsi_device_add(struct mipi_dsi_h + int ret; + u32 reg; + +- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { ++ if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) { + drm_err(host, "modalias failure on %pOF\n", node); + return ERR_PTR(-EINVAL); + } +--- a/drivers/hsi/hsi_core.c ++++ b/drivers/hsi/hsi_core.c +@@ -207,7 +207,7 @@ static void hsi_add_client_from_dt(struc + if (!cl) + return; + +- err = of_modalias_node(client, name, sizeof(name)); ++ err = of_alias_from_compatible(client, name, sizeof(name)); + if (err) + goto err; + +--- a/drivers/i2c/busses/i2c-powermac.c ++++ b/drivers/i2c/busses/i2c-powermac.c +@@ -284,7 +284,7 @@ static bool i2c_powermac_get_type(struct + */ + + /* First try proper modalias */ +- if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) { ++ if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) { + snprintf(type, type_size, "MAC,%s", tmp); + return true; + } +--- a/drivers/i2c/i2c-core-of.c ++++ b/drivers/i2c/i2c-core-of.c +@@ -27,7 +27,7 @@ int of_i2c_get_board_info(struct device + + memset(info, 0, sizeof(*info)); + +- if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { ++ if (of_alias_from_compatible(node, info->type, sizeof(info->type)) < 0) { + dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); + return -EINVAL; + } +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -1208,19 +1208,23 @@ struct device_node *of_find_matching_nod + EXPORT_SYMBOL(of_find_matching_node_and_match); + + /** +- * of_modalias_node - Lookup appropriate modalias for a device node ++ * of_alias_from_compatible - Lookup appropriate alias for a device node ++ * depending on compatible + * @node: pointer to a device tree node +- * @modalias: Pointer to buffer that modalias value will be copied into +- * @len: Length of modalias value ++ * @alias: Pointer to buffer that alias value will be copied into ++ * @len: Length of alias value + * + * Based on the value of the compatible property, this routine will attempt +- * to choose an appropriate modalias value for a particular device tree node. ++ * to choose an appropriate alias value for a particular device tree node. + * It does this by stripping the manufacturer prefix (as delimited by a ',') + * from the first entry in the compatible list property. + * ++ * Note: The matching on just the "product" side of the compatible is a relic ++ * from I2C and SPI. Please do not add any new user. ++ * + * Return: This routine returns 0 on success, <0 on failure. + */ +-int of_modalias_node(struct device_node *node, char *modalias, int len) ++int of_alias_from_compatible(const struct device_node *node, char *alias, int len) + { + const char *compatible, *p; + int cplen; +@@ -1229,10 +1233,10 @@ int of_modalias_node(struct device_node + if (!compatible || strlen(compatible) > cplen) + return -ENODEV; + p = strchr(compatible, ','); +- strscpy(modalias, p ? p + 1 : compatible, len); ++ strscpy(alias, p ? p + 1 : compatible, len); + return 0; + } +-EXPORT_SYMBOL_GPL(of_modalias_node); ++EXPORT_SYMBOL_GPL(of_alias_from_compatible); + + /** + * of_find_node_by_phandle - Find a node given a phandle +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2315,8 +2315,8 @@ of_register_spi_device(struct spi_contro + } + + /* Select device driver */ +- rc = of_modalias_node(nc, spi->modalias, +- sizeof(spi->modalias)); ++ rc = of_alias_from_compatible(nc, spi->modalias, ++ sizeof(spi->modalias)); + if (rc < 0) { + dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc); + goto err_out; +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -362,7 +362,8 @@ extern int of_n_addr_cells(struct device + extern int of_n_size_cells(struct device_node *np); + extern const struct of_device_id *of_match_node( + const struct of_device_id *matches, const struct device_node *node); +-extern int of_modalias_node(struct device_node *node, char *modalias, int len); ++extern int of_alias_from_compatible(const struct device_node *node, char *alias, ++ int len); + extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args); + extern int __of_parse_phandle_with_args(const struct device_node *np, + const char *list_name, const char *cells_name, int cell_count, diff --git a/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch b/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch new file mode 100644 index 000000000..39a84161a --- /dev/null +++ b/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch @@ -0,0 +1,160 @@ +From bd7a7ed774afd1a4174df34227626c95573be517 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:17 +0100 +Subject: [PATCH] of: Move of_modalias() to module.c + +Create a specific .c file for OF related module handling. +Move of_modalias() inside as a first step. + +The helper is exposed through of.h even though it is only used by core +files because the users from device.c will soon be split into an OF-only +helper in module.c as well as a device-oriented inline helper in +of_device.h. Putting this helper in of_private.h would require to +include of_private.h from of_device.h, which is not acceptable. + +Suggested-by: Rob Herring +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-10-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/Makefile | 2 +- + drivers/of/device.c | 37 ------------------------------------- + drivers/of/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + include/linux/of.h | 9 +++++++++ + 4 files changed, 54 insertions(+), 38 deletions(-) + create mode 100644 drivers/of/module.c + +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -1,5 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 +-obj-y = base.o device.o platform.o property.o ++obj-y = base.o device.o module.o platform.o property.o + obj-$(CONFIG_OF_KOBJ) += kobj.o + obj-$(CONFIG_OF_DYNAMIC) += dynamic.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -1,5 +1,4 @@ + // SPDX-License-Identifier: GPL-2.0 +-#include + #include + #include + #include +@@ -248,42 +247,6 @@ const void *of_device_get_match_data(con + } + EXPORT_SYMBOL(of_device_get_match_data); + +-static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) +-{ +- const char *compat; +- char *c; +- struct property *p; +- ssize_t csize; +- ssize_t tsize; +- +- /* Name & Type */ +- /* %p eats all alphanum characters, so %c must be used here */ +- csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', +- of_node_get_device_type(np)); +- tsize = csize; +- len -= csize; +- if (str) +- str += csize; +- +- of_property_for_each_string(np, "compatible", p, compat) { +- csize = strlen(compat) + 1; +- tsize += csize; +- if (csize > len) +- continue; +- +- csize = snprintf(str, len, "C%s", compat); +- for (c = str; c; ) { +- c = strchr(c, ' '); +- if (c) +- *c++ = '_'; +- } +- len -= csize; +- str += csize; +- } +- +- return tsize; +-} +- + int of_device_request_module(struct device *dev) + { + char *str; +--- /dev/null ++++ b/drivers/of/module.c +@@ -0,0 +1,44 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Linux kernel module helpers. ++ */ ++ ++#include ++#include ++#include ++ ++ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) ++{ ++ const char *compat; ++ char *c; ++ struct property *p; ++ ssize_t csize; ++ ssize_t tsize; ++ ++ /* Name & Type */ ++ /* %p eats all alphanum characters, so %c must be used here */ ++ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', ++ of_node_get_device_type(np)); ++ tsize = csize; ++ len -= csize; ++ if (str) ++ str += csize; ++ ++ of_property_for_each_string(np, "compatible", p, compat) { ++ csize = strlen(compat) + 1; ++ tsize += csize; ++ if (csize > len) ++ continue; ++ ++ csize = snprintf(str, len, "C%s", compat); ++ for (c = str; c; ) { ++ c = strchr(c, ' '); ++ if (c) ++ *c++ = '_'; ++ } ++ len -= csize; ++ str += csize; ++ } ++ ++ return tsize; ++} +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -374,6 +374,9 @@ extern int of_parse_phandle_with_args_ma + extern int of_count_phandle_with_args(const struct device_node *np, + const char *list_name, const char *cells_name); + ++/* module functions */ ++extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); ++ + /* phandle iterator functions */ + extern int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, +@@ -731,6 +734,12 @@ static inline int of_count_phandle_with_ + return -ENOSYS; + } + ++static inline ssize_t of_modalias(const struct device_node *np, char *str, ++ ssize_t len) ++{ ++ return -ENODEV; ++} ++ + static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, + const char *list_name, diff --git a/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch b/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch new file mode 100644 index 000000000..046c1df56 --- /dev/null +++ b/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch @@ -0,0 +1,131 @@ +From e6506f06d5e82765666902ccf9e9162f3e31d518 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 4 Apr 2023 18:21:18 +0100 +Subject: [PATCH] of: Move the request module helper logic to module.c + +Depending on device.c for pure OF handling is considered +backwards. Let's extract the content of of_device_request_module() to +have the real logic under module.c. + +The next step will be to convert users of of_device_request_module() to +use the new helper. + +Signed-off-by: Miquel Raynal +Reviewed-by: Rob Herring +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20230404172148.82422-11-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/device.c | 25 ++----------------------- + drivers/of/module.c | 30 ++++++++++++++++++++++++++++++ + include/linux/of.h | 6 ++++++ + 3 files changed, 38 insertions(+), 23 deletions(-) + +--- a/drivers/of/device.c ++++ b/drivers/of/device.c +@@ -8,7 +8,6 @@ + #include /* for bus_dma_region */ + #include + #include +-#include + #include + #include + #include +@@ -249,30 +248,10 @@ EXPORT_SYMBOL(of_device_get_match_data); + + int of_device_request_module(struct device *dev) + { +- char *str; +- ssize_t size; +- int ret; +- +- if (!dev || !dev->of_node) ++ if (!dev) + return -ENODEV; + +- size = of_modalias(dev->of_node, NULL, 0); +- if (size < 0) +- return size; +- +- /* Reserve an additional byte for the trailing '\0' */ +- size++; +- +- str = kmalloc(size, GFP_KERNEL); +- if (!str) +- return -ENOMEM; +- +- of_modalias(dev->of_node, str, size); +- str[size - 1] = '\0'; +- ret = request_module(str); +- kfree(str); +- +- return ret; ++ return of_request_module(dev->of_node); + } + EXPORT_SYMBOL_GPL(of_device_request_module); + +--- a/drivers/of/module.c ++++ b/drivers/of/module.c +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include + #include + +@@ -42,3 +43,32 @@ ssize_t of_modalias(const struct device_ + + return tsize; + } ++ ++int of_request_module(const struct device_node *np) ++{ ++ char *str; ++ ssize_t size; ++ int ret; ++ ++ if (!np) ++ return -ENODEV; ++ ++ size = of_modalias(np, NULL, 0); ++ if (size < 0) ++ return size; ++ ++ /* Reserve an additional byte for the trailing '\0' */ ++ size++; ++ ++ str = kmalloc(size, GFP_KERNEL); ++ if (!str) ++ return -ENOMEM; ++ ++ of_modalias(np, str, size); ++ str[size - 1] = '\0'; ++ ret = request_module(str); ++ kfree(str); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(of_request_module); +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -376,6 +376,7 @@ extern int of_count_phandle_with_args(co + + /* module functions */ + extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); ++extern int of_request_module(const struct device_node *np); + + /* phandle iterator functions */ + extern int of_phandle_iterator_init(struct of_phandle_iterator *it, +@@ -739,6 +740,11 @@ static inline ssize_t of_modalias(const + { + return -ENODEV; + } ++ ++static inline int of_request_module(const struct device_node *np) ++{ ++ return -ENODEV; ++} + + static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, + const struct device_node *np, diff --git a/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch b/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch new file mode 100644 index 000000000..3319f431b --- /dev/null +++ b/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch @@ -0,0 +1,207 @@ +From 77faa07c185c969e742cbb3e6aa487a11b0b616c Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Tue, 30 Aug 2022 09:57:42 +0300 +Subject: [PATCH] dt-bindings: arm: qcom: document qcom,msm-id and + qcom,board-id + +The top level qcom,msm-id and qcom,board-id properties are utilized by +bootloaders on Qualcomm MSM platforms to determine which device tree +should be used and passed to the kernel. + +The commit b32e592d3c28 ("devicetree: bindings: Document qcom board +compatible format") from 2015 was a consensus during discussion about +upstreaming qcom,msm-id and qcom,board-id fields. There are however still +problems with that consensus: +1. It was reached 7 years ago but it turned out its implementation did + not reach all possible products. + +2. Initially additional tool (dtbTool) was needed for parsing these + fields to create a QCDT image consisting of multiple DTBs, later the + bootloaders were improved and they use these qcom,msm-id and + qcom,board-id properties directly. + +3. Extracting relevant information from the board compatible requires + this additional tool (dtbTool), which makes the build process more + complicated and not easily reproducible (DTBs are modified after the + kernel build). + +4. Some versions of Qualcomm bootloaders expect these properties even + when booting with a single DTB. The community is stuck with these + bootloaders thus they require properties in the DTBs. + +Since several upstreamed Qualcomm SoC-based boards require these +properties to properly boot and the properties are reportedly used by +bootloaders, document them along with the bindings header with constants +used by: bootloader, some DTS and socinfo driver. + +Link: https://lore.kernel.org/r/a3c932d1-a102-ce18-deea-18cbbd05ecab@linaro.org/ +Co-developed-by: Kumar Gala +Signed-off-by: Kumar Gala +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Rob Herring +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220830065744.161163-2-krzysztof.kozlowski@linaro.org +--- + include/dt-bindings/arm/qcom,ids.h | 155 +++++++++++++++++++++++++++++ + 1 file changed, 155 insertions(+) + create mode 100644 include/dt-bindings/arm/qcom,ids.h + +--- /dev/null ++++ b/include/dt-bindings/arm/qcom,ids.h +@@ -0,0 +1,155 @@ ++/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ ++/* ++ * Copyright (c) 2015, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Linaro Ltd ++ * Author: Krzysztof Kozlowski based on previous work of Kumar Gala. ++ */ ++#ifndef _DT_BINDINGS_ARM_QCOM_IDS_H ++#define _DT_BINDINGS_ARM_QCOM_IDS_H ++ ++/* ++ * The MSM chipset and hardware revision used by Qualcomm bootloaders, DTS for ++ * older chipsets (qcom,msm-id) and in socinfo driver: ++ */ ++#define QCOM_ID_MSM8960 87 ++#define QCOM_ID_APQ8064 109 ++#define QCOM_ID_MSM8660A 122 ++#define QCOM_ID_MSM8260A 123 ++#define QCOM_ID_APQ8060A 124 ++#define QCOM_ID_MSM8974 126 ++#define QCOM_ID_MPQ8064 130 ++#define QCOM_ID_MSM8960AB 138 ++#define QCOM_ID_APQ8060AB 139 ++#define QCOM_ID_MSM8260AB 140 ++#define QCOM_ID_MSM8660AB 141 ++#define QCOM_ID_MSM8626 145 ++#define QCOM_ID_MSM8610 147 ++#define QCOM_ID_APQ8064AB 153 ++#define QCOM_ID_MSM8226 158 ++#define QCOM_ID_MSM8526 159 ++#define QCOM_ID_MSM8110 161 ++#define QCOM_ID_MSM8210 162 ++#define QCOM_ID_MSM8810 163 ++#define QCOM_ID_MSM8212 164 ++#define QCOM_ID_MSM8612 165 ++#define QCOM_ID_MSM8112 166 ++#define QCOM_ID_MSM8225Q 168 ++#define QCOM_ID_MSM8625Q 169 ++#define QCOM_ID_MSM8125Q 170 ++#define QCOM_ID_APQ8064AA 172 ++#define QCOM_ID_APQ8084 178 ++#define QCOM_ID_APQ8074 184 ++#define QCOM_ID_MSM8274 185 ++#define QCOM_ID_MSM8674 186 ++#define QCOM_ID_MSM8974PRO_AC 194 ++#define QCOM_ID_MSM8126 198 ++#define QCOM_ID_APQ8026 199 ++#define QCOM_ID_MSM8926 200 ++#define QCOM_ID_MSM8326 205 ++#define QCOM_ID_MSM8916 206 ++#define QCOM_ID_MSM8994 207 ++#define QCOM_ID_APQ8074PRO_AA 208 ++#define QCOM_ID_APQ8074PRO_AB 209 ++#define QCOM_ID_APQ8074PRO_AC 210 ++#define QCOM_ID_MSM8274PRO_AA 211 ++#define QCOM_ID_MSM8274PRO_AB 212 ++#define QCOM_ID_MSM8274PRO_AC 213 ++#define QCOM_ID_MSM8674PRO_AA 214 ++#define QCOM_ID_MSM8674PRO_AB 215 ++#define QCOM_ID_MSM8674PRO_AC 216 ++#define QCOM_ID_MSM8974PRO_AA 217 ++#define QCOM_ID_MSM8974PRO_AB 218 ++#define QCOM_ID_APQ8028 219 ++#define QCOM_ID_MSM8128 220 ++#define QCOM_ID_MSM8228 221 ++#define QCOM_ID_MSM8528 222 ++#define QCOM_ID_MSM8628 223 ++#define QCOM_ID_MSM8928 224 ++#define QCOM_ID_MSM8510 225 ++#define QCOM_ID_MSM8512 226 ++#define QCOM_ID_MSM8936 233 ++#define QCOM_ID_MSM8939 239 ++#define QCOM_ID_APQ8036 240 ++#define QCOM_ID_APQ8039 241 ++#define QCOM_ID_MSM8996 246 ++#define QCOM_ID_APQ8016 247 ++#define QCOM_ID_MSM8216 248 ++#define QCOM_ID_MSM8116 249 ++#define QCOM_ID_MSM8616 250 ++#define QCOM_ID_MSM8992 251 ++#define QCOM_ID_APQ8094 253 ++#define QCOM_ID_MDM9607 290 ++#define QCOM_ID_APQ8096 291 ++#define QCOM_ID_MSM8998 292 ++#define QCOM_ID_MSM8953 293 ++#define QCOM_ID_MDM8207 296 ++#define QCOM_ID_MDM9207 297 ++#define QCOM_ID_MDM9307 298 ++#define QCOM_ID_MDM9628 299 ++#define QCOM_ID_APQ8053 304 ++#define QCOM_ID_MSM8996SG 305 ++#define QCOM_ID_MSM8996AU 310 ++#define QCOM_ID_APQ8096AU 311 ++#define QCOM_ID_APQ8096SG 312 ++#define QCOM_ID_SDM660 317 ++#define QCOM_ID_SDM630 318 ++#define QCOM_ID_APQ8098 319 ++#define QCOM_ID_SDM845 321 ++#define QCOM_ID_MDM9206 322 ++#define QCOM_ID_IPQ8074 323 ++#define QCOM_ID_SDA660 324 ++#define QCOM_ID_SDM658 325 ++#define QCOM_ID_SDA658 326 ++#define QCOM_ID_SDA630 327 ++#define QCOM_ID_SDM450 338 ++#define QCOM_ID_SDA845 341 ++#define QCOM_ID_IPQ8072 342 ++#define QCOM_ID_IPQ8076 343 ++#define QCOM_ID_IPQ8078 344 ++#define QCOM_ID_SDM636 345 ++#define QCOM_ID_SDA636 346 ++#define QCOM_ID_SDM632 349 ++#define QCOM_ID_SDA632 350 ++#define QCOM_ID_SDA450 351 ++#define QCOM_ID_SM8250 356 ++#define QCOM_ID_IPQ8070 375 ++#define QCOM_ID_IPQ8071 376 ++#define QCOM_ID_IPQ8072A 389 ++#define QCOM_ID_IPQ8074A 390 ++#define QCOM_ID_IPQ8076A 391 ++#define QCOM_ID_IPQ8078A 392 ++#define QCOM_ID_SM6125 394 ++#define QCOM_ID_IPQ8070A 395 ++#define QCOM_ID_IPQ8071A 396 ++#define QCOM_ID_IPQ6018 402 ++#define QCOM_ID_IPQ6028 403 ++#define QCOM_ID_IPQ6000 421 ++#define QCOM_ID_IPQ6010 422 ++#define QCOM_ID_SC7180 425 ++#define QCOM_ID_SM6350 434 ++#define QCOM_ID_SM8350 439 ++#define QCOM_ID_SC8280XP 449 ++#define QCOM_ID_IPQ6005 453 ++#define QCOM_ID_QRB5165 455 ++#define QCOM_ID_SM8450 457 ++#define QCOM_ID_SM7225 459 ++#define QCOM_ID_SA8295P 460 ++#define QCOM_ID_SA8540P 461 ++#define QCOM_ID_SM8450_2 480 ++#define QCOM_ID_SM8450_3 482 ++#define QCOM_ID_SC7280 487 ++#define QCOM_ID_SC7180P 495 ++#define QCOM_ID_SM6375 507 ++ ++/* ++ * The board type and revision information, used by Qualcomm bootloaders and ++ * DTS for older chipsets (qcom,board-id): ++ */ ++#define QCOM_BOARD_ID(a, major, minor) \ ++ (((major & 0xff) << 16) | ((minor & 0xff) << 8) | QCOM_BOARD_ID_##a) ++ ++#define QCOM_BOARD_ID_MTP 8 ++#define QCOM_BOARD_ID_DRAGONBOARD 10 ++#define QCOM_BOARD_ID_SBC 24 ++ ++#endif /* _DT_BINDINGS_ARM_QCOM_IDS_H */ diff --git a/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch b/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch new file mode 100644 index 000000000..394087a27 --- /dev/null +++ b/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch @@ -0,0 +1,171 @@ +From 7cbff3c3f867ff3b24de674f44ca03f54e416a37 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sat, 31 Dec 2022 00:27:42 +0100 +Subject: [PATCH] soc: qcom: socinfo: move SMEM item struct and defines to a + header + +Move SMEM item struct and related defines to a header in order to be able +to reuse them in the Qualcomm NVMEM CPUFreq driver instead of duplicating +them. + +Signed-off-by: Robert Marko +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230526204802.3081168-1-robimarko@gmail.com +--- + drivers/soc/qcom/socinfo.c | 58 +-------------------------- + include/linux/soc/qcom/socinfo.h | 67 ++++++++++++++++++++++++++++++++ + 2 files changed, 68 insertions(+), 57 deletions(-) + create mode 100644 include/linux/soc/qcom/socinfo.h + +--- a/drivers/soc/qcom/socinfo.c ++++ b/drivers/soc/qcom/socinfo.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -25,15 +26,6 @@ + #define SOCINFO_MINOR(ver) ((ver) & 0xffff) + #define SOCINFO_VERSION(maj, min) ((((maj) & 0xffff) << 16)|((min) & 0xffff)) + +-#define SMEM_SOCINFO_BUILD_ID_LENGTH 32 +-#define SMEM_SOCINFO_CHIP_ID_LENGTH 32 +- +-/* +- * SMEM item id, used to acquire handles to respective +- * SMEM region. +- */ +-#define SMEM_HW_SW_BUILD_ID 137 +- + #ifdef CONFIG_DEBUG_FS + #define SMEM_IMAGE_VERSION_BLOCKS_COUNT 32 + #define SMEM_IMAGE_VERSION_SIZE 4096 +@@ -116,54 +108,6 @@ static const char *const pmic_models[] = + }; + #endif /* CONFIG_DEBUG_FS */ + +-/* Socinfo SMEM item structure */ +-struct socinfo { +- __le32 fmt; +- __le32 id; +- __le32 ver; +- char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH]; +- /* Version 2 */ +- __le32 raw_id; +- __le32 raw_ver; +- /* Version 3 */ +- __le32 hw_plat; +- /* Version 4 */ +- __le32 plat_ver; +- /* Version 5 */ +- __le32 accessory_chip; +- /* Version 6 */ +- __le32 hw_plat_subtype; +- /* Version 7 */ +- __le32 pmic_model; +- __le32 pmic_die_rev; +- /* Version 8 */ +- __le32 pmic_model_1; +- __le32 pmic_die_rev_1; +- __le32 pmic_model_2; +- __le32 pmic_die_rev_2; +- /* Version 9 */ +- __le32 foundry_id; +- /* Version 10 */ +- __le32 serial_num; +- /* Version 11 */ +- __le32 num_pmics; +- __le32 pmic_array_offset; +- /* Version 12 */ +- __le32 chip_family; +- __le32 raw_device_family; +- __le32 raw_device_num; +- /* Version 13 */ +- __le32 nproduct_id; +- char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH]; +- /* Version 14 */ +- __le32 num_clusters; +- __le32 ncluster_array_offset; +- __le32 num_defective_parts; +- __le32 ndefective_parts_array_offset; +- /* Version 15 */ +- __le32 nmodem_supported; +-}; +- + #ifdef CONFIG_DEBUG_FS + struct socinfo_params { + u32 raw_device_family; +--- /dev/null ++++ b/include/linux/soc/qcom/socinfo.h +@@ -0,0 +1,67 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2017-2019, Linaro Ltd. ++ */ ++ ++#ifndef __QCOM_SOCINFO_H__ ++#define __QCOM_SOCINFO_H__ ++ ++/* ++ * SMEM item id, used to acquire handles to respective ++ * SMEM region. ++ */ ++#define SMEM_HW_SW_BUILD_ID 137 ++ ++#define SMEM_SOCINFO_BUILD_ID_LENGTH 32 ++#define SMEM_SOCINFO_CHIP_ID_LENGTH 32 ++ ++/* Socinfo SMEM item structure */ ++struct socinfo { ++ __le32 fmt; ++ __le32 id; ++ __le32 ver; ++ char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH]; ++ /* Version 2 */ ++ __le32 raw_id; ++ __le32 raw_ver; ++ /* Version 3 */ ++ __le32 hw_plat; ++ /* Version 4 */ ++ __le32 plat_ver; ++ /* Version 5 */ ++ __le32 accessory_chip; ++ /* Version 6 */ ++ __le32 hw_plat_subtype; ++ /* Version 7 */ ++ __le32 pmic_model; ++ __le32 pmic_die_rev; ++ /* Version 8 */ ++ __le32 pmic_model_1; ++ __le32 pmic_die_rev_1; ++ __le32 pmic_model_2; ++ __le32 pmic_die_rev_2; ++ /* Version 9 */ ++ __le32 foundry_id; ++ /* Version 10 */ ++ __le32 serial_num; ++ /* Version 11 */ ++ __le32 num_pmics; ++ __le32 pmic_array_offset; ++ /* Version 12 */ ++ __le32 chip_family; ++ __le32 raw_device_family; ++ __le32 raw_device_num; ++ /* Version 13 */ ++ __le32 nproduct_id; ++ char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH]; ++ /* Version 14 */ ++ __le32 num_clusters; ++ __le32 ncluster_array_offset; ++ __le32 num_defective_parts; ++ __le32 ndefective_parts_array_offset; ++ /* Version 15 */ ++ __le32 nmodem_supported; ++}; ++ ++#endif diff --git a/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch b/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch new file mode 100644 index 000000000..7c7c3f363 --- /dev/null +++ b/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch @@ -0,0 +1,55 @@ +From 9f1bbff157a69db7684f5da2f73b2325c638a90e Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 26 May 2023 22:47:59 +0200 +Subject: [PATCH] soc: qcom: smem: Switch to EXPORT_SYMBOL_GPL() + +SMEM has been GPL licensed from the start, and there is no reason to use +EXPORT_SYMBOL() so switch to the GPL version. + +Signed-off-by: Robert Marko +Reviewed-by: Konrad Dybcio +Reviewed-by: Trilok Soni +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230526204802.3081168-2-robimarko@gmail.com +--- + drivers/soc/qcom/smem.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -500,7 +500,7 @@ int qcom_smem_alloc(unsigned host, unsig + + return ret; + } +-EXPORT_SYMBOL(qcom_smem_alloc); ++EXPORT_SYMBOL_GPL(qcom_smem_alloc); + + static void *qcom_smem_get_global(struct qcom_smem *smem, + unsigned item, +@@ -674,7 +674,7 @@ void *qcom_smem_get(unsigned host, unsig + return ptr; + + } +-EXPORT_SYMBOL(qcom_smem_get); ++EXPORT_SYMBOL_GPL(qcom_smem_get); + + /** + * qcom_smem_get_free_space() - retrieve amount of free space in a partition +@@ -719,7 +719,7 @@ int qcom_smem_get_free_space(unsigned ho + + return ret; + } +-EXPORT_SYMBOL(qcom_smem_get_free_space); ++EXPORT_SYMBOL_GPL(qcom_smem_get_free_space); + + static bool addr_in_range(void __iomem *base, size_t size, void *addr) + { +@@ -770,7 +770,7 @@ phys_addr_t qcom_smem_virt_to_phys(void + + return 0; + } +-EXPORT_SYMBOL(qcom_smem_virt_to_phys); ++EXPORT_SYMBOL_GPL(qcom_smem_virt_to_phys); + + static int qcom_smem_get_sbl_version(struct qcom_smem *smem) + { diff --git a/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch b/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch new file mode 100644 index 000000000..4a816bb0f --- /dev/null +++ b/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch @@ -0,0 +1,70 @@ +From c3ecf2602a32d9b9e5fc997076c0d2836495c085 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 26 May 2023 22:48:00 +0200 +Subject: [PATCH] soc: qcom: smem: introduce qcom_smem_get_soc_id() + +Introduce a helper to return the SoC SMEM ID, which is used to identify the +exact SoC model as there may be differences in the same SoC family. + +Currently, cpufreq-nvmem does this completely in the driver and there has +been more interest expresed for other drivers to use this information so +lets expose a common helper to prevent redoing it in individual drivers +since this field is present on every SMEM table version. + +Signed-off-by: Robert Marko +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230526204802.3081168-3-robimarko@gmail.com +--- + drivers/soc/qcom/smem.c | 23 +++++++++++++++++++++++ + include/linux/soc/qcom/smem.h | 2 ++ + 2 files changed, 25 insertions(+) + +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + /* + * The Qualcomm shared memory system is a allocate only heap structure that +@@ -772,6 +773,28 @@ phys_addr_t qcom_smem_virt_to_phys(void + } + EXPORT_SYMBOL_GPL(qcom_smem_virt_to_phys); + ++/** ++ * qcom_smem_get_soc_id() - return the SoC ID ++ * @id: On success, we return the SoC ID here. ++ * ++ * Look up SoC ID from HW/SW build ID and return it. ++ * ++ * Return: 0 on success, negative errno on failure. ++ */ ++int qcom_smem_get_soc_id(u32 *id) ++{ ++ struct socinfo *info; ++ ++ info = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID, NULL); ++ if (IS_ERR(info)) ++ return PTR_ERR(info); ++ ++ *id = __le32_to_cpu(info->id); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(qcom_smem_get_soc_id); ++ + static int qcom_smem_get_sbl_version(struct qcom_smem *smem) + { + struct smem_header *header; +--- a/include/linux/soc/qcom/smem.h ++++ b/include/linux/soc/qcom/smem.h +@@ -11,4 +11,6 @@ int qcom_smem_get_free_space(unsigned ho + + phys_addr_t qcom_smem_virt_to_phys(void *p); + ++int qcom_smem_get_soc_id(u32 *id); ++ + #endif diff --git a/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch b/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch new file mode 100644 index 000000000..9560122cc --- /dev/null +++ b/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch @@ -0,0 +1,51 @@ +From 2b8634d1468ff498cc91b6adf993c27ae6fa079d Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 26 May 2023 22:48:01 +0200 +Subject: [PATCH] cpufreq: qcom-nvmem: use SoC ID-s from bindings + +SMEM SoC ID-s are now stored in DT bindings so lets use those instead of +defining them in the driver again. + +Signed-off-by: Robert Marko +Reviewed-by: Konrad Dybcio +Reviewed-by: Bjorn Andersson +Acked-by: Viresh Kumar +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230526204802.3081168-4-robimarko@gmail.com +--- + drivers/cpufreq/qcom-cpufreq-nvmem.c | 15 +++++---------- + 1 file changed, 5 insertions(+), 10 deletions(-) + +--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c ++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c +@@ -31,12 +31,7 @@ + + #define MSM_ID_SMEM 137 + +-enum _msm_id { +- MSM8996V3 = 0xF6ul, +- APQ8096V3 = 0x123ul, +- MSM8996SG = 0x131ul, +- APQ8096SG = 0x138ul, +-}; ++#include + + enum _msm8996_version { + MSM8996_V3, +@@ -154,12 +149,12 @@ static enum _msm8996_version qcom_cpufre + msm_id++; + + switch ((enum _msm_id)*msm_id) { +- case MSM8996V3: +- case APQ8096V3: ++ case QCOM_ID_MSM8996: ++ case QCOM_ID_APQ8096: + version = MSM8996_V3; + break; +- case MSM8996SG: +- case APQ8096SG: ++ case QCOM_ID_MSM8996SG: ++ case QCOM_ID_APQ8096SG: + version = MSM8996_SG; + break; + default: diff --git a/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch b/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch new file mode 100644 index 000000000..4f37d672b --- /dev/null +++ b/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch @@ -0,0 +1,109 @@ +From e7992615acacc27baeec310197108143afc77337 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 26 May 2023 22:48:02 +0200 +Subject: [PATCH] cpufreq: qcom-nvmem: use helper to get SMEM SoC ID + +Now that SMEM exports a helper to get the SMEM SoC ID lets utilize it. +Currently qcom_cpufreq_get_msm_id() is encoding the returned SMEM SoC ID +into an enum, however there is no reason to do so and we can just match +directly on the SMEM SoC ID as returned by qcom_smem_get_soc_id(). + +Signed-off-by: Robert Marko +Acked-by: Viresh Kumar +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230526204802.3081168-5-robimarko@gmail.com +--- + drivers/cpufreq/qcom-cpufreq-nvmem.c | 56 +++++----------------------- + 1 file changed, 10 insertions(+), 46 deletions(-) + +--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c ++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c +@@ -29,16 +29,8 @@ + #include + #include + +-#define MSM_ID_SMEM 137 +- + #include + +-enum _msm8996_version { +- MSM8996_V3, +- MSM8996_SG, +- NUM_OF_MSM8996_VERSIONS, +-}; +- + struct qcom_cpufreq_drv; + + struct qcom_cpufreq_match_data { +@@ -135,60 +127,32 @@ static void get_krait_bin_format_b(struc + dev_dbg(cpu_dev, "PVS version: %d\n", *pvs_ver); + } + +-static enum _msm8996_version qcom_cpufreq_get_msm_id(void) +-{ +- size_t len; +- u32 *msm_id; +- enum _msm8996_version version; +- +- msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len); +- if (IS_ERR(msm_id)) +- return NUM_OF_MSM8996_VERSIONS; +- +- /* The first 4 bytes are format, next to them is the actual msm-id */ +- msm_id++; +- +- switch ((enum _msm_id)*msm_id) { +- case QCOM_ID_MSM8996: +- case QCOM_ID_APQ8096: +- version = MSM8996_V3; +- break; +- case QCOM_ID_MSM8996SG: +- case QCOM_ID_APQ8096SG: +- version = MSM8996_SG; +- break; +- default: +- version = NUM_OF_MSM8996_VERSIONS; +- } +- +- return version; +-} +- + static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev, + struct nvmem_cell *speedbin_nvmem, + char **pvs_name, + struct qcom_cpufreq_drv *drv) + { + size_t len; ++ u32 msm_id; + u8 *speedbin; +- enum _msm8996_version msm8996_version; ++ int ret; + *pvs_name = NULL; + +- msm8996_version = qcom_cpufreq_get_msm_id(); +- if (NUM_OF_MSM8996_VERSIONS == msm8996_version) { +- dev_err(cpu_dev, "Not Snapdragon 820/821!"); +- return -ENODEV; +- } ++ ret = qcom_smem_get_soc_id(&msm_id); ++ if (ret) ++ return ret; + + speedbin = nvmem_cell_read(speedbin_nvmem, &len); + if (IS_ERR(speedbin)) + return PTR_ERR(speedbin); + +- switch (msm8996_version) { +- case MSM8996_V3: ++ switch (msm_id) { ++ case QCOM_ID_MSM8996: ++ case QCOM_ID_APQ8096: + drv->versions = 1 << (unsigned int)(*speedbin); + break; +- case MSM8996_SG: ++ case QCOM_ID_MSM8996SG: ++ case QCOM_ID_APQ8096SG: + drv->versions = 1 << ((unsigned int)(*speedbin) + 4); + break; + default: diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 index 334b14034..1d8cc64f2 100644 --- a/target/linux/generic/config-6.1 +++ b/target/linux/generic/config-6.1 @@ -123,7 +123,6 @@ CONFIG_64BIT_TIME=y # 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 @@ -148,6 +147,7 @@ CONFIG_AEABI=y # CONFIG_AF_RXRPC_IPV6 is not set CONFIG_AF_UNIX_OOB=y # CONFIG_AGP is not set +# CONFIG_AHCI_BRCM is not set # CONFIG_AHCI_CEVA is not set # CONFIG_AHCI_DWC is not set # CONFIG_AHCI_IMX is not set @@ -189,10 +189,8 @@ 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 # CONFIG_APPLE_GMUX is not set # CONFIG_APPLE_MFI_FASTCHARGE is not set # CONFIG_APPLE_PROPERTIES is not set @@ -223,16 +221,15 @@ CONFIG_ANON_INODES=y # CONFIG_ARCH_BCM_53573 is not set # CONFIG_ARCH_BCM_63XX is not set # CONFIG_ARCH_BCM_CYGNUS is not set +# CONFIG_ARCH_BCM_HR2 is not set # 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 # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CNS3XXX is not set -# CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_DIGICOLOR is not set # CONFIG_ARCH_DMA_ADDR_T_64BIT is not set @@ -241,6 +238,7 @@ CONFIG_ARCH_BINFMT_ELF_STATE=y # CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_EXYNOS is not set CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_FORCE_MAX_ORDER=11 # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_HI3xxx is not set @@ -262,7 +260,6 @@ CONFIG_ARCH_FLATMEM_ENABLE=y # CONFIG_ARCH_LPC32XX is not set # CONFIG_ARCH_MEDIATEK is not set # 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=8 CONFIG_ARCH_MMAP_RND_BITS_MAX=16 @@ -334,7 +331,6 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARCH_VT8500 is not set # CONFIG_ARCH_VULCAN is not set # CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_WANTS_NO_INSTR is not set # CONFIG_ARCH_WANTS_THP_SWAP is not set # CONFIG_ARCH_WM8505 is not set # CONFIG_ARCH_WM8750 is not set @@ -347,13 +343,11 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARC_EMAC is not set # CONFIG_ARC_IRQ_NO_AUTOSAVE is not set # CONFIG_ARM64_16K_PAGES is not set -CONFIG_ARM64_4K_PAGES=y # CONFIG_ARM64_64K_PAGES is not set # CONFIG_ARM64_AMU_EXTN is not set # CONFIG_ARM64_BTI is not set # CONFIG_ARM64_CRYPTO is not set # CONFIG_ARM64_E0PD is not set -# CONFIG_ARM64_EPAN is not set # CONFIG_ARM64_ERRATUM_1024718 is not set # CONFIG_ARM64_ERRATUM_1165522 is not set # CONFIG_ARM64_ERRATUM_1286807 is not set @@ -381,34 +375,27 @@ CONFIG_ARM64_4K_PAGES=y # CONFIG_ARM64_ERRATUM_845719 is not set # CONFIG_ARM64_ERRATUM_858921 is not set # CONFIG_ARM64_HW_AFDBM is not set -# CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419 is not set # CONFIG_ARM64_LSE_ATOMICS is not set -# CONFIG_ARM64_MODULE_PLTS is not set +CONFIG_ARM64_MODULE_PLTS=y # CONFIG_ARM64_MTE is not set # CONFIG_ARM64_PAN is not set # CONFIG_ARM64_PMEM is not set # CONFIG_ARM64_PSEUDO_NMI is not set # CONFIG_ARM64_PTDUMP_DEBUGFS is not set # CONFIG_ARM64_PTR_AUTH is not set -# CONFIG_ARM64_PTR_AUTH_KERNEL is not set # CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set # CONFIG_ARM64_RAS_EXTN is not set # CONFIG_ARM64_RELOC_TEST is not set # CONFIG_ARM64_SME is not set # CONFIG_ARM64_SVE is not set CONFIG_ARM64_SW_TTBR0_PAN=y -# CONFIG_ARM64_TAGGED_ADDR_ABI is not set # CONFIG_ARM64_TLB_RANGE is not set # CONFIG_ARM64_UAO is not set # CONFIG_ARM64_USE_LSE_ATOMICS is not set -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 # CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set # CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set # CONFIG_ARM_CCI is not set @@ -451,22 +438,18 @@ CONFIG_ARM_DMA_MEM_BUFFERABLE=y # CONFIG_ARM_ERRATA_857272 is not set # CONFIG_ARM_FFA_TRANSPORT is not set CONFIG_ARM_GIC_MAX_NR=1 -# CONFIG_ARM_GT_INITIAL_PRESCALER_VAL is not set # 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 +CONFIG_ARM_MODULE_PLTS=y # CONFIG_ARM_PATCH_PHYS_VIRT is not set # CONFIG_ARM_PSCI is not set # CONFIG_ARM_PSCI_CHECKER is not set # CONFIG_ARM_PSCI_CPUIDLE is not set # CONFIG_ARM_PTDUMP_DEBUGFS is not set # 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_PROTOCOL is not set # CONFIG_ARM_SCPI_PROTOCOL is not set # CONFIG_ARM_SDE_INTERFACE is not set @@ -624,7 +607,9 @@ CONFIG_BASE_SMALL=0 # CONFIG_BCM54140_PHY is not set # CONFIG_BCM63XX is not set # CONFIG_BCM63XX_PHY is not set +# CONFIG_BCM7038_L1_IRQ is not set # CONFIG_BCM7038_WDT is not set +# CONFIG_BCM7120_L2_IRQ is not set # CONFIG_BCM7XXX_PHY is not set # CONFIG_BCM84881_PHY is not set # CONFIG_BCM87XX_PHY is not set @@ -669,7 +654,6 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_ATIIXP is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_BSGLIB is not set -# CONFIG_BLK_DEV_BSG_COMMON is not set # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD64X is not set # CONFIG_BLK_DEV_COW_COMMON is not set @@ -744,7 +728,6 @@ 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 @@ -770,6 +753,7 @@ CONFIG_BLOCK=y # CONFIG_BONDING is not set # CONFIG_BOOKE_WDT is not set CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set # CONFIG_BOOTTIME_TRACING is not set @@ -794,6 +778,7 @@ CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_BRCMFMAC is not set # CONFIG_BRCMSMAC is not set # CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_BRCMSTB_L2_IRQ is not set CONFIG_BRIDGE=y # CONFIG_BRIDGE_CFM is not set # CONFIG_BRIDGE_EBT_802_3 is not set @@ -966,7 +951,7 @@ CONFIG_CFG80211_HEADERS=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_QCOM_SMBB is not set # CONFIG_CHARGER_RT9455 is not set # CONFIG_CHARGER_SBS is not set # CONFIG_CHARGER_SMB347 is not set @@ -1017,7 +1002,6 @@ CONFIG_CLS_U32_MARK=y # CONFIG_CM3605 is not set # CONFIG_CM36651 is not set # CONFIG_CMA is not set -# CONFIG_CMA_SYSFS is not set CONFIG_CMDLINE="" # CONFIG_CMDLINE_BOOL is not set # CONFIG_CMDLINE_EXTEND is not set @@ -1035,7 +1019,6 @@ CONFIG_CMDLINE="" # CONFIG_COMMON_CLK_CS2000_CP is not set # CONFIG_COMMON_CLK_FIXED_MMIO is not set # CONFIG_COMMON_CLK_IPROC is not set -# CONFIG_COMMON_CLK_LAN966X is not set # CONFIG_COMMON_CLK_MAX9485 is not set # CONFIG_COMMON_CLK_MT6765 is not set # CONFIG_COMMON_CLK_MT8167 is not set @@ -1051,8 +1034,6 @@ CONFIG_CMDLINE="" # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_QCOM is not set -# CONFIG_COMMON_CLK_RK808 is not set -# CONFIG_COMMON_CLK_ROCKCHIP is not set # CONFIG_COMMON_CLK_RS9_PCIE is not set # CONFIG_COMMON_CLK_SI514 is not set # CONFIG_COMMON_CLK_SI5341 is not set @@ -1066,19 +1047,14 @@ CONFIG_CMDLINE="" 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 -# CONFIG_CONFIG_KVM_AMD_SEV is not set # CONFIG_CONNECTOR is not set 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 @@ -1108,14 +1084,13 @@ CONFIG_CONSTRUCTORS=y # CONFIG_CPU_IDLE_GOV_TEO is not set # CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set # CONFIG_CPU_ISOLATION is not set -CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_CPU_NO_EFFICIENT_FFS is not set CONFIG_CPU_SW_DOMAIN_PAN=y # CONFIG_CPU_THERMAL is not set # CONFIG_CRAMFS is not set CONFIG_CRAMFS_BLOCKDEV=y # CONFIG_CRAMFS_MTD is not set -CONFIG_CRASHLOG=y # CONFIG_CRASH_DUMP is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y @@ -1166,7 +1141,6 @@ CONFIG_CRYPTO_ALGAPI2=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S is not set # CONFIG_CRYPTO_ARIA is not set # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_BLAKE2B is not set @@ -1276,8 +1250,6 @@ CONFIG_CRYPTO_LIB_ARC4=y # CONFIG_CRYPTO_LIB_CURVE25519 is not set # CONFIG_CRYPTO_LIB_POLY1305 is not set CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 -# 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 @@ -1308,27 +1280,20 @@ CONFIG_CRYPTO_PCRYPT=y # CONFIG_CRYPTO_POLY1305_NEON is not set # CONFIG_CRYPTO_POLY1305_X86_64 is not set # CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set -# CONFIG_CRYPTO_RMD128 is not set # CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set # CONFIG_CRYPTO_RNG is not set # CONFIG_CRYPTO_RSA is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SALSA20_586 is not set # CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SEQIV is not set # 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 is not set # CONFIG_CRYPTO_SHA256_ARM is not set # CONFIG_CRYPTO_SHA256_ARM64 is not set -# CONFIG_CRYPTO_SHA256_SSSE3 is not set # CONFIG_CRYPTO_SHA2_ARM64_CE is not set # CONFIG_CRYPTO_SHA2_ARM_CE is not set # CONFIG_CRYPTO_SHA3 is not set @@ -1344,6 +1309,7 @@ CONFIG_CRYPTO_SKCIPHER2=y # CONFIG_CRYPTO_SM3 is not set # CONFIG_CRYPTO_SM3_ARM64_CE is not set # CONFIG_CRYPTO_SM3_GENERIC is not set +# CONFIG_CRYPTO_SM3_NEON is not set # CONFIG_CRYPTO_SM4 is not set # CONFIG_CRYPTO_SM4_ARM64_CE is not set # CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set @@ -1354,7 +1320,6 @@ CONFIG_CRYPTO_SKCIPHER2=y # CONFIG_CRYPTO_STREEBOG is not set # CONFIG_CRYPTO_TEA is not set # CONFIG_CRYPTO_TEST is not set -# CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_TWOFISH_586 is not set # CONFIG_CRYPTO_TWOFISH_COMMON is not set @@ -1376,7 +1341,6 @@ CONFIG_CRYPTO_SKCIPHER2=y # CONFIG_CS89x0 is not set # CONFIG_CS89x0_PLATFORM is not set # CONFIG_CSD_LOCK_WAIT_DEBUG is not set -# CONFIG_CURRENT_POINTER_IN_TPIDRURO is not set # CONFIG_CUSE is not set # CONFIG_CW1200 is not set # CONFIG_CXD2880_SPI_DRV is not set @@ -1472,7 +1436,10 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_VIRTUAL is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGFLAGS is not set # CONFIG_DEBUG_VM_PGTABLE is not set +# CONFIG_DEBUG_VM_RB is not set +# CONFIG_DEBUG_VM_VMACACHE is not set # CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set # CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set # CONFIG_DEBUG_WX is not set @@ -1487,7 +1454,6 @@ CONFIG_DEFAULT_FQ_CODEL=y 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 @@ -1643,11 +1609,6 @@ CONFIG_DQL=y # CONFIG_DRM_I2C_NXP_TDA998X is not set # CONFIG_DRM_I2C_SIL164 is not set # CONFIG_DRM_I915 is not set -CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 -# CONFIG_DRM_IMX8QM_LDB is not set -# CONFIG_DRM_IMX8QXP_LDB is not set -# 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 @@ -1747,6 +1708,7 @@ CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 # 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_WAVESHARE_TOUCHSCREEN 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 @@ -1758,9 +1720,9 @@ 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_ROCKCHIP is not set # CONFIG_DRM_SII902X is not set # CONFIG_DRM_SII9234 is not set # CONFIG_DRM_SIL_SII8620 is not set @@ -1786,7 +1748,6 @@ 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 @@ -1927,6 +1888,7 @@ CONFIG_DVB_MAX_ADAPTERS=16 # CONFIG_DVB_TUNER_DIB0090 is not set # CONFIG_DVB_TUNER_ITD1000 is not set # CONFIG_DVB_ULE_DEBUG is not set +# CONFIG_DVB_USB is not set # CONFIG_DVB_USB_V2 is not set # CONFIG_DVB_VES1820 is not set # CONFIG_DVB_VES1X93 is not set @@ -1952,7 +1914,7 @@ CONFIG_DVB_MAX_ADAPTERS=16 # CONFIG_DW_WATCHDOG is not set # CONFIG_DW_XDATA_PCIE is not set # CONFIG_DYNAMIC_DEBUG is not set -CONFIG_DYNAMIC_DEBUG_CORE=y +# CONFIG_DYNAMIC_DEBUG_CORE is not set # CONFIG_E100 is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set @@ -1982,7 +1944,6 @@ CONFIG_ELFCORE=y # CONFIG_EMAC_ROCKCHIP is not set CONFIG_EMBEDDED=y # CONFIG_EM_TIMER_STI is not set -# CONFIG_ENABLE_MUST_CHECK is not set CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENA_ETHERNET is not set # CONFIG_ENC28J60 is not set @@ -2003,7 +1964,6 @@ CONFIG_ETHERNET=y CONFIG_ETHTOOL_NETLINK=y CONFIG_EVENTFD=y # CONFIG_EVM is not set -# CONFIG_EXCLUSIVE_SYSTEM_RAM is not set # CONFIG_EXFAT_FS is not set CONFIG_EXPERT=y CONFIG_EXPORTFS=y @@ -2201,7 +2161,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_FONT_6x8 is not set # 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 @@ -2234,6 +2193,7 @@ CONFIG_FSNOTIFY=y # CONFIG_FTMAC100 is not set # CONFIG_FTRACE is not set # CONFIG_FTRACE_RECORD_RECURSION is not set +# CONFIG_FTRACE_SORT_STARTUP_TEST is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_FTR_FIXUP_SELFTEST is not set # CONFIG_FTWDT010_WATCHDOG is not set @@ -2241,6 +2201,7 @@ CONFIG_FSNOTIFY=y # CONFIG_FUJITSU_ES is not set # CONFIG_FUJITSU_LAPTOP is not set # CONFIG_FUJITSU_TABLET is not set +# CONFIG_FUNCTION_ERROR_INJECTION is not set # CONFIG_FUNCTION_TRACER is not set # CONFIG_FUN_ETH is not set # CONFIG_FUSE_FS is not set @@ -2250,11 +2211,9 @@ CONFIG_FSNOTIFY=y # CONFIG_FUSION_SPI is not set CONFIG_FUTEX=y CONFIG_FUTEX_PI=y -# CONFIG_FWNODE_MDIO is not set # 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 @@ -2267,9 +2226,7 @@ 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 @@ -2278,18 +2235,12 @@ CONFIG_GACT_PROB=y # CONFIG_GENERIC_ADC_THERMAL is not set 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 -# CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED is not set CONFIG_GENERIC_NET_UTILS=y # CONFIG_GENERIC_PHY is not set -# CONFIG_GENERIC_PINCONF is not set -# CONFIG_GENERIC_PINCTRL_GROUPS is not set -# CONFIG_GENERIC_PINMUX_FUNCTIONS is not set CONFIG_GENERIC_PTDUMP=y CONFIG_GENERIC_VDSO_TIME_NS=y # CONFIG_GENEVE is not set @@ -2349,7 +2300,6 @@ CONFIG_GPIOLIB_FASTPATH_LIMIT=512 # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_MB86S7X is not set # CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_MCP23S08 is not set # CONFIG_GPIO_ML_IOH is not set # CONFIG_GPIO_MOCKUP is not set # CONFIG_GPIO_MPC8XXX is not set @@ -2365,7 +2315,6 @@ CONFIG_GPIOLIB_FASTPATH_LIMIT=512 # CONFIG_GPIO_PWM is not set # CONFIG_GPIO_RCAR is not set # CONFIG_GPIO_RDC321X is not set -# CONFIG_GPIO_ROCKCHIP is not set # CONFIG_GPIO_SAMA5D2_PIOBU is not set # CONFIG_GPIO_SCH is not set # CONFIG_GPIO_SCH311X is not set @@ -2534,7 +2483,6 @@ CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HID_WACOM is not set # CONFIG_HID_WALTOP is not set # CONFIG_HID_WIIMOTE is not set -# CONFIG_HID_XIAOM is not set # CONFIG_HID_XIAOMI is not set # CONFIG_HID_XINMO is not set # CONFIG_HID_ZEROPLUS is not set @@ -2550,6 +2498,8 @@ CONFIG_HIGH_RES_TIMERS=y # CONFIG_HISI_FEMAC is not set # CONFIG_HISI_HIKEY_USB is not set # CONFIG_HISI_PCIE_PMU is not set +# CONFIG_HISI_PTT is not set +# CONFIG_HIST_TRIGGERS_DEBUG is not set # CONFIG_HIX5HD2_GMAC is not set # CONFIG_HMC425 is not set # CONFIG_HMC6352 is not set @@ -2564,7 +2514,6 @@ CONFIG_HIGH_RES_TIMERS=y # CONFIG_HOSTAP_PLX is not set # CONFIG_HOTPLUG_CPU is not set # CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_SHPC is not set # CONFIG_HP03 is not set # CONFIG_HP100 is not set # CONFIG_HP206C is not set @@ -2598,6 +2547,7 @@ CONFIG_HW_PERF_EVENTS=y # CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set # CONFIG_HW_RANDOM_ATMEL is not set # CONFIG_HW_RANDOM_BA431 is not set +# CONFIG_HW_RANDOM_BCM2835 is not set # CONFIG_HW_RANDOM_CAVIUM is not set # CONFIG_HW_RANDOM_CCTRNG is not set # CONFIG_HW_RANDOM_CN10K is not set @@ -2644,6 +2594,7 @@ CONFIG_HZ_100=y # CONFIG_I2C_AU1550 is not set # CONFIG_I2C_BCM2835 is not set # CONFIG_I2C_BCM_IPROC is not set +# CONFIG_I2C_BRCMSTB is not set # CONFIG_I2C_CADENCE is not set # CONFIG_I2C_CBUS_GPIO is not set # CONFIG_I2C_CHARDEV is not set @@ -2667,7 +2618,6 @@ CONFIG_HZ_100=y # CONFIG_I2C_HID_OF is not set # CONFIG_I2C_HID_OF_ELAN is not set # CONFIG_I2C_HID_OF_GOODIX is not set -# CONFIG_I2C_HISI is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_IBM_IIC is not set # CONFIG_I2C_IMG is not set @@ -2758,7 +2708,6 @@ CONFIG_HZ_100=y # CONFIG_IFB is not set # CONFIG_IGB is not set # CONFIG_IGBVF is not set -# CONFIG_IGB_HWMON is not set # CONFIG_IGC is not set # CONFIG_IIO is not set # CONFIG_IIO_BUFFER is not set @@ -2796,7 +2745,6 @@ 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 @@ -2806,10 +2754,6 @@ CONFIG_INET=y # CONFIG_INET6_ESPINTCP is not set # CONFIG_INET6_IPCOMP is not set # CONFIG_INET6_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_BEET is not set -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET6_XFRM_MODE_TUNNEL is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET_AH is not set # CONFIG_INET_DIAG is not set @@ -2817,13 +2761,10 @@ 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_TABLE_PERTURB_ORDER=16 # CONFIG_INET_TCP_DIAG is not set # CONFIG_INET_TUNNEL is not set # CONFIG_INET_UDP_DIAG is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INFINIBAND is not set # CONFIG_INFTL is not set @@ -2895,6 +2836,8 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_PALMAS_PWRBUTTON is not set # CONFIG_INPUT_PCF8574 is not set # CONFIG_INPUT_PCSPKR is not set +# CONFIG_INPUT_PM8941_PWRKEY is not set +# CONFIG_INPUT_PM8XXX_VIBRATOR is not set # CONFIG_INPUT_POLLDEV is not set # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_PWM_BEEPER is not set @@ -2938,7 +2881,6 @@ CONFIG_INPUT_MISC=y # CONFIG_INTEL_SOC_PMIC is not set # CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set # CONFIG_INTEL_SOC_PMIC_CHTWC is not set -# CONFIG_INTEL_TCC_COOLING is not set # CONFIG_INTEL_TH is not set # CONFIG_INTEL_VBTN is not set # CONFIG_INTEL_XWAY_PHY is not set @@ -2949,9 +2891,6 @@ CONFIG_INPUT_MISC=y # CONFIG_INV_MPU6050_I2C is not set # CONFIG_INV_MPU6050_IIO is not set # 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 @@ -3077,8 +3016,11 @@ CONFIG_IP_VS_MH_TAB_INDEX=10 # CONFIG_IR_RC5_DECODER is not set # CONFIG_IR_RC6_DECODER is not set # CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_SERIAL is not set +# CONFIG_IR_SIR is not set # CONFIG_IR_SONY_DECODER is not set # CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_TOY is not set # CONFIG_IR_TTUSBIR is not set # CONFIG_ISA_BUS is not set # CONFIG_ISA_BUS_API is not set @@ -3147,9 +3089,11 @@ CONFIG_KALLSYMS_BASE_RELATIVE=y # CONFIG_KALLSYMS_UNCOMPRESSED is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_KASAN is not set +# CONFIG_KASAN_MODULE_TEST is not set CONFIG_KASAN_STACK=y # CONFIG_KCMP is not set # CONFIG_KCOV is not set +CONFIG_KCOV_IRQ_AREA_SIZE=0x40000 # CONFIG_KCSAN is not set # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_CAT is not set @@ -3207,8 +3151,6 @@ CONFIG_KERNFS=y # CONFIG_KEY_DH_OPERATIONS is not set # CONFIG_KFENCE is not set # CONFIG_KGDB is not set -# CONFIG_KMAP_LOCAL is not set -# CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY is not set # CONFIG_KMEMCHECK is not set # CONFIG_KMX61 is not set # CONFIG_KPC2000 is not set @@ -3262,6 +3204,7 @@ CONFIG_LBDAF=y CONFIG_LDISC_AUTOLOAD=y # CONFIG_LDM_PARTITION is not set CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y +# CONFIG_LD_HEAD_STUB_CATCH is not set # CONFIG_LEDS_AN30259A is not set # CONFIG_LEDS_APU is not set # CONFIG_LEDS_AW2013 is not set @@ -3352,9 +3295,11 @@ CONFIG_LIB_MEMNEQ=y CONFIG_LINEAR_RANGES=y # CONFIG_LIQUIDIO is not set # CONFIG_LIQUIDIO_VF is not set +# CONFIG_LIRC is not set # CONFIG_LIS3L02DQ is not set # CONFIG_LITEX_LITEETH is not set # CONFIG_LITEX_SOC_CONTROLLER is not set +# CONFIG_LIVEPATCH is not set # CONFIG_LKDTM is not set CONFIG_LLC=y # CONFIG_LLC2 is not set @@ -3364,6 +3309,11 @@ CONFIG_LLC=y CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_LOCKD is not set +CONFIG_LOCKDEP_BITS=15 +CONFIG_LOCKDEP_CHAINS_BITS=16 +CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12 +CONFIG_LOCKDEP_STACK_TRACE_BITS=19 +CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14 CONFIG_LOCKDEP_SUPPORT=y CONFIG_LOCKD_V4=y # CONFIG_LOCKUP_DETECTOR is not set @@ -3513,6 +3463,7 @@ CONFIG_MAY_USE_DEVLINK=y # CONFIG_MEDIA_CAMERA_SUPPORT is not set # CONFIG_MEDIA_CEC_SUPPORT is not set # CONFIG_MEDIA_CONTROLLER is not set +# CONFIG_MEDIA_CONTROLLER_DVB 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 @@ -3718,7 +3669,6 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MICROCHIP_PIT64B is not set # CONFIG_MICROCHIP_T1_PHY is not set # CONFIG_MICROSEMI_PHY is not set -# CONFIG_MICROSOFT_MANA is not set # CONFIG_MIGRATION is not set CONFIG_MII=y # CONFIG_MIKROTIK is not set @@ -3791,7 +3741,6 @@ CONFIG_MMC_BLOCK_MINORS=8 # CONFIG_MMC_CQHCI is not set # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_DW is not set -# CONFIG_MMC_DW_ROCKCHIP is not set # CONFIG_MMC_HSQ is not set # CONFIG_MMC_JZ4740 is not set # CONFIG_MMC_MTK is not set @@ -3801,6 +3750,7 @@ CONFIG_MMC_BLOCK_MINORS=8 # CONFIG_MMC_SDHCI_ACPI is not set # CONFIG_MMC_SDHCI_AM654 is not set # CONFIG_MMC_SDHCI_BCM_KONA is not set +# CONFIG_MMC_SDHCI_BRCMSTB is not set # CONFIG_MMC_SDHCI_CADENCE is not set # CONFIG_MMC_SDHCI_F_SDH30 is not set # CONFIG_MMC_SDHCI_IPROC is not set @@ -3938,6 +3888,10 @@ CONFIG_MTD_MAP_BANK_WIDTH_4=y # CONFIG_MTD_NAND_BCH is not set # CONFIG_MTD_NAND_BF5XX is not set # CONFIG_MTD_NAND_BRCMNAND is not set +# CONFIG_MTD_NAND_BRCMNAND_BCM63XX is not set +# CONFIG_MTD_NAND_BRCMNAND_BCMBCA is not set +# CONFIG_MTD_NAND_BRCMNAND_BRCMSTB is not set +# CONFIG_MTD_NAND_BRCMNAND_IPROC is not set # CONFIG_MTD_NAND_CADENCE is not set # CONFIG_MTD_NAND_CAFE is not set # CONFIG_MTD_NAND_CM_X270 is not set @@ -4074,7 +4028,6 @@ CONFIG_MULTIUSER=y # CONFIG_MVMDIO is not set # CONFIG_MVNETA_BM is not set # CONFIG_MVSW61XX_PHY is not set -# CONFIG_MVSWITCH_PHY is not set # CONFIG_MV_XOR_V2 is not set # CONFIG_MWAVE is not set # CONFIG_MWL8K is not set @@ -4087,7 +4040,6 @@ CONFIG_MULTIUSER=y # CONFIG_NAU7802 is not set # CONFIG_NBPFAXI_DMA is not set # CONFIG_NCP_FS is not set -# CONFIG_ND_BLK is not set # CONFIG_NE2000 is not set # CONFIG_NE2K_PCI is not set # CONFIG_NEC_MARKEINS is not set @@ -4181,7 +4133,6 @@ CONFIG_NETDEVICES=y # CONFIG_NETFILTER_XT_TARGET_TPROXY is not set # CONFIG_NETFILTER_XT_TARGET_TRACE is not set # CONFIG_NETFS_STATS is not set -# CONFIG_NETFS_SUPPORT is not set # CONFIG_NETLABEL is not set # CONFIG_NETLINK_DIAG is not set # CONFIG_NETLINK_MMAP is not set @@ -4224,7 +4175,6 @@ CONFIG_NET_CLS_IND=y # CONFIG_NET_CLS_ROUTE4 is not set # CONFIG_NET_CLS_RSVP is not set # CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_TCINDEX is not set # CONFIG_NET_CLS_U32 is not set CONFIG_NET_CORE=y # CONFIG_NET_DEVLINK is not set @@ -4251,6 +4201,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_QCA8K_LEDS_SUPPORT 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 @@ -4262,7 +4213,6 @@ CONFIG_NET_CORE=y # CONFIG_NET_DSA_TAG_BRCM_LEGACY is not set # CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set # CONFIG_NET_DSA_TAG_DSA is not set -# CONFIG_NET_DSA_TAG_DSA_COMMON is not set # CONFIG_NET_DSA_TAG_EDSA is not set # CONFIG_NET_DSA_TAG_GSWIP is not set # CONFIG_NET_DSA_TAG_HELLCREEK is not set @@ -4489,8 +4439,6 @@ CONFIG_NFS_V3=y # CONFIG_NF_CONNTRACK_EVENTS is not set # CONFIG_NF_CONNTRACK_FTP is not set # CONFIG_NF_CONNTRACK_H323 is not set -# CONFIG_NF_CONNTRACK_IPV4 is not set -# CONFIG_NF_CONNTRACK_IPV6 is not set # CONFIG_NF_CONNTRACK_IRC is not set # CONFIG_NF_CONNTRACK_LABELS is not set # CONFIG_NF_CONNTRACK_MARK is not set @@ -4527,10 +4475,7 @@ CONFIG_NF_CONNTRACK_PROCFS=y # CONFIG_NF_NAT_AMANDA is not set # CONFIG_NF_NAT_FTP is not set # CONFIG_NF_NAT_H323 is not set -# CONFIG_NF_NAT_IPV6 is not set # CONFIG_NF_NAT_IRC is not set -CONFIG_NF_NAT_MASQUERADE_IPV4=y -CONFIG_NF_NAT_MASQUERADE_IPV6=y # CONFIG_NF_NAT_NEEDED is not set # CONFIG_NF_NAT_PPTP is not set # CONFIG_NF_NAT_PROTO_GRE is not set @@ -4541,7 +4486,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=y +# CONFIG_NF_TABLES is not set CONFIG_NF_TABLES_ARP=y CONFIG_NF_TABLES_BRIDGE=y CONFIG_NF_TABLES_INET=y @@ -4624,8 +4569,6 @@ CONFIG_NMI_LOG_BUF_SHIFT=13 # CONFIG_NO_HZ is not set # CONFIG_NO_HZ_FULL is not set # CONFIG_NO_HZ_IDLE is not set -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 @@ -4643,7 +4586,8 @@ CONFIG_NR_LRU_GENS=7 # CONFIG_NVMEM is not set # CONFIG_NVMEM_BCM_OCOTP is not set # CONFIG_NVMEM_IMX_OCOTP is not set -# CONFIG_NVMEM_NINTENDO_OTP is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set # CONFIG_NVMEM_REBOOT_MODE is not set # CONFIG_NVMEM_RMEM is not set # CONFIG_NVMEM_SYSFS is not set @@ -4709,8 +4653,6 @@ 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 # CONFIG_PANASONIC_LAPTOP is not set @@ -4804,8 +4746,6 @@ CONFIG_PCIE_BUS_DEFAULT=y # CONFIG_PCIE_CADENCE_HOST is not set # CONFIG_PCIE_CADENCE_PLAT_HOST is not set # CONFIG_PCIE_DPC is not set -# CONFIG_PCIE_DW is not set -# CONFIG_PCIE_DW_HOST is not set # CONFIG_PCIE_DW_PLAT is not set # CONFIG_PCIE_DW_PLAT_HOST is not set # CONFIG_PCIE_ECRC is not set @@ -4815,7 +4755,6 @@ CONFIG_PCIE_BUS_DEFAULT=y # 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 # CONFIG_PCIE_XILINX is not set # CONFIG_PCIPCWATCHDOG is not set # CONFIG_PCI_ATMEL is not set @@ -4910,10 +4849,6 @@ CONFIG_PCI_SYSCALL=y # CONFIG_PHY_QCOM_DWC3 is not set # CONFIG_PHY_QCOM_USB_HS is not set # CONFIG_PHY_QCOM_USB_HSIC is not set -# CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY is not set -# CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set -# CONFIG_PHY_ROCKCHIP_INNO_USB2 is not set -# CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY is not set # CONFIG_PHY_SAMSUNG_USB2 is not set # CONFIG_PHY_TUSB1210 is not set # CONFIG_PHY_XGENE is not set @@ -4978,7 +4913,6 @@ CONFIG_PINMUX=y # 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 CONFIG_POSIX_TIMERS=y # CONFIG_POWERCAP is not set @@ -5009,6 +4943,7 @@ CONFIG_PPC_4K_PAGES=y # CONFIG_PPC_DISABLE_WERROR is not set # CONFIG_PPC_EMULATED_STATS is not set # CONFIG_PPC_EPAPR_HV_BYTECHAN is not set +# CONFIG_PPC_QUEUED_SPINLOCKS is not set # CONFIG_PPP is not set # CONFIG_PPPOATM is not set # CONFIG_PPPOE is not set @@ -5030,10 +4965,8 @@ CONFIG_PPP_MULTILINK=y # CONFIG_PREEMPT is not set # CONFIG_PREEMPTIRQ_DELAY_TEST is not set # CONFIG_PREEMPTIRQ_EVENTS is not set -# CONFIG_PREEMPT_BUILD is not set # CONFIG_PREEMPT_DYNAMIC is not set CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_NONE_BUILD is not set # CONFIG_PREEMPT_TRACER is not set # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PRESTERA is not set @@ -5089,7 +5022,6 @@ CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 # CONFIG_PTP_1588_CLOCK_IXP46X is not set # CONFIG_PTP_1588_CLOCK_KVM is not set # CONFIG_PTP_1588_CLOCK_OCP is not set -# CONFIG_PTP_1588_CLOCK_OPTIONAL is not set # CONFIG_PTP_1588_CLOCK_PCH is not set # CONFIG_PTP_1588_CLOCK_VMW is not set # CONFIG_PUBLIC_KEY_ALGO_RSA is not set @@ -5100,7 +5032,9 @@ CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 # CONFIG_PWM_DEBUG is not set # CONFIG_PWM_DWC is not set # CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_IMG is not set # CONFIG_PWM_JZ4740 is not set +# CONFIG_PWM_MEDIATEK is not set # CONFIG_PWM_PCA9685 is not set # CONFIG_PWM_RASPBERRYPI_POE is not set # CONFIG_PWM_XILINX is not set @@ -5121,7 +5055,6 @@ CONFIG_PWRSEQ_SIMPLE=y # 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 @@ -5171,14 +5104,13 @@ CONFIG_PWRSEQ_SIMPLE=y # CONFIG_RALINK is not set # CONFIG_RANDOM32_SELFTEST is not set # CONFIG_RANDOMIZE_BASE is not set -# CONFIG_RANDOMIZE_KSTACK_OFFSET is not set +CONFIG_RANDOMIZE_KSTACK_OFFSET=y # CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set -# CONFIG_RANDOM_TRUST_BOOTLOADER is not set -# CONFIG_RANDOM_TRUST_CPU is not set +CONFIG_RANDOM_TRUST_BOOTLOADER=y +CONFIG_RANDOM_TRUST_CPU=y # 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=60 @@ -5201,6 +5133,7 @@ CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 # CONFIG_RC_DECODERS is not set # CONFIG_RC_LOOPBACK is not set # CONFIG_RC_MAP is not set +# CONFIG_RC_XBOX_DVD is not set # CONFIG_RDS is not set # CONFIG_RD_BZIP2 is not set # CONFIG_RD_GZIP is not set @@ -5308,7 +5241,6 @@ CONFIG_REISERFS_FS_XATTR=y # CONFIG_RESET_INTEL_GW is not set # CONFIG_RESET_LANTIQ is not set # CONFIG_RESET_LPC18XX is not set -# CONFIG_RESET_MCHP_SPARX5 is not set # CONFIG_RESET_MESON is not set # CONFIG_RESET_PISTACHIO is not set # CONFIG_RESET_SIMPLE is not set @@ -5333,17 +5265,8 @@ CONFIG_RFKILL=y # 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 -# CONFIG_ROCKCHIP_IODOMAIN is not set -# CONFIG_ROCKCHIP_IOMMU is not set -# CONFIG_ROCKCHIP_MBOX is not set # CONFIG_ROCKCHIP_PHY is not set -# CONFIG_ROCKCHIP_PM_DOMAINS is not set -# CONFIG_ROCKCHIP_SARADC is not set -# CONFIG_ROCKCHIP_THERMAL is not set -# CONFIG_ROCKCHIP_VOP2 is not set # CONFIG_ROCKER is not set -# CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set # CONFIG_ROMFS_FS is not set # CONFIG_ROSE is not set # CONFIG_RPCSEC_GSS_KRB5 is not set @@ -5425,7 +5348,6 @@ CONFIG_RTC_DRV_CMOS=y # CONFIG_RTC_DRV_PT7C4338 is not set # CONFIG_RTC_DRV_R7301 is not set # CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RK808 is not set # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_RS5C372 is not set @@ -5477,6 +5399,7 @@ CONFIG_RTC_SYSTOHC_DEVICE="rtc0" CONFIG_RT_MUTEXES=y # CONFIG_RUNTIME_DEBUG is not set CONFIG_RUNTIME_TESTING_MENU=y +# CONFIG_RV is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_RXKAD=y # CONFIG_S2IO is not set @@ -5486,6 +5409,7 @@ CONFIG_RXKAD=y # CONFIG_SATA_AHCI is not set # CONFIG_SATA_AHCI_PLATFORM is not set # CONFIG_SATA_DWC is not set +# CONFIG_SATA_DWC_OLD_DMA is not set # CONFIG_SATA_FSL is not set # CONFIG_SATA_HIGHBANK is not set # CONFIG_SATA_HOST is not set @@ -5523,7 +5447,7 @@ CONFIG_SCHED_HRTICK=y # CONFIG_SCHED_MC is not set CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_SCHED_SMT is not set -# CONFIG_SCHED_STACK_END_CHECK is not set +CONFIG_SCHED_STACK_END_CHECK=y # CONFIG_SCHED_TRACER is not set # CONFIG_SCR24X is not set # CONFIG_SCSI is not set @@ -5545,7 +5469,6 @@ CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_SCSI_BNX2_ISCSI is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CHELSIO_FCOE is not set -# CONFIG_SCSI_COMMON is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_CXGB4_ISCSI is not set @@ -5613,7 +5536,6 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_UFSHCD is not set -# CONFIG_SCSI_UFS_HWMON is not set # CONFIG_SCSI_ULTRASTOR is not set # CONFIG_SCSI_VIRTIO is not set # CONFIG_SCSI_WD719X is not set @@ -5990,7 +5912,9 @@ CONFIG_SERIAL_EARLYCON=y # CONFIG_SGI_PARTITION is not set # CONFIG_SG_POOL is not set # CONFIG_SG_SPLIT is not set +# CONFIG_SHADOW_CALL_STACK 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 @@ -6021,8 +5945,8 @@ CONFIG_SIGNALFD=y # CONFIG_SKY2_DEBUG is not set # CONFIG_SLAB is not set CONFIG_SLABINFO=y -# CONFIG_SLAB_FREELIST_HARDENED is not set -# CONFIG_SLAB_FREELIST_RANDOM is not set +CONFIG_SLAB_FREELIST_HARDENED=y +CONFIG_SLAB_FREELIST_RANDOM=y CONFIG_SLAB_MERGE_DEFAULT=y # CONFIG_SLHC is not set # CONFIG_SLICOSS is not set @@ -6095,7 +6019,6 @@ CONFIG_SLUB_CPU_PARTIAL=y # 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 @@ -6393,7 +6316,7 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_QCOM is not set # CONFIG_SND_SOC_RK3328 is not set # CONFIG_SND_SOC_RK817 is not set -# CONFIG_SND_SOC_ROCKCHIP_SPDIF is not set +# CONFIG_SND_SOC_ROCKCHIP is not set # CONFIG_SND_SOC_RT5616 is not set # CONFIG_SND_SOC_RT5631 is not set # CONFIG_SND_SOC_RT5640 is not set @@ -6512,7 +6435,6 @@ CONFIG_SND_X86=y # CONFIG_SNI_RM is not set # CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set # CONFIG_SOCK_CGROUP_DATA is not set -# CONFIG_SOCK_RX_QUEUE_MAPPING is not set # CONFIG_SOC_AM33XX is not set # CONFIG_SOC_AM43XX is not set # CONFIG_SOC_BRCMSTB is not set @@ -6521,7 +6443,6 @@ 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 @@ -6542,7 +6463,6 @@ CONFIG_SND_X86=y # CONFIG_SPI is not set # CONFIG_SPINLOCK_TEST is not set # CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_ALTERA_CORE is not set # CONFIG_SPI_AMD is not set # CONFIG_SPI_AU1550 is not set # CONFIG_SPI_AX88796C is not set @@ -6584,7 +6504,6 @@ CONFIG_SND_X86=y # CONFIG_SPI_PXA2XX_PCI is not set # CONFIG_SPI_QCOM_QSPI is not set # CONFIG_SPI_ROCKCHIP is not set -CONFIG_SPI_ROCKCHIP_SFC=y # CONFIG_SPI_S3C64XX is not set # CONFIG_SPI_SC18IS602 is not set # CONFIG_SPI_SIFIVE is not set @@ -6702,6 +6621,7 @@ CONFIG_SYMBOLIC_ERRNAME=y # CONFIG_SYNC_FILE is not set # CONFIG_SYNOPSYS_DWC_ETH_QOS is not set # CONFIG_SYNTH_EVENTS is not set +# CONFIG_SYNTH_EVENT_GEN_TEST is not set CONFIG_SYN_COOKIES=y # CONFIG_SYSCON_REBOOT_MODE is not set CONFIG_SYSCTL=y @@ -6724,7 +6644,6 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TARGET_CORE is not set # CONFIG_TASKSTATS is not set # CONFIG_TASKS_RCU is not set -CONFIG_TASKS_TRACE_RCU_READ_MB=y # CONFIG_TASK_XACCT is not set # CONFIG_TC35815 is not set # CONFIG_TCG_ATMEL is not set @@ -6778,6 +6697,7 @@ CONFIG_TCP_CONG_CUBIC=y # CONFIG_TEST_BLACKHOLE_DEV is not set # CONFIG_TEST_BPF is not set # CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set +# CONFIG_TEST_DEBUG_VIRTUAL is not set # CONFIG_TEST_DIV64 is not set # CONFIG_TEST_DYNAMIC_DEBUG is not set # CONFIG_TEST_FIRMWARE is not set @@ -6791,6 +6711,7 @@ CONFIG_TCP_CONG_CUBIC=y # CONFIG_TEST_LIST_SORT is not set # CONFIG_TEST_LKM is not set # CONFIG_TEST_LOCKUP is not set +# CONFIG_TEST_MAPLE_TREE is not set # CONFIG_TEST_MEMCAT_P is not set # CONFIG_TEST_MEMINIT is not set # CONFIG_TEST_MIN_HEAP is not set @@ -6833,7 +6754,6 @@ CONFIG_TEXTSEARCH=y # CONFIG_THERMAL_WRITABLE_TRIPS is not set # CONFIG_THINKPAD_ACPI is not set CONFIG_THIN_ARCHIVES=y -# CONFIG_THREAD_INFO_IN_TASK is not set # CONFIG_THRUSTMASTER_FF is not set # CONFIG_THUMB2_KERNEL is not set # CONFIG_THUNDERBOLT is not set @@ -6843,7 +6763,6 @@ CONFIG_THIN_ARCHIVES=y # CONFIG_THUNDER_NIC_VF is not set # CONFIG_TICK_CPU_ACCOUNTING is not set CONFIG_TICK_ONESHOT=y -CONFIG_TIERS_PER_GEN=4 # CONFIG_TIFM_CORE is not set # CONFIG_TIGON3 is not set # CONFIG_TIMB_DMA is not set @@ -6893,6 +6812,8 @@ CONFIG_TINY_RCU=y # CONFIG_TI_TSC2046 is not set # CONFIG_TLAN is not set # CONFIG_TLS is not set +# CONFIG_TLS_DEVICE is not set +# CONFIG_TLS_TOE is not set # CONFIG_TMD_HERMES is not set # CONFIG_TMP006 is not set # CONFIG_TMP007 is not set @@ -7043,14 +6964,13 @@ 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_MMIO_ACCESS is not set # CONFIG_TRACE_SINK is not set # CONFIG_TRACING_EVENTS_GPIO is not set CONFIG_TRACING_SUPPORT=y CONFIG_TRAD_SIGNALS=y # CONFIG_TRANSPARENT_HUGEPAGE is not set -# CONFIG_TRANS_TABLE is not set # CONFIG_TREE_RCU is not set # CONFIG_TREE_RCU_TRACE is not set # CONFIG_TRIM_UNUSED_KSYMS is not set @@ -7076,6 +6996,7 @@ CONFIG_TTY=y # CONFIG_TWL6040_CORE is not set # CONFIG_TXGBE is not set # CONFIG_TYPEC is not set +# CONFIG_TYPEC_DP_ALTMODE is not set # CONFIG_TYPEC_TCPM is not set # CONFIG_TYPEC_UCSI is not set # CONFIG_TYPHOON is not set @@ -7091,7 +7012,12 @@ CONFIG_UBIFS_FS_ZLIB=y CONFIG_UBIFS_FS_ZSTD=y # CONFIG_UBSAN is not set CONFIG_UBSAN_ALIGNMENT=y +CONFIG_UBSAN_BOOL=y +# CONFIG_UBSAN_DIV_ZERO is not set +CONFIG_UBSAN_ENUM=y # CONFIG_UBSAN_MISC is not set +CONFIG_UBSAN_SHIFT=y +# CONFIG_UBSAN_UNREACHABLE is not set # CONFIG_UCB1400_CORE is not set # CONFIG_UCSI is not set # CONFIG_UDF_FS is not set @@ -7112,7 +7038,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_UNIX_DIAG is not set CONFIG_UNIX_SCM=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set +# CONFIG_UNUSED_BOARD_FILES is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_UNWINDER_FRAME_POINTER is not set # CONFIG_UPROBES is not set @@ -7489,6 +7415,7 @@ CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y # CONFIG_USB_WHCI_HCD is not set # CONFIG_USB_WUSB is not set # CONFIG_USB_WUSB_CBAF is not set +# CONFIG_USB_XEN_HCD is not set # CONFIG_USB_XHCI_DBGCAP is not set # CONFIG_USB_XHCI_HCD is not set # CONFIG_USB_XHCI_MVEBU is not set @@ -7554,8 +7481,6 @@ CONFIG_VHOST_MENU=y # 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 @@ -7569,6 +7494,7 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_CADENCE_CSI2TX is not set # CONFIG_VIDEO_CAFE_CCIC is not set # CONFIG_VIDEO_CCS is not set +# CONFIG_VIDEO_CODA is not set # CONFIG_VIDEO_CS3308 is not set # CONFIG_VIDEO_CS5345 is not set # CONFIG_VIDEO_CS53L32A is not set @@ -7587,7 +7513,6 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set # CONFIG_VIDEO_GO7007 is not set # CONFIG_VIDEO_GS1662 is not set -# CONFIG_VIDEO_HANTRO_ROCKCHIP is not set # CONFIG_VIDEO_HDPVR is not set # CONFIG_VIDEO_HEXIUM_GEMINI is not set # CONFIG_VIDEO_HEXIUM_ORION is not set @@ -7601,14 +7526,14 @@ CONFIG_VHOST_MENU=y # 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_IMX8_JPEG is not set +# CONFIG_VIDEO_IMX_PXP is not set # CONFIG_VIDEO_IRS1125 is not set # CONFIG_VIDEO_IR_I2C is not set # CONFIG_VIDEO_ISL7998X is not set @@ -7619,6 +7544,7 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_M52790 is not set # CONFIG_VIDEO_M5MOLS is not set # CONFIG_VIDEO_MAX9286 is not set +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set # CONFIG_VIDEO_ML86V7667 is not set # CONFIG_VIDEO_MSP3400 is not set # CONFIG_VIDEO_MT9M001 is not set @@ -7889,7 +7815,6 @@ CONFIG_XFRM=y # CONFIG_XIL_AXIS_FIFO is not set # CONFIG_XIP_KERNEL is not set # CONFIG_XMON is not set -# CONFIG_XXHASH is not set CONFIG_XZ_DEC=y # CONFIG_XZ_DEC_ARM is not set # CONFIG_XZ_DEC_ARMTHUMB is not set @@ -7918,11 +7843,11 @@ CONFIG_XZ_DEC=y # CONFIG_ZLIB_DEFLATE is not set # CONFIG_ZLIB_INFLATE is not set CONFIG_ZONE_DMA=y -# CONFIG_ZONE_DMA32 is not set # CONFIG_ZOPT2201 is not set # CONFIG_ZPA2326 is not set # CONFIG_ZPOOL is not set # CONFIG_ZRAM is not set +# CONFIG_ZRAM_DEF_COMP_842 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 diff --git a/target/linux/generic/hack-6.1/251-kconfig.patch b/target/linux/generic/hack-6.1/251-kconfig.patch index 9511c4c2b..e1ecbca6f 100644 --- a/target/linux/generic/hack-6.1/251-kconfig.patch +++ b/target/linux/generic/hack-6.1/251-kconfig.patch @@ -197,3 +197,14 @@ Signed-off-by: John Crispin config SND_JACK bool +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -430,7 +430,7 @@ config NET_DEVLINK + default n + + config PAGE_POOL +- bool ++ bool "Page pool support" + + config PAGE_POOL_STATS + default n 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 index 295da11eb..c0fa2ddab 100644 --- 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 @@ -91,7 +91,7 @@ Signed-off-by: Daniel Golle #include "mtdcore.h" -@@ -1075,6 +1076,8 @@ int mtd_device_parse_register(struct mtd +@@ -1074,6 +1075,8 @@ int mtd_device_parse_register(struct mtd register_reboot_notifier(&mtd->reboot_notifier); } diff --git a/target/linux/generic/hack-6.1/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 deleted file mode 100644 index 26399f1c8..000000000 --- a/target/linux/generic/hack-6.1/420-mtd-set-rootfs-to-be-root-dev.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Gabor Juhos -Subject: kernel/3.1[02]: move MTD root device setup code to mtdcore - -The current code only allows to automatically set -root device on MTD partitions. Move the code to MTD -core to allow to use it with all MTD devices. - -Signed-off-by: Gabor Juhos ---- - drivers/mtd/mtdcore.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -765,6 +766,16 @@ int add_mtd_device(struct mtd_info *mtd) - of this try_ nonsense, and no bitching about it - either. :) */ - __module_get(THIS_MODULE); -+ -+ if (!strcmp(mtd->name, "rootfs") && -+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ ROOT_DEV == 0) { -+ unsigned int index = mtd->index; -+ pr_notice("mtd: device %d (%s) set to be root filesystem\n", -+ mtd->index, mtd->name); -+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, index); -+ } -+ - return 0; - - fail_nvmem_add: diff --git a/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch b/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch new file mode 100644 index 000000000..8e8e5cea8 --- /dev/null +++ b/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch @@ -0,0 +1,24 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 7 Nov 2022 23:48:24 +0100 +Subject: [PATCH] mtd: support OpenWrt's MTD_ROOTFS_ROOT_DEV +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows setting ROOT_DEV to MTD partition named "rootfs". + +Signed-off-by: Rafał Miłecki +--- + +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -750,7 +750,8 @@ int add_mtd_device(struct mtd_info *mtd) + + mutex_unlock(&mtd_table_mutex); + +- if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) { ++ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL) || ++ (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && !strcmp(mtd->name, "rootfs") && ROOT_DEV == 0)) { + if (IS_BUILTIN(CONFIG_MTD)) { + pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); diff --git a/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch index fde2bb7d3..444f8edfe 100644 --- a/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch +++ b/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch @@ -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,13 +24,14 @@ MODULE_ALIAS("ipt_connmark"); +@@ -24,13 +24,13 @@ MODULE_ALIAS("ipt_connmark"); MODULE_ALIAS("ip6t_connmark"); static unsigned int @@ -120,21 +120,22 @@ Signed-off-by: Kevin Darbyshire-Bryant u_int32_t new_targetmark; struct nf_conn *ct; u_int32_t newmark; - u_int32_t oldmark; +- u_int32_t oldmark; + u_int8_t dscp; ct = nf_ct_get(skb, &ctinfo); if (ct == NULL) -@@ -39,12 +40,24 @@ connmark_tg_shift(struct sk_buff *skb, c +@@ -38,13 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c + switch (info->mode) { case XT_CONNMARK_SET: - oldmark = READ_ONCE(ct->mark); +- oldmark = READ_ONCE(ct->mark); - newmark = (oldmark & ~info->ctmask) ^ info->ctmark; - if (info->shift_dir == D_SHIFT_RIGHT) - newmark >>= info->shift_bits; - else - newmark <<= info->shift_bits; -+ newmark = ct->mark; ++ newmark = READ_ONCE(ct->mark); + if (info->func & XT_CONNMARK_VALUE) { + newmark = (newmark & ~info->ctmask) ^ info->ctmark; + if (info->shift_dir == D_SHIFT_RIGHT) @@ -155,7 +156,7 @@ Signed-off-by: Kevin Darbyshire-Bryant if (READ_ONCE(ct->mark) != newmark) { WRITE_ONCE(ct->mark, newmark); nf_conntrack_event_cache(IPCT_MARK, ct); -@@ -83,20 +96,36 @@ static unsigned int +@@ -83,20 +94,36 @@ static unsigned int connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_connmark_tginfo1 *info = par->targinfo; @@ -194,7 +195,7 @@ Signed-off-by: Kevin Darbyshire-Bryant return connmark_tg_shift(skb, info); } -@@ -167,6 +196,16 @@ static struct xt_target connmark_tg_reg[ +@@ -167,6 +194,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.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch b/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch index 557144cbc..386291bfe 100644 --- a/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch +++ b/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch @@ -36,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,697 @@ +@@ -0,0 +1,698 @@ +/* + * Copyright (C) 2018-2021 Felix Fietkau + * @@ -690,6 +690,7 @@ Signed-off-by: Felix Fietkau +{ + INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work); + tbl->ft.type = &flowtable_inet; ++ tbl->ft.flags = NF_FLOWTABLE_COUNTER; + + return nf_flow_table_init(&tbl->ft); +} @@ -708,7 +709,7 @@ Signed-off-by: Felix Fietkau + if (ret) + goto cleanup; + -+ flowtable[1].ft.flags = NF_FLOWTABLE_HW_OFFLOAD; ++ flowtable[1].ft.flags |= NF_FLOWTABLE_HW_OFFLOAD; + + ret = xt_register_target(&offload_tg_reg); + if (ret) diff --git a/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch b/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch index 795cff377..fd7d5346a 100644 --- a/target/linux/generic/hack-6.1/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 -@@ -150,8 +150,8 @@ static inline bool dev_xmit_complete(int +@@ -149,8 +149,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.1/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch index 48be44002..9d77efaca 100644 --- a/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch +++ b/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig -@@ -61,6 +61,80 @@ config SFP +@@ -62,6 +62,80 @@ config SFP depends on HWMON || HWMON=n select MDIO_I2C diff --git a/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch b/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch new file mode 100644 index 000000000..8b7f2f095 --- /dev/null +++ b/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch @@ -0,0 +1,53 @@ +From 880d1311335120f64447ca9d11933872d734e19a Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 27 Mar 2023 18:41:54 +0100 +Subject: [PATCH] generic: pcs-mtk-lynxi: add hack to use 2500Base-X without AN + +Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually +disabling auto-negotiation, e.g. using ethtool. While a proper fix +using SFP quirks is being discussed upstream, bring a work-around to +restore user experience to what it was before the switch to the +dedicated SGMII PCS driver. + +Signed-off-by: Daniel Golle + +--- a/drivers/net/pcs/pcs-mtk-lynxi.c ++++ b/drivers/net/pcs/pcs-mtk-lynxi.c +@@ -92,14 +92,23 @@ static void mtk_pcs_lynxi_get_state(stru + struct phylink_link_state *state) + { + struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); +- unsigned int bm, adv; ++ unsigned int bm, bmsr, adv; + + /* Read the BMSR and LPA */ + regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); +- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); ++ bmsr = FIELD_GET(SGMII_BMSR, bm); ++ ++ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { ++ state->link = !!(bmsr & BMSR_LSTATUS); ++ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); ++ state->speed = SPEED_2500; ++ state->duplex = DUPLEX_FULL; + +- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), +- FIELD_GET(SGMII_LPA, adv)); ++ return; ++ } ++ ++ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); ++ phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv)); + } + + static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode, +@@ -134,7 +143,8 @@ static int mtk_pcs_lynxi_config(struct p + /* 1000base-X or 2500base-X autoneg */ + sgm_mode = SGMII_REMOTE_FAULT_DIS; + use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, +- advertising); ++ advertising) && ++ !(interface == PHY_INTERFACE_MODE_2500BASEX); + } else { + /* 1000base-X or 2500base-X without autoneg */ + sgm_mode = 0; diff --git a/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch b/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch new file mode 100644 index 000000000..d7165cb30 --- /dev/null +++ b/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch @@ -0,0 +1,101 @@ +From 94b90966095f3fa625897e8f53d215882f6e19b3 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Sat, 11 Mar 2023 17:00:01 +0100 +Subject: [PATCH] mxl-gpy: control LED reg from DT + +Add dynamic configuration for the LED control registers on MXL PHYs. + +This patch has been tested with MaxLinear GPY211C. It is unlikely to be +accepted upstream, as upstream plans on integrating their own framework +for handling these LEDs. + +For the time being, use this hack to configure PHY driven device-LEDs to +show the correct state. + +A possible alternative might be to expose the LEDs using the kernel LED +framework and bind it to the netdevice. This might also be upstreamable, +although it is a considerable extra amount of work. + +Signed-off-by: David Bauer +--- + drivers/net/phy/mxl-gpy.c | 37 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/mxl-gpy.c ++++ b/drivers/net/phy/mxl-gpy.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -33,6 +34,7 @@ + #define PHY_MIISTAT 0x18 /* MII state */ + #define PHY_IMASK 0x19 /* interrupt mask */ + #define PHY_ISTAT 0x1A /* interrupt status */ ++#define PHY_LED 0x1B /* LED control */ + #define PHY_FWV 0x1E /* firmware version */ + + #define PHY_MIISTAT_SPD_MASK GENMASK(2, 0) +@@ -56,10 +58,15 @@ + PHY_IMASK_ADSC | \ + PHY_IMASK_ANC) + ++#define PHY_LED_NUM_LEDS 4 ++ + #define PHY_FWV_REL_MASK BIT(15) + #define PHY_FWV_MAJOR_MASK GENMASK(11, 8) + #define PHY_FWV_MINOR_MASK GENMASK(7, 0) + ++/* LED */ ++#define VSPEC1_LED(x) (0x1 + x) ++ + /* SGMII */ + #define VSPEC1_SGMII_CTRL 0x08 + #define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */ +@@ -241,6 +248,31 @@ out: + return ret; + } + ++static int gpy_led_write(struct phy_device *phydev) ++{ ++ struct device_node *node = phydev->mdio.dev.of_node; ++ u32 led_regs[PHY_LED_NUM_LEDS]; ++ int i, ret; ++ ++ if (!IS_ENABLED(CONFIG_OF_MDIO)) ++ return 0; ++ ++ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS)) ++ return 0; ++ ++ /* Enable LED function handling on all ports*/ ++ phy_write(phydev, PHY_LED, 0xFF00); ++ ++ /* Write LED register values */ ++ for (i = 0; i < PHY_LED_NUM_LEDS; i++) { ++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(i), (u16)led_regs[i]); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int gpy_config_init(struct phy_device *phydev) + { + int ret; +@@ -252,7 +284,10 @@ static int gpy_config_init(struct phy_de + + /* Clear all pending interrupts */ + ret = phy_read(phydev, PHY_ISTAT); +- return ret < 0 ? ret : 0; ++ if (ret < 0) ++ return ret; ++ ++ return gpy_led_write(phydev); + } + + static bool gpy_has_broken_mdint(struct phy_device *phydev) diff --git a/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch b/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch new file mode 100644 index 000000000..3405d5c53 --- /dev/null +++ b/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch @@ -0,0 +1,72 @@ +From cc225d163b5a4f7a0d1968298bf7927306646a47 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Fri, 28 Apr 2023 01:53:01 +0200 +Subject: [PATCH] net: phy: mediatek-ge: add LED configuration interface + +This adds a small hack similar to the one used for ar8xxx switches to +read a reg:value map for configuring the LED configuration registers. + +This allows OpenWrt to write device-specific LED action as well as blink +configurations. It is unlikely to be accepted upstream, as upstream +plans on integrating their own framework for handling these LEDs. + +Signed-off-by: David Bauer +--- + drivers/net/phy/mediatek-ge.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +--- a/drivers/net/phy/mediatek-ge.c ++++ b/drivers/net/phy/mediatek-ge.c +@@ -1,4 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0+ ++#include + #include + #include + #include +@@ -53,6 +54,36 @@ static int mt7530_phy_config_init(struct + return 0; + } + ++static int mt7530_led_config_of(struct phy_device *phydev) ++{ ++ struct device_node *np = phydev->mdio.dev.of_node; ++ const __be32 *paddr; ++ int len; ++ int i; ++ ++ paddr = of_get_property(np, "mediatek,led-config", &len); ++ if (!paddr) ++ return 0; ++ ++ if (len < (2 * sizeof(*paddr))) ++ return -EINVAL; ++ ++ len /= sizeof(*paddr); ++ ++ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len); ++ for (i = 0; i < len - 1; i += 2) { ++ u32 reg; ++ u32 val; ++ ++ reg = be32_to_cpup(paddr + i); ++ val = be32_to_cpup(paddr + i + 1); ++ ++ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val); ++ } ++ ++ return 0; ++} ++ + static int mt7531_phy_config_init(struct phy_device *phydev) + { + mtk_gephy_config_init(phydev); +@@ -65,6 +96,9 @@ static int mt7531_phy_config_init(struct + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404); + phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404); + ++ /* LED Config*/ ++ mt7530_led_config_of(phydev); ++ + return 0; + } + diff --git a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch index 754b718c5..7257f7010 100644 --- a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch +++ b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch @@ -29,7 +29,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support #define QUECTEL_VENDOR_ID 0x2c7c /* These Quectel products use Quectel's vendor ID */ -@@ -1170,6 +1172,11 @@ static const struct usb_device_id option +@@ -1173,6 +1175,11 @@ static const struct usb_device_id option .driver_info = ZLP }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), .driver_info = RSVD(4) }, diff --git a/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch b/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch new file mode 100644 index 000000000..c581a512c --- /dev/null +++ b/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch @@ -0,0 +1,187 @@ +From e4d708702e6c98f2111e33201a264d6788564cb2 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +Date: Fri, 12 May 2023 11:08:43 +0200 +Subject: [PATCH] ssb_sprom: add generic kernel support for Broadcom Fallback SPROMs + +--- + drivers/bcma/Kconfig | 4 ++++ + drivers/bcma/Makefile | 1 + + drivers/bcma/bcma_private.h | 4 ++++ + drivers/bcma/main.c | 8 ++++++++ + drivers/bcma/sprom.c | 23 ++++++++++++++--------- + drivers/ssb/Kconfig | 5 +++++ + drivers/ssb/Makefile | 1 + + drivers/ssb/main.c | 8 ++++++++ + drivers/ssb/sprom.c | 12 +++++++++++- + drivers/ssb/ssb_private.h | 4 ++++ + 10 files changed, 60 insertions(+), 10 deletions(-) + +--- a/drivers/bcma/Kconfig ++++ b/drivers/bcma/Kconfig +@@ -18,6 +18,10 @@ config BCMA_BLOCKIO + bool + default y + ++config BCMA_FALLBACK_SPROM ++ bool ++ default y ++ + config BCMA_HOST_PCI_POSSIBLE + bool + depends on PCI = y +--- a/drivers/bcma/Makefile ++++ b/drivers/bcma/Makefile +@@ -11,6 +11,7 @@ bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) + bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o + bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o + bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o ++bcma-$(CONFIG_BCMA_FALLBACK_SPROM) += fallback-sprom.o + bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o + bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o + obj-$(CONFIG_BCMA) += bcma.o +--- a/drivers/bcma/bcma_private.h ++++ b/drivers/bcma/bcma_private.h +@@ -38,6 +38,10 @@ int bcma_bus_resume(struct bcma_bus *bus + void bcma_detect_chip(struct bcma_bus *bus); + int bcma_bus_scan(struct bcma_bus *bus); + ++/* fallback-sprom.c */ ++int __init bcma_fbs_register(void); ++int bcma_get_fallback_sprom(struct bcma_bus *dev, struct ssb_sprom *out); ++ + /* sprom.c */ + int bcma_sprom_get(struct bcma_bus *bus); + +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -668,6 +668,14 @@ static int __init bcma_modinit(void) + { + int err; + ++#ifdef CONFIG_BCMA_FALLBACK_SPROM ++ err = bcma_fbs_register(); ++ if (err) { ++ pr_err("Fallback SPROM initialization failed\n"); ++ err = 0; ++ } ++#endif /* CONFIG_BCMA_FALLBACK_SPROM */ ++ + err = bcma_init_bus_register(); + if (err) + return err; +--- a/drivers/bcma/sprom.c ++++ b/drivers/bcma/sprom.c +@@ -51,21 +51,26 @@ static int bcma_fill_sprom_with_fallback + { + int err; + +- if (!get_fallback_sprom) { ++ if (get_fallback_sprom) ++ err = get_fallback_sprom(bus, out); ++ ++#ifdef CONFIG_BCMA_FALLBACK_SPROM ++ if (!get_fallback_sprom || err) ++ err = bcma_get_fallback_sprom(bus, out); ++#else ++ if (!get_fallback_sprom) + err = -ENOENT; +- goto fail; +- } ++#endif /* CONFIG_BCMA_FALLBACK_SPROM */ + +- err = get_fallback_sprom(bus, out); +- if (err) +- goto fail; ++ if (err) { ++ bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); ++ return err; ++ } + + bcma_debug(bus, "Using SPROM revision %d provided by platform.\n", + bus->sprom.revision); ++ + return 0; +-fail: +- bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); +- return err; + } + + /************************************************** +--- a/drivers/ssb/Kconfig ++++ b/drivers/ssb/Kconfig +@@ -25,6 +25,11 @@ if SSB + config SSB_SPROM + bool + ++config SSB_FALLBACK_SPROM ++ bool ++ depends on SSB_PCIHOST ++ default y ++ + # Support for Block-I/O. SELECT this from the driver that needs it. + config SSB_BLOCKIO + bool +--- a/drivers/ssb/Makefile ++++ b/drivers/ssb/Makefile +@@ -2,6 +2,7 @@ + # core + ssb-y += main.o scan.o + ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o ++ssb-$(CONFIG_SSB_FALLBACK_SPROM) += fallback-sprom.o + ssb-$(CONFIG_SSB_SPROM) += sprom.o + + # host support +--- a/drivers/ssb/main.c ++++ b/drivers/ssb/main.c +@@ -1287,6 +1287,14 @@ static int __init ssb_modinit(void) + { + int err; + ++#ifdef CONFIG_SSB_FALLBACK_SPROM ++ err = ssb_fbs_register(); ++ if (err) { ++ pr_err("Fallback SPROM initialization failed\n"); ++ err = 0; ++ } ++#endif /* CONFIG_SSB_FALLBACK_SPROM */ ++ + /* See the comment at the ssb_is_early_boot definition */ + ssb_is_early_boot = 0; + err = bus_register(&ssb_bustype); +--- a/drivers/ssb/sprom.c ++++ b/drivers/ssb/sprom.c +@@ -180,10 +180,20 @@ int ssb_arch_register_fallback_sprom(int + + int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out) + { ++ int err; ++ ++ if (get_fallback_sprom) ++ err = get_fallback_sprom(bus, out); ++ ++#ifdef CONFIG_SSB_FALLBACK_SPROM ++ if (!get_fallback_sprom || err) ++ err = ssb_get_fallback_sprom(bus, out); ++#else + if (!get_fallback_sprom) + return -ENOENT; ++#endif /* CONFIG_SSB_FALLBACK_SPROM */ + +- return get_fallback_sprom(bus, out); ++ return err; + } + + /* https://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ +--- a/drivers/ssb/ssb_private.h ++++ b/drivers/ssb/ssb_private.h +@@ -143,6 +143,10 @@ extern int ssb_bus_scan(struct ssb_bus * + extern void ssb_iounmap(struct ssb_bus *ssb); + + ++/* fallback-sprom.c */ ++int __init ssb_fbs_register(void); ++int ssb_get_fallback_sprom(struct ssb_bus *dev, struct ssb_sprom *out); ++ + /* sprom.c */ + extern + ssize_t ssb_attr_sprom_show(struct ssb_bus *bus, char *buf, 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 index 29fd269fa..582a48cb1 100644 --- a/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch +++ b/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch @@ -142,17 +142,6 @@ Signed-off-by: Felix Fietkau 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 diff --git a/target/linux/generic/hack-6.1/970-export-efivarfs-function.patch b/target/linux/generic/hack-6.1/970-export-efivarfs-function.patch deleted file mode 100644 index 5ef545743..000000000 --- a/target/linux/generic/hack-6.1/970-export-efivarfs-function.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 767cc7f3b63233577767e60fe4bc911f6595c121 Mon Sep 17 00:00:00 2001 -From: W_Y_CPP <383152993@qq.com> -Date: Wed, 22 Feb 2023 22:58:07 +0900 -Subject: [PATCH] export efivarfs function - ---- - fs/efivarfs/internal.h | 39 --------------------------------------- - include/linux/efi.h | 39 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 39 insertions(+), 39 deletions(-) - fs/efivarfs/vars.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - ---- a/fs/efivarfs/internal.h -+++ b/fs/efivarfs/internal.h -@@ -9,45 +9,6 @@ - #include - #include - --struct efi_variable { -- efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)]; -- efi_guid_t VendorGuid; -- unsigned long DataSize; -- __u8 Data[1024]; -- efi_status_t Status; -- __u32 Attributes; --} __attribute__((packed)); -- --struct efivar_entry { -- struct efi_variable var; -- struct list_head list; -- struct kobject kobj; --}; -- --int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), -- void *data, bool duplicates, struct list_head *head); -- --int efivar_entry_add(struct efivar_entry *entry, struct list_head *head); --void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head); --void efivar_entry_remove(struct efivar_entry *entry); --int efivar_entry_delete(struct efivar_entry *entry); -- --int efivar_entry_size(struct efivar_entry *entry, unsigned long *size); --int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes, -- unsigned long *size, void *data); --int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, -- unsigned long *size, void *data); --int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, -- unsigned long *size, void *data, bool *set); -- --int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), -- struct list_head *head, void *data); -- --bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, -- unsigned long data_size); --bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, -- size_t len); -- - extern const struct file_operations efivarfs_file_operations; - extern const struct inode_operations efivarfs_dir_inode_operations; - extern bool efivarfs_valid_name(const char *str, int len); ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -1062,6 +1062,45 @@ struct efivars { - - #define EFI_VAR_NAME_LEN 1024 - -+struct efi_variable { -+ efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)]; -+ efi_guid_t VendorGuid; -+ unsigned long DataSize; -+ __u8 Data[1024]; -+ efi_status_t Status; -+ __u32 Attributes; -+} __attribute__((packed)); -+ -+struct efivar_entry { -+ struct efi_variable var; -+ struct list_head list; -+ struct kobject kobj; -+}; -+ -+int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), -+ void *data, bool duplicates, struct list_head *head); -+ -+int efivar_entry_add(struct efivar_entry *entry, struct list_head *head); -+void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head); -+void efivar_entry_remove(struct efivar_entry *entry); -+int efivar_entry_delete(struct efivar_entry *entry); -+ -+int efivar_entry_size(struct efivar_entry *entry, unsigned long *size); -+int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes, -+ unsigned long *size, void *data); -+int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, -+ unsigned long *size, void *data); -+int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, -+ unsigned long *size, void *data, bool *set); -+ -+int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), -+ struct list_head *head, void *data); -+ -+bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, -+ unsigned long data_size); -+bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, -+ size_t len); -+ - int efivars_register(struct efivars *efivars, - const struct efivar_operations *ops, - struct kobject *kobject); ---- a/fs/efivarfs/vars.c -+++ b/fs/efivarfs/vars.c -@@ -259,6 +259,7 @@ efivar_validate(efi_guid_t vendor, efi_c - kfree(utf8_name); - return true; - } -+EXPORT_SYMBOL_GPL(efivar_validate); - - bool - efivar_variable_is_removable(efi_guid_t vendor, const char *var_name, -@@ -287,7 +288,7 @@ efivar_variable_is_removable(efi_guid_t - */ - return found; - } -- -+EXPORT_SYMBOL_GPL(efivar_variable_is_removable); - static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor, - struct list_head *head) - { -@@ -446,7 +447,7 @@ free: - - return err; - } -- -+EXPORT_SYMBOL_GPL(efivar_init); - /** - * efivar_entry_add - add entry to variable list - * @entry: entry to add to list -@@ -466,7 +467,7 @@ int efivar_entry_add(struct efivar_entry - - return 0; - } -- -+EXPORT_SYMBOL_GPL(efivar_entry_add); - /** - * __efivar_entry_add - add entry to variable list - * @entry: entry to add to list -@@ -487,7 +488,7 @@ void efivar_entry_remove(struct efivar_e - { - list_del(&entry->list); - } -- -+EXPORT_SYMBOL_GPL(efivar_entry_remove); - /* - * efivar_entry_list_del_unlock - remove entry from variable list - * @entry: entry to remove -@@ -536,7 +537,7 @@ int efivar_entry_delete(struct efivar_en - efivar_entry_list_del_unlock(entry); - return 0; - } -- -+EXPORT_SYMBOL_GPL(efivar_entry_delete); - /** - * efivar_entry_size - obtain the size of a variable - * @entry: entry for this variable -@@ -562,7 +563,7 @@ int efivar_entry_size(struct efivar_entr - - return 0; - } -- -+EXPORT_SYMBOL_GPL(efivar_entry_size); - /** - * __efivar_entry_get - call get_variable() - * @entry: read data for this variable -@@ -585,7 +586,7 @@ int __efivar_entry_get(struct efivar_ent - - return efi_status_to_err(status); - } -- -+EXPORT_SYMBOL_GPL(__efivar_entry_get); - /** - * efivar_entry_get - call get_variable() - * @entry: read data for this variable -@@ -606,7 +607,7 @@ int efivar_entry_get(struct efivar_entry - - return 0; - } -- -+EXPORT_SYMBOL_GPL(efivar_entry_get); - /** - * efivar_entry_set_get_size - call set_variable() and get new size (atomic) - * @entry: entry containing variable to set and get -@@ -686,7 +687,7 @@ out: - return err; - - } -- -+EXPORT_SYMBOL_GPL(efivar_entry_set_get_size); - /** - * efivar_entry_iter - iterate over variable list - * @func: callback function -@@ -720,3 +721,4 @@ int efivar_entry_iter(int (*func)(struct - - return err; - } -+EXPORT_SYMBOL_GPL(efivar_entry_iter); -\ No newline at end of file diff --git a/target/linux/generic/pending-6.1/110-v6.3-0001-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch b/target/linux/generic/pending-6.1/110-v6.3-0001-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch new file mode 100644 index 000000000..ebeeae2f8 --- /dev/null +++ b/target/linux/generic/pending-6.1/110-v6.3-0001-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch @@ -0,0 +1,32 @@ +From f7982c726e02001afc19052fe48f642dfcbc00b2 Mon Sep 17 00:00:00 2001 +From: Vincent Tremblay +Date: Mon, 26 Dec 2022 21:10:37 -0500 +Subject: [PATCH 1/2] spidev: Add Silicon Labs EM3581 device compatible + +Add compatible string for Silicon Labs EM3581 device. + +Note: This patch is adapted from a patch submitted to the for-next branch (v6.3). + +Signed-off-by: Vincent Tremblay +--- + drivers/spi/spidev.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -700,6 +700,7 @@ static const struct spi_device_id spidev + { .name = "m53cpld" }, + { .name = "spi-petra" }, + { .name = "spi-authenta" }, ++ { .name = "em3581" }, + {}, + }; + MODULE_DEVICE_TABLE(spi, spidev_spi_ids); +@@ -726,6 +727,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 = "silabs,em3581", .data = &spidev_of_check }, + {}, + }; + MODULE_DEVICE_TABLE(of, spidev_dt_ids); diff --git a/target/linux/generic/pending-6.1/110-v6.3-0002-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch b/target/linux/generic/pending-6.1/110-v6.3-0002-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch new file mode 100644 index 000000000..db5b5800f --- /dev/null +++ b/target/linux/generic/pending-6.1/110-v6.3-0002-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch @@ -0,0 +1,32 @@ +From 536581825219e97fa2ae0c4de35605d2f6311416 Mon Sep 17 00:00:00 2001 +From: Vincent Tremblay +Date: Tue, 27 Dec 2022 09:00:58 -0500 +Subject: [PATCH 2/2] spidev: Add Silicon Labs SI3210 device compatible + +Add compatible string for Silicon Labs SI3210 device. + +Note: This patch is adapted from a patch submitted to the for-next branch (v6.3). + +Signed-off-by: Vincent Tremblay +--- + drivers/spi/spidev.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -701,6 +701,7 @@ static const struct spi_device_id spidev + { .name = "spi-petra" }, + { .name = "spi-authenta" }, + { .name = "em3581" }, ++ { .name = "si3210" }, + {}, + }; + MODULE_DEVICE_TABLE(spi, spidev_spi_ids); +@@ -728,6 +729,7 @@ static const struct of_device_id spidev_ + { .compatible = "cisco,spi-petra", .data = &spidev_of_check }, + { .compatible = "micron,spi-authenta", .data = &spidev_of_check }, + { .compatible = "silabs,em3581", .data = &spidev_of_check }, ++ { .compatible = "silabs,si3210", .data = &spidev_of_check }, + {}, + }; + MODULE_DEVICE_TABLE(of, spidev_dt_ids); diff --git a/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch b/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch new file mode 100644 index 000000000..d6b10491f --- /dev/null +++ b/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch @@ -0,0 +1,75 @@ +From bd1b9f66d5134e518419f4c4dacf1884c1616983 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Thu, 28 Apr 2022 11:13:23 +0200 +Subject: [PATCH] watchdog: max63xx_wdt: Add support for specifying WDI logic + via GPIO +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On some boards is WDI logic of max6370 chip connected via GPIO. +So extend max63xx_wdt driver to allow specifying WDI logic via GPIO. + +Signed-off-by: Pali Rohár +--- + drivers/watchdog/max63xx_wdt.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/drivers/watchdog/max63xx_wdt.c ++++ b/drivers/watchdog/max63xx_wdt.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #define DEFAULT_HEARTBEAT 60 + #define MAX_HEARTBEAT 60 +@@ -53,6 +54,9 @@ struct max63xx_wdt { + void __iomem *base; + spinlock_t lock; + ++ /* GPIOs */ ++ struct gpio_desc *gpio_wdi; ++ + /* WDI and WSET bits write access routines */ + void (*ping)(struct max63xx_wdt *wdt); + void (*set)(struct max63xx_wdt *wdt, u8 set); +@@ -158,6 +162,17 @@ static const struct watchdog_info max63x + .identity = "max63xx Watchdog", + }; + ++static void max63xx_gpio_ping(struct max63xx_wdt *wdt) ++{ ++ spin_lock(&wdt->lock); ++ ++ gpiod_set_value(wdt->gpio_wdi, 1); ++ udelay(1); ++ gpiod_set_value(wdt->gpio_wdi, 0); ++ ++ spin_unlock(&wdt->lock); ++} ++ + static void max63xx_mmap_ping(struct max63xx_wdt *wdt) + { + u8 val; +@@ -225,10 +240,19 @@ static int max63xx_wdt_probe(struct plat + return -EINVAL; + } + ++ wdt->gpio_wdi = devm_gpiod_get(dev, NULL, GPIOD_FLAGS_BIT_DIR_OUT); ++ if (IS_ERR(wdt->gpio_wdi) && PTR_ERR(wdt->gpio_wdi) != -ENOENT) ++ return dev_err_probe(dev, PTR_ERR(wdt->gpio_wdi), ++ "unable to request gpio: %ld\n", ++ PTR_ERR(wdt->gpio_wdi)); ++ + err = max63xx_mmap_init(pdev, wdt); + if (err) + return err; + ++ if (!IS_ERR(wdt->gpio_wdi)) ++ wdt->ping = max63xx_gpio_ping; ++ + platform_set_drvdata(pdev, &wdt->wdd); + watchdog_set_drvdata(&wdt->wdd, wdt); + 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 deleted file mode 100644 index be1d94277..000000000 --- a/target/linux/generic/pending-6.1/130-add-linux-spidev-compatible-si3210.patch +++ /dev/null @@ -1,18 +0,0 @@ -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 -@@ -726,6 +726,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.1/143-jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsys.patch b/target/linux/generic/pending-6.1/143-jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsys.patch new file mode 100644 index 000000000..e5a86dd29 --- /dev/null +++ b/target/linux/generic/pending-6.1/143-jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsys.patch @@ -0,0 +1,121 @@ +From eee53f6eb7561f516b9c4bac829ce31c48096130 Mon Sep 17 00:00:00 2001 +From: Fabian Frederick +Date: Tue, 9 May 2017 22:30:03 +0200 +Subject: [PATCH] jffs2: reduce stack usage in jffs2_build_xattr_subsystem() + +Use kcalloc() for allocation/flush of 128 pointers table to +reduce stack usage. + +Function now returns -ENOMEM or 0 on success. + +stackusage +Before: +./fs/jffs2/xattr.c:775 jffs2_build_xattr_subsystem 1208 +dynamic,bounded + +After: +./fs/jffs2/xattr.c:775 jffs2_build_xattr_subsystem 192 +dynamic,bounded + +Also update definition when CONFIG_JFFS2_FS_XATTR is not enabled + +Tested with an MTD mount point and some user set/getfattr. + +Many current target on OpenWRT also suffer from a compilation warning +(that become an error with CONFIG_WERROR) with the following output: + +fs/jffs2/xattr.c: In function 'jffs2_build_xattr_subsystem': +fs/jffs2/xattr.c:887:1: error: the frame size of 1088 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] + 887 | } + | ^ + +Using dynamic allocation fix this compilation warning. + +Fixes: c9f700f840bd ("[JFFS2][XATTR] using 'delete marker' for xdatum/xref deletion") +Reported-by: Tim Gardner +Reported-by: kernel test robot +Reported-by: Ron Economos +Reported-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Signed-off-by: Fabian Frederick +Signed-off-by: Christian Marangi +Cc: stable@vger.kernel.org +--- + fs/jffs2/build.c | 5 ++++- + fs/jffs2/xattr.c | 13 +++++++++---- + fs/jffs2/xattr.h | 4 ++-- + 3 files changed, 15 insertions(+), 7 deletions(-) + +--- a/fs/jffs2/build.c ++++ b/fs/jffs2/build.c +@@ -211,7 +211,10 @@ static int jffs2_build_filesystem(struct + ic->scan_dents = NULL; + cond_resched(); + } +- jffs2_build_xattr_subsystem(c); ++ ret = jffs2_build_xattr_subsystem(c); ++ if (ret) ++ goto exit; ++ + c->flags &= ~JFFS2_SB_FLAG_BUILDING; + + dbg_fsbuild("FS build complete\n"); +--- a/fs/jffs2/xattr.c ++++ b/fs/jffs2/xattr.c +@@ -772,10 +772,10 @@ void jffs2_clear_xattr_subsystem(struct + } + + #define XREF_TMPHASH_SIZE (128) +-void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) ++int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) + { + struct jffs2_xattr_ref *ref, *_ref; +- struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE]; ++ struct jffs2_xattr_ref **xref_tmphash; + struct jffs2_xattr_datum *xd, *_xd; + struct jffs2_inode_cache *ic; + struct jffs2_raw_node_ref *raw; +@@ -784,9 +784,12 @@ void jffs2_build_xattr_subsystem(struct + + BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); + ++ xref_tmphash = kcalloc(XREF_TMPHASH_SIZE, ++ sizeof(struct jffs2_xattr_ref *), GFP_KERNEL); ++ if (!xref_tmphash) ++ return -ENOMEM; ++ + /* Phase.1 : Merge same xref */ +- for (i=0; i < XREF_TMPHASH_SIZE; i++) +- xref_tmphash[i] = NULL; + for (ref=c->xref_temp; ref; ref=_ref) { + struct jffs2_xattr_ref *tmp; + +@@ -884,6 +887,8 @@ void jffs2_build_xattr_subsystem(struct + "%u of xref (%u dead, %u orphan) found.\n", + xdatum_count, xdatum_unchecked_count, xdatum_orphan_count, + xref_count, xref_dead_count, xref_orphan_count); ++ kfree(xref_tmphash); ++ return 0; + } + + struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, +--- a/fs/jffs2/xattr.h ++++ b/fs/jffs2/xattr.h +@@ -71,7 +71,7 @@ static inline int is_xattr_ref_dead(stru + #ifdef CONFIG_JFFS2_FS_XATTR + + extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c); +-extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); ++extern int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); + extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c); + + extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, +@@ -103,7 +103,7 @@ extern ssize_t jffs2_listxattr(struct de + #else + + #define jffs2_init_xattr_subsystem(c) +-#define jffs2_build_xattr_subsystem(c) ++#define jffs2_build_xattr_subsystem(c) (0) + #define jffs2_clear_xattr_subsystem(c) + + #define jffs2_xattr_do_crccheck_inode(c, ic) diff --git a/target/linux/generic/pending-6.1/160-workqueue-fix-enum-type-for-gcc-13.patch b/target/linux/generic/pending-6.1/160-workqueue-fix-enum-type-for-gcc-13.patch new file mode 100644 index 000000000..82076121a --- /dev/null +++ b/target/linux/generic/pending-6.1/160-workqueue-fix-enum-type-for-gcc-13.patch @@ -0,0 +1,44 @@ +From 525ff9c2965770762b81d679820552a208070d59 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 17 Jan 2023 17:40:35 +0100 +Subject: workqueue: fix enum type for gcc-13 + +In gcc-13, the WORK_STRUCT_WQ_DATA_MASK constant is a signed 64-bit +type on 32-bit architectures because the enum definition has both +negative numbers and numbers above LONG_MAX in it: + +kernel/workqueue.c: In function 'get_work_pwq': +kernel/workqueue.c:709:24: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] + 709 | return (void *)(data & WORK_STRUCT_WQ_DATA_MASK); + | ^ +kernel/workqueue.c: In function 'get_work_pool': +kernel/workqueue.c:737:25: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] + 737 | return ((struct pool_workqueue *) + | ^ +kernel/workqueue.c: In function 'get_work_pool_id': +kernel/workqueue.c:759:25: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] + 759 | return ((struct pool_workqueue *) + | ^ + +Change the enum definition to ensure all values can fit into +the range of 'unsigned long' on all architectures. + +Signed-off-by: Arnd Bergmann +Tested-by: Thierry Reding +Tested-by: Lai Jiangshan +Signed-off-by: Tejun Heo +--- + include/linux/workqueue.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/workqueue.h ++++ b/include/linux/workqueue.h +@@ -83,7 +83,7 @@ enum { + + /* convenience constants */ + WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1, +- WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, ++ WORK_STRUCT_WQ_DATA_MASK = (unsigned long)~WORK_STRUCT_FLAG_MASK, + WORK_STRUCT_NO_POOL = (unsigned long)WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT, + + /* bit mask for work_busy() return values */ diff --git a/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch index a4413e919..82576d644 100644 --- a/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch +++ b/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch @@ -9,7 +9,7 @@ Acked-by: Rob Landley --- --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -1032,9 +1032,6 @@ config FW_ARC +@@ -1033,9 +1033,6 @@ config FW_ARC config ARCH_MAY_HAVE_PC_FDC bool @@ -19,7 +19,7 @@ Acked-by: Rob Landley config CEVT_BCM1480 bool -@@ -3089,6 +3086,18 @@ choice +@@ -3090,6 +3087,18 @@ choice bool "Extend builtin kernel arguments with bootloader arguments" endchoice diff --git a/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch b/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch new file mode 100644 index 000000000..bd56adad3 --- /dev/null +++ b/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch @@ -0,0 +1,71 @@ +From e6e6ef4275978823ec3a84133fc91f4ffbef5c84 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Mon, 22 Feb 2016 18:09:44 +0000 +Subject: [PATCH] MIPS: Add barriers between dcache & icache flushes + +Index-based cache operations may be arbitrarily reordered by out of +order CPUs. Thus code which writes back the dcache & then invalidates +the icache using indexed cache ops must include a barrier between +operating on the 2 caches in order to prevent the scenario in which: + + - icache invalidation occurs. + + - icache fetch occurs, due to speculation. + + - dcache writeback occurs. + +If the above were allowed to happen then the icache would contain stale +data. Forcing the dcache writeback to complete before the icache +invalidation avoids this. + +Signed-off-by: Paul Burton +Cc: James Hogan +--- + arch/mips/mm/c-r4k.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/arch/mips/mm/c-r4k.c ++++ b/arch/mips/mm/c-r4k.c +@@ -514,6 +514,7 @@ static inline void local_r4k___flush_cac + + default: + r4k_blast_dcache(); ++ mb(); /* cache instructions may be reordered */ + r4k_blast_icache(); + break; + } +@@ -594,8 +595,10 @@ static inline void local_r4k_flush_cache + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache(); + /* If executable, blast stale lines from icache */ +- if (exec) ++ if (exec) { ++ mb(); /* cache instructions may be reordered */ + r4k_blast_icache(); ++ } + } + + static void r4k_flush_cache_range(struct vm_area_struct *vma, +@@ -696,8 +699,13 @@ static inline void local_r4k_flush_cache + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { + vaddr ? r4k_blast_dcache_page(addr) : + r4k_blast_dcache_user_page(addr); +- if (exec && !cpu_icache_snoops_remote_store) ++ if (exec) ++ mb(); /* cache instructions may be reordered */ ++ ++ if (exec && !cpu_icache_snoops_remote_store) { + r4k_blast_scache_page(addr); ++ mb(); /* cache instructions may be reordered */ ++ } + } + if (exec) { + if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { +@@ -764,6 +772,7 @@ static inline void __local_r4k_flush_ica + else + blast_dcache_range(start, end); + } ++ mb(); /* cache instructions may be reordered */ + } + + if (type == R4K_INDEX || diff --git a/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch b/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch new file mode 100644 index 000000000..91654cc29 --- /dev/null +++ b/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch @@ -0,0 +1,113 @@ +From patchwork Thu Mar 16 19:28:33 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13178238 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 5EF2AC6FD19 + for ; Thu, 16 Mar 2023 19:28:43 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230076AbjCPT2l (ORCPT ); + Thu, 16 Mar 2023 15:28:41 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56412 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230039AbjCPT2k (ORCPT + ); Thu, 16 Mar 2023 15:28:40 -0400 +Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com + [IPv6:2a00:1450:4864:20::42f]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7259B7D9F; + Thu, 16 Mar 2023 12:28:38 -0700 (PDT) +Received: by mail-wr1-x42f.google.com with SMTP id y14so2539231wrq.4; + Thu, 16 Mar 2023 12:28:38 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1678994917; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=; + b=FzMRr5ekh/fDiJqTlezNj6nLjzvn5z92FtYeB8MquVSMB8PuvarccnyqAzsXiccf+v + uwRFIomnTWNLGVjzc1xrB2hGiCKD3jBo5n1u8p/yEV6rpolbxVjfM7eTHXyAHXGXz7ZJ + TPeVbWfAlxiSD6+BPtXr/efehcdI64fIoL6G/U1WHNMo01Tzr/Obf3y5tug17N0fGcXg + CH6E5a2HguZUtwrm26LcK9IOV/7xEx5eIE1cOvTLMxPbGWaZwEjjP16HylJr06xRLhaf + RpiYBT3mXwwuOx0jLOhqavY/2kZ9GVbZRWMMwZrZv9xNO13SBwc1VUVgD4k3FntnSk7Z + AaOQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1678994917; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=; + b=OaA5DMgqalrfqO5iOtmmxFPsH90MkN7l4EJpyVnzuiO1Wd6rSCpqPOR7xpxZno8OPP + tdfm4vzn9Ie4AUDbFKDTUlPG+tgkmIruo3K9C0VnY9DD2PRZMEYBbWaJKU1otqKt0NKu + IAAHNvxvQvCESKzbXFLYwWbRKFScOSMGmGBTDfgThz51A18Ff1hJy/BmnuZk7M2TLgHO + wQpy9t7oeB/Hkxl41y46emLc/nESsvwvAG/fx/zPzCe9UiaQLrdZq+BKeOwSBedktzK5 + U/ZTfgzU2UGSI67aGRqqGnI0uXq+MAJMK18qzM0VByxj6W+AXJ6BJr5P0quljeQ8upSg + bEUg== +X-Gm-Message-State: AO0yUKWnqTlccBDnqwCSRdqOBGc2FyfiLy1Tg7EjPENlISpzXuDYwW/R + lJSI06rrfq+Vel/SigfpGJI= +X-Google-Smtp-Source: + AK7set/jYfYl9ttVzIXJO+ZQVfa6cE/yOsP8fx4teiTmGNNWyVlIJRzMAlF3IUGqRAXAmY3hAabIuQ== +X-Received: by 2002:a5d:40ce:0:b0:2cd:ceab:df1a with SMTP id + b14-20020a5d40ce000000b002cdceabdf1amr381006wrq.32.1678994916642; + Thu, 16 Mar 2023 12:28:36 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + l10-20020a5d4bca000000b002cfea3c49d5sm180041wrt.52.2023.03.16.12.28.35 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Thu, 16 Mar 2023 12:28:35 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: f.fainelli@gmail.com, jonas.gorski@gmail.com, + bcm-kernel-feedback-list@broadcom.com, tglx@linutronix.de, + maz@kernel.org, linux-mips@vger.kernel.org, + linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +Subject: [PATCH v2] irqchip/bcm-6345-l1: request memory region +Date: Thu, 16 Mar 2023 20:28:33 +0100 +Message-Id: <20230316192833.1603149-1-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230316180701.783785-1-noltari@gmail.com> +References: <20230316180701.783785-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: linux-mips@vger.kernel.org + +Request memory region in order to display it in /proc/iomem. +Also stop printing the MMIO address since it just displays (ptrval). + +Signed-off-by: Álvaro Fernández Rojas +Acked-by: Florian Fainelli +--- + v2: request memory region and stop displaying MMIO address. + + drivers/irqchip/irq-bcm6345-l1.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/irqchip/irq-bcm6345-l1.c ++++ b/drivers/irqchip/irq-bcm6345-l1.c +@@ -257,6 +257,9 @@ static int __init bcm6345_l1_init_one(st + if (!cpu->map_base) + return -ENOMEM; + ++ if (!request_mem_region(res.start, sz, res.name)) ++ pr_err("failed to request intc memory"); ++ + for (i = 0; i < n_words; i++) { + cpu->enable_cache[i] = 0; + __raw_writel(0, cpu->map_base + reg_enable(intc, i)); +@@ -335,8 +338,7 @@ static int __init bcm6345_l1_of_init(str + for_each_cpu(idx, &intc->cpumask) { + struct bcm6345_l1_cpu *cpu = intc->cpus[idx]; + +- pr_info(" CPU%u at MMIO 0x%p (irq = %d)\n", idx, +- cpu->map_base, cpu->parent_irq); ++ pr_info(" CPU%u (irq = %d)\n", idx, cpu->parent_irq); + } + + return 0; diff --git a/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch b/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch index d9e8bd92e..c619d12ce 100644 --- a/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch +++ b/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch @@ -66,7 +66,7 @@ Subject: [PATCH] mtd: mtdsplit support /* * MTD methods which simply translate the effective address and pass through -@@ -236,6 +238,146 @@ static int mtd_add_partition_attrs(struc +@@ -236,6 +238,147 @@ static int mtd_add_partition_attrs(struc return ret; } @@ -198,7 +198,8 @@ Subject: [PATCH] mtd: mtdsplit support + if (rootfs_found) + return; + -+ if (!strcmp(part->name, "rootfs")) { ++ if (of_find_property(mtd_get_of_node(part), "linux,rootfs", NULL) || ++ !strcmp(part->name, "rootfs")) { + run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); + + rootfs_found = 1; @@ -213,7 +214,7 @@ Subject: [PATCH] mtd: mtdsplit support int mtd_add_partition(struct mtd_info *parent, const char *name, long long offset, long long length) { -@@ -274,6 +416,7 @@ int mtd_add_partition(struct mtd_info *p +@@ -274,6 +417,7 @@ int mtd_add_partition(struct mtd_info *p if (ret) goto err_remove_part; @@ -221,7 +222,7 @@ Subject: [PATCH] mtd: mtdsplit support mtd_add_partition_attrs(child); return 0; -@@ -422,6 +565,7 @@ int add_mtd_partitions(struct mtd_info * +@@ -422,6 +566,7 @@ int add_mtd_partitions(struct mtd_info * goto err_del_partitions; } @@ -229,7 +230,7 @@ Subject: [PATCH] mtd: mtdsplit support mtd_add_partition_attrs(child); /* Look for subpartitions */ -@@ -438,31 +582,6 @@ err_del_partitions: +@@ -438,31 +583,6 @@ err_del_partitions: return ret; } diff --git a/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch b/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch new file mode 100644 index 000000000..6740d1d7b --- /dev/null +++ b/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch @@ -0,0 +1,21 @@ +From: Christian Marangi +Subject: kernel/mtd: add support for EON EN25QX128A + +Add support for EON EN25QX128A with no flags as it does +support SFDP parsing. + +Signed-off-by: Christian Marangi +--- + 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 +@@ -19,6 +19,7 @@ static const struct flash_info eon_nor_p + NO_SFDP_FLAGS(SECT_4K) }, + { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256) + NO_SFDP_FLAGS(SECT_4K) }, ++ { "en25qx128a", INFO(0x1c7118, 0, 64 * 1024, 256) }, + { "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/488-mtd-spi-nor-add-xmc-xm25qh64c.patch b/target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch new file mode 100644 index 000000000..e1e4f25e1 --- /dev/null +++ b/target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch @@ -0,0 +1,23 @@ +From: Joe Mullally +Subject: mtd/spi-nor/xmc: add support for XMC XM25QH64C + +The XMC XM25QH64C is a 8MB SPI NOR chip. The patch is verified on TL-WPA8631P v3. +Datasheet available at https://www.xmcwh.com/uploads/442/XM25QH64C.pdf + +Signed-off-by: Joe Mullally +--- + 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 +@@ -13,6 +13,9 @@ static const struct flash_info xmc_nor_p + { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ) }, ++ { "XM25QH64C", INFO(0x204017, 0, 64 * 1024, 128) ++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | ++ SPI_NOR_QUAD_READ) }, + { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ) }, diff --git a/target/linux/generic/pending-6.1/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 index 321680154..e0cbc4508 100644 --- a/target/linux/generic/pending-6.1/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 @@ -165,7 +165,7 @@ Signed-off-by: Bernhard Frauendienst + platform_set_drvdata(pdev, info); + + of_for_each_phandle(&it, err, node, "devices", NULL, 0) { -+ mtd = get_mtd_device_by_node(it.node); ++ mtd = of_get_mtd_device_by_node(it.node); + if (IS_ERR(mtd)) { + of_node_put(it.node); + err = -EPROBE_DEFER; diff --git a/target/linux/generic/pending-6.1/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 index a9b32b60f..9b264b3a0 100644 --- a/target/linux/generic/pending-6.1/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 -@@ -2136,6 +2136,8 @@ struct net_device { +@@ -2135,6 +2135,8 @@ struct net_device { struct netdev_hw_addr_list mc; struct netdev_hw_addr_list dev_addrs; 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 index ccd4bf08c..7d603f5de 100644 --- 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 @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2859,8 +2859,8 @@ static irqreturn_t mtk_handle_irq_rx(int +@@ -3048,8 +3048,8 @@ static irqreturn_t mtk_handle_irq_rx(int eth->rx_events++; if (likely(napi_schedule_prep(ð->rx_napi))) { @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau } return IRQ_HANDLED; -@@ -2872,8 +2872,8 @@ static irqreturn_t mtk_handle_irq_tx(int +@@ -3061,8 +3061,8 @@ static irqreturn_t mtk_handle_irq_tx(int eth->tx_events++; if (likely(napi_schedule_prep(ð->tx_napi))) { @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau } return IRQ_HANDLED; -@@ -4194,6 +4194,8 @@ static int mtk_probe(struct platform_dev +@@ -4727,6 +4727,8 @@ static int mtk_probe(struct platform_dev * for NAPI to work */ init_dummy_netdev(ð->dummy_dev); diff --git a/target/linux/generic/pending-6.1/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 index 48b1afe3f..8d2803158 100644 --- a/target/linux/generic/pending-6.1/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 -@@ -1750,6 +1750,9 @@ void phy_detach(struct phy_device *phyde +@@ -1753,6 +1753,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 -@@ -858,6 +858,12 @@ struct phy_driver { +@@ -878,6 +878,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 index e27ac3595..d444b2027 100644 --- 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 @@ -12,17 +12,16 @@ 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; +@@ -27,6 +27,13 @@ static struct sk_buff *mtk_tag_xmit(stru + + skb_set_queue_mapping(skb, dp->index); + /* 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; ++ eth_skb_pad(skb); + /* Build the special tag after the MAC Source Address. If VLAN header * is present, it's required that VLAN header and special tag is diff --git a/target/linux/generic/pending-6.1/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 index 61ef7ebda..f29e69035 100644 --- a/target/linux/generic/pending-6.1/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) -@@ -849,6 +858,43 @@ static irqreturn_t rtl9000a_handle_inter +@@ -849,6 +858,48 @@ static irqreturn_t rtl9000a_handle_inter return IRQ_HANDLED; } @@ -48,8 +48,13 @@ Signed-off-by: Alexander Couzens + u16 option_mode; + + switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_2500BASEX: ++ if (!phydev->is_c45) { ++ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX; ++ break; ++ } ++ fallthrough; ++ case PHY_INTERFACE_MODE_SGMII: + option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII; + break; + default: @@ -57,24 +62,24 @@ Signed-off-by: Alexander Couzens + } + + phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, -+ 0x75f3, 0); ++ 0x75f3, 0); + + phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL, + RTL8221B_SERDES_OPTION, + RTL8221B_SERDES_OPTION_MODE_MASK, option_mode); + switch (option_mode) { -+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII: -+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX: -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020); -+ break; -+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII: -+ case RTL8221B_SERDES_OPTION_MODE_HISGMII: -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020); -+ break; ++ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII: ++ case RTL8221B_SERDES_OPTION_MODE_2500BASEX: ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503); ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455); ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020); ++ break; ++ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII: ++ case RTL8221B_SERDES_OPTION_MODE_HISGMII: ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503); ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433); ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020); ++ break; + } + + return 0; @@ -83,19 +88,19 @@ Signed-off-by: Alexander Couzens static struct phy_driver realtek_drvs[] = { { PHY_ID_MATCH_EXACT(0x00008201), -@@ -1001,6 +1047,7 @@ static struct phy_driver realtek_drvs[] +@@ -1001,6 +1052,7 @@ static struct phy_driver realtek_drvs[] PHY_ID_MATCH_EXACT(0x001cc849), .name = "RTL8221B-VB-CG 2.5Gbps PHY", .get_features = rtl822x_get_features, -+ .config_init = rtl8221b_config_init, ++ .config_init = rtl8221b_config_init, .config_aneg = rtl822x_config_aneg, .read_status = rtl822x_read_status, .suspend = genphy_suspend, -@@ -1012,6 +1059,7 @@ static struct phy_driver realtek_drvs[] +@@ -1012,6 +1064,7 @@ static struct phy_driver realtek_drvs[] .name = "RTL8221B-VM-CG 2.5Gbps PHY", .get_features = rtl822x_get_features, .config_aneg = rtl822x_config_aneg, -+ .config_init = rtl8221b_config_init, ++ .config_init = rtl8221b_config_init, .read_status = rtl822x_read_status, .suspend = genphy_suspend, .resume = rtlgen_resume, diff --git a/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch b/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch new file mode 100644 index 000000000..a9b200214 --- /dev/null +++ b/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch @@ -0,0 +1,45 @@ +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -684,6 +684,25 @@ static int rtl822x_config_aneg(struct ph + return __genphy_config_aneg(phydev, ret); + } + ++static void rtl822x_update_interface(struct phy_device *phydev) ++{ ++ /* Automatically switch SERDES interface between ++ * SGMII and 2500-BaseX according to speed. ++ */ ++ switch (phydev->speed) { ++ case SPEED_2500: ++ phydev->interface = PHY_INTERFACE_MODE_2500BASEX; ++ break; ++ case SPEED_1000: ++ case SPEED_100: ++ case SPEED_10: ++ phydev->interface = PHY_INTERFACE_MODE_SGMII; ++ break; ++ default: ++ break; ++ } ++} ++ + static int rtl822x_read_status(struct phy_device *phydev) + { + int ret; +@@ -702,11 +721,14 @@ static int rtl822x_read_status(struct ph + phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL); + } + +- ret = genphy_read_status(phydev); ++ ret = rtlgen_read_status(phydev); + if (ret < 0) + return ret; + +- return rtlgen_get_speed(phydev); ++ if (phydev->is_c45 && phydev->link) ++ rtl822x_update_interface(phydev); ++ ++ return 0; + } + + static bool rtlgen_supports_2_5gbps(struct phy_device *phydev) 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 index ec6f68504..00a43e3e5 100644 --- 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 @@ -15,7 +15,7 @@ Signed-off-by: Alexander Couzens --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2195,6 +2195,10 @@ mt7530_setup(struct dsa_switch *ds) +@@ -2236,6 +2236,10 @@ mt7530_setup(struct dsa_switch *ds) return -ENODEV; } diff --git a/target/linux/generic/pending-6.1/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 deleted file mode 100644 index cd9770665..000000000 --- a/target/linux/generic/pending-6.1/724-net-mtk_sgmii-implement-mtk_pcs_ops.patch +++ /dev/null @@ -1,46 +0,0 @@ -From cbfed00575d15eafd85efd9619b7ecc0836a4aa7 Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Sat, 13 Aug 2022 14:42:12 +0200 -Subject: [PATCH 04/10] net: mtk_sgmii: implement mtk_pcs_ops - -Implement mtk_pcs_ops for the SGMII pcs to read the current state -of the hardware. - -Signed-off-by: Alexander Couzens -[added DUPLEX_FULL] -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -122,10 +122,28 @@ static void mtk_pcs_link_up(struct phyli - regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); - } - -+static void mtk_pcs_get_state(struct phylink_pcs *pcs, struct phylink_link_state *state) -+{ -+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ unsigned int val; -+ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -+ state->an_complete = !!(val & SGMII_AN_COMPLETE); -+ state->link = !!(val & SGMII_LINK_STATYS); -+ if (!state->link) -+ return; -+ -+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); -+ state->speed = val & RG_PHY_SPEED_3_125G ? SPEED_2500 : SPEED_1000; -+ state->duplex = DUPLEX_FULL; -+ state->pause = 0; -+} -+ - static const struct phylink_pcs_ops mtk_pcs_ops = { - .pcs_config = mtk_pcs_config, - .pcs_an_restart = mtk_pcs_restart_an, - .pcs_link_up = mtk_pcs_link_up, -+ .pcs_get_state = mtk_pcs_get_state, - }; - - int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) diff --git a/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch new file mode 100644 index 000000000..cdc181763 --- /dev/null +++ b/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch @@ -0,0 +1,65 @@ +From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 2 Apr 2023 23:56:16 +0100 +Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs + +Some vendor bootloaders do weird things with those PHYs which result in +link modes being reported wrongly. Start from a clean sheet by resetting +the PHY. + +Reported-by: Yevhen Kolomeiko +Signed-off-by: Daniel Golle +--- + drivers/net/phy/realtek.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -1038,6 +1038,7 @@ static struct phy_driver realtek_drvs[] + .write_page = rtl821x_write_page, + .read_mmd = rtl822x_read_mmd, + .write_mmd = rtl822x_write_mmd, ++ .soft_reset = genphy_soft_reset, + }, { + PHY_ID_MATCH_EXACT(0x001cc840), + .name = "RTL8226B_RTL8221B 2.5Gbps PHY", +@@ -1050,6 +1051,7 @@ static struct phy_driver realtek_drvs[] + .write_page = rtl821x_write_page, + .read_mmd = rtl822x_read_mmd, + .write_mmd = rtl822x_write_mmd, ++ .soft_reset = genphy_soft_reset, + }, { + PHY_ID_MATCH_EXACT(0x001cc838), + .name = "RTL8226-CG 2.5Gbps PHY", +@@ -1060,6 +1062,7 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .soft_reset = genphy_soft_reset, + }, { + PHY_ID_MATCH_EXACT(0x001cc848), + .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", +@@ -1070,6 +1073,7 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .soft_reset = genphy_soft_reset, + }, { + PHY_ID_MATCH_EXACT(0x001cc849), + .name = "RTL8221B-VB-CG 2.5Gbps PHY", +@@ -1081,6 +1085,7 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .soft_reset = genphy_soft_reset, + }, { + PHY_ID_MATCH_EXACT(0x001cc84a), + .name = "RTL8221B-VM-CG 2.5Gbps PHY", +@@ -1092,6 +1097,7 @@ static struct phy_driver realtek_drvs[] + .resume = rtlgen_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, ++ .soft_reset = genphy_soft_reset, + }, { + PHY_ID_MATCH_EXACT(0x001cc961), + .name = "RTL8366RB Gigabit Ethernet", diff --git a/target/linux/generic/pending-6.1/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 deleted file mode 100644 index 0fa357d48..000000000 --- a/target/linux/generic/pending-6.1/725-net-mtk_sgmii-fix-powering-up-the-SGMII-phy.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 7f75f43fe2159123baa101fcc8c6faa0b0a4c598 Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Sat, 13 Aug 2022 14:48:51 +0200 -Subject: [PATCH 05/10] net: mtk_sgmii: fix powering up the SGMII phy - -There are certain race condition when the SGMII_PHYA_PWD register still -contains 0x9 which prevents the SGMII from working properly. - -The SGMII still shows link but no traffic can flow. - -Signed-off-by: Alexander Couzens ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -36,9 +36,7 @@ static int mtk_pcs_setup_mode_an(struct - val |= SGMII_AN_RESTART; - regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); - -- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); -- val &= ~SGMII_PHYA_PWD; -- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); - - return 0; - -@@ -70,9 +68,7 @@ static int mtk_pcs_setup_mode_force(stru - regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); - - /* Release PHYA power down state */ -- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); -- val &= ~SGMII_PHYA_PWD; -- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); - - return 0; - } diff --git a/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch new file mode 100644 index 000000000..55f14acb5 --- /dev/null +++ b/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch @@ -0,0 +1,42 @@ +From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 3 Apr 2023 01:21:57 +0300 +Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs + +MAC drivers don't use SGMII in-band autonegotiation unless told to do so +in device tree using 'managed = "in-band-status"'. When using MDIO to +access a PHY, in-band-status is unneeded as we have link-status via +MDIO. Switch off SGMII in-band autonegotiation using magic values. + +Reported-by: Chen Minqiang +Reported-by: Yevhen Kolomeiko +Tested-by: Yevhen Kolomeiko +Signed-off-by: Daniel Golle +--- + drivers/net/phy/realtek.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -883,6 +883,7 @@ static irqreturn_t rtl9000a_handle_inter + static int rtl8221b_config_init(struct phy_device *phydev) + { + u16 option_mode; ++ int val; + + switch (phydev->interface) { + case PHY_INTERFACE_MODE_2500BASEX: +@@ -919,6 +920,13 @@ static int rtl8221b_config_init(struct p + break; + } + ++ /* Disable SGMII AN */ ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2); ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0); ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3); ++ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, ++ val, !(val & BIT(0)), 500, 100000, false); ++ + return 0; + } + diff --git a/target/linux/generic/pending-6.1/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 deleted file mode 100644 index 329b41cf0..000000000 --- a/target/linux/generic/pending-6.1/726-net-mtk_sgmii-ensure-the-SGMII-PHY-is-powered-down-o.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 9daea9b71d060d93d7394ac465b2e5ee0b7e7bca Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Mon, 15 Aug 2022 16:02:01 +0200 -Subject: [PATCH 06/10] net: mtk_sgmii: ensure the SGMII PHY is powered down on - configuration - -The code expect the PHY to be in power down (which is only true after reset). -Allow the changes of SGMII parameters more than once. ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -7,6 +7,7 @@ - * - */ - -+#include - #include - #include - #include -@@ -24,6 +25,9 @@ static int mtk_pcs_setup_mode_an(struct - { - unsigned int val; - -+ /* PHYA power down */ -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); -+ - /* Setup the link timer and QPHY power up inside SGMIISYS */ - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, - SGMII_LINK_TIMER_DEFAULT); -@@ -36,6 +40,10 @@ static int mtk_pcs_setup_mode_an(struct - val |= SGMII_AN_RESTART; - regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); - -+ /* Release PHYA power down state -+ * unknown how much the QPHY needs but it is racy without a sleep -+ */ -+ usleep_range(50, 100); - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); - - return 0; -@@ -50,6 +58,9 @@ static int mtk_pcs_setup_mode_force(stru - { - unsigned int val; - -+ /* PHYA power down */ -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); -+ - regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); - val &= ~RG_PHY_SPEED_MASK; - if (interface == PHY_INTERFACE_MODE_2500BASEX) -@@ -67,7 +78,10 @@ static int mtk_pcs_setup_mode_force(stru - val |= SGMII_SPEED_1000; - regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); - -- /* Release PHYA power down state */ -+ /* Release PHYA power down state -+ * unknown how much the QPHY needs but it is racy without a sleep -+ */ -+ usleep_range(50, 100); - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); - - return 0; diff --git a/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch new file mode 100644 index 000000000..986e842e1 --- /dev/null +++ b/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch @@ -0,0 +1,35 @@ +From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sat, 22 Apr 2023 01:21:14 +0100 +Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex + +As we cannot rely on phy_read_paged function before the PHY is +identified, the paged read in rtlgen_supports_2_5gbps needs to be open +coded as it is being called by the match_phy_device function, ie. before +.read_page and .write_page have been populated. + +Make sure it is also protected by the MDIO bus mutex and use +rtl821x_write_page instead of 3 individually locked MDIO bus operations. + +Signed-off-by: Daniel Golle +--- + drivers/net/phy/realtek.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -735,9 +735,11 @@ static bool rtlgen_supports_2_5gbps(stru + { + int val; + +- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61); +- val = phy_read(phydev, 0x13); +- phy_write(phydev, RTL821x_PAGE_SELECT, 0); ++ mutex_lock(&phydev->mdio.bus->mdio_lock); ++ rtl821x_write_page(phydev, 0xa61); ++ val = __phy_read(phydev, 0x13); ++ rtl821x_write_page(phydev, 0); ++ mutex_unlock(&phydev->mdio.bus->mdio_lock); + + return val >= 0 && val & RTL_SUPPORTS_2500FULL; + } diff --git a/target/linux/generic/pending-6.1/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 deleted file mode 100644 index 5bc187cfc..000000000 --- a/target/linux/generic/pending-6.1/727-net-mtk_sgmii-mtk_pcs_setup_mode_an-don-t-rely-on-re.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e4dca7affb8c03438b63bdb5fddefd6ad2431cfd Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Mon, 15 Aug 2022 14:59:29 +0200 -Subject: [PATCH 07/10] net: mtk_sgmii: mtk_pcs_setup_mode_an: don't rely on - register defaults - -Ensure autonegotiation is enabled. - -Signed-off-by: Alexander Couzens ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -32,12 +32,13 @@ static int mtk_pcs_setup_mode_an(struct - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, - SGMII_LINK_TIMER_DEFAULT); - -+ /* disable remote fault & enable auto neg */ - regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); -- val |= SGMII_REMOTE_FAULT_DIS; -+ val |= SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN; - regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); - - regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -- val |= SGMII_AN_RESTART; -+ val |= SGMII_AN_RESTART | SGMII_AN_ENABLE; - regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); - - /* Release PHYA power down state diff --git a/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch new file mode 100644 index 000000000..717ece0d5 --- /dev/null +++ b/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch @@ -0,0 +1,60 @@ +From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sat, 22 Apr 2023 01:23:08 +0100 +Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE + advertisement + +Use existing generic inline functions to encode local advertisement +of 10GbE link modes as well as to decode link-partner advertisement. + +Signed-off-by: Daniel Golle +--- + drivers/net/phy/realtek.c | 22 +++++----------------- + 1 file changed, 5 insertions(+), 17 deletions(-) + +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -68,10 +68,6 @@ + #define RTL_SUPPORTS_5000FULL BIT(14) + #define RTL_SUPPORTS_2500FULL BIT(13) + #define RTL_SUPPORTS_10000FULL BIT(0) +-#define RTL_ADV_2500FULL BIT(7) +-#define RTL_LPADV_10000FULL BIT(11) +-#define RTL_LPADV_5000FULL BIT(6) +-#define RTL_LPADV_2500FULL BIT(5) + + #define RTL9000A_GINMR 0x14 + #define RTL9000A_GINMR_LINK_STATUS BIT(4) +@@ -669,14 +665,11 @@ static int rtl822x_config_aneg(struct ph + int ret = 0; + + if (phydev->autoneg == AUTONEG_ENABLE) { +- u16 adv2500 = 0; +- +- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, +- phydev->advertising)) +- adv2500 = RTL_ADV_2500FULL; +- + ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12, +- RTL_ADV_2500FULL, adv2500); ++ MDIO_AN_10GBT_CTRL_ADV10G | ++ MDIO_AN_10GBT_CTRL_ADV5G | ++ MDIO_AN_10GBT_CTRL_ADV2_5G, ++ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising)); + if (ret < 0) + return ret; + } +@@ -713,12 +706,7 @@ static int rtl822x_read_status(struct ph + if (lpadv < 0) + return lpadv; + +- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, +- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL); +- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, +- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL); +- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, +- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL); ++ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv); + } + + ret = rtlgen_read_status(phydev); diff --git a/target/linux/generic/pending-6.1/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 deleted file mode 100644 index 0b17f77ee..000000000 --- a/target/linux/generic/pending-6.1/728-net-mtk_sgmii-set-the-speed-according-to-the-phy-int.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 952b64575613d26163a5afa5ff8bfdb57840091b Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Mon, 15 Aug 2022 15:00:14 +0200 -Subject: [PATCH 08/10] net: mtk_sgmii: set the speed according to the phy - interface in AN - -The non auto-negotioting code path is setting the correct speed for the -interface. Ensure auto-negotiation code path is doing it as well. - -Signed-off-by: Alexander Couzens ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -21,13 +21,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st - } - - /* For SGMII interface mode */ --static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) -+static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs, phy_interface_t interface) - { - unsigned int val; - - /* PHYA power down */ - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); - -+ /* Set SGMII phy speed */ -+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); -+ val &= ~RG_PHY_SPEED_MASK; -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val |= RG_PHY_SPEED_3_125G; -+ regmap_write(mpcs->regmap, mpcs->ana_rgc3, val); -+ - /* Setup the link timer and QPHY power up inside SGMIISYS */ - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, - SGMII_LINK_TIMER_DEFAULT); -@@ -100,7 +107,7 @@ static int mtk_pcs_config(struct phylink - if (interface != PHY_INTERFACE_MODE_SGMII) - err = mtk_pcs_setup_mode_force(mpcs, interface); - else if (phylink_autoneg_inband(mode)) -- err = mtk_pcs_setup_mode_an(mpcs); -+ err = mtk_pcs_setup_mode_an(mpcs, interface); - - return err; - } diff --git a/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch new file mode 100644 index 000000000..bae24a2ec --- /dev/null +++ b/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch @@ -0,0 +1,28 @@ +From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sat, 22 Apr 2023 01:25:39 +0100 +Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner + advertisement + +Only use link-partner advertisement bits for 10GbE modes if they are +actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes +unless both of them are set. + +Signed-off-by: Daniel Golle +--- + drivers/net/phy/realtek.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -706,6 +706,10 @@ static int rtl822x_read_status(struct ph + if (lpadv < 0) + return lpadv; + ++ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) || ++ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK)) ++ lpadv = 0; ++ + mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv); + } + diff --git a/target/linux/generic/pending-6.1/729-net-mtk_eth_soc-improve-comment.patch b/target/linux/generic/pending-6.1/729-net-mtk_eth_soc-improve-comment.patch deleted file mode 100644 index 80144850e..000000000 --- a/target/linux/generic/pending-6.1/729-net-mtk_eth_soc-improve-comment.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 06773f19cffd6c9d34dcbc8320169afef5ab60ba Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Mon, 15 Aug 2022 13:58:07 +0200 -Subject: [PATCH 09/10] net: mtk_eth_soc: improve comment - -Signed-off-by: Alexander Couzens ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -80,7 +80,8 @@ static int mtk_pcs_setup_mode_force(stru - val &= ~SGMII_AN_ENABLE; - regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); - -- /* Set the speed etc but leave the duplex unchanged */ -+ /* Set the speed etc but leave the duplex unchanged. -+ * The SGMII mode for 2.5gbit is the same as for 1gbit, expect the speed in ANA_RGC3 */ - regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); - val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK; - val |= SGMII_SPEED_1000; diff --git a/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch new file mode 100644 index 000000000..b5dbfa383 --- /dev/null +++ b/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch @@ -0,0 +1,100 @@ +From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sat, 22 Apr 2023 03:26:01 +0100 +Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x + +Setup Link Down Power Saving Mode according the DTS property +just like for RTL821x 1GE PHYs. + +Signed-off-by: Daniel Golle +--- + drivers/net/phy/realtek.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -62,6 +62,10 @@ + #define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2 + #define RTL8221B_SERDES_OPTION_MODE_HISGMII 3 + ++#define RTL8221B_PHYCR1 0xa430 ++#define RTL8221B_PHYCR1_ALDPS_EN BIT(2) ++#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12) ++ + #define RTL8366RB_POWER_SAVE 0x15 + #define RTL8366RB_POWER_SAVE_ON BIT(12) + +@@ -748,6 +752,25 @@ static int rtl8226_match_phy_device(stru + rtlgen_supports_2_5gbps(phydev); + } + ++static int rtl822x_probe(struct phy_device *phydev) ++{ ++ struct device *dev = &phydev->mdio.dev; ++ int val; ++ ++ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1); ++ if (val < 0) ++ return val; ++ ++ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable")) ++ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN; ++ else ++ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN); ++ ++ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val); ++ ++ return 0; ++} ++ + static int rtlgen_resume(struct phy_device *phydev) + { + int ret = genphy_resume(phydev); +@@ -1033,6 +1056,7 @@ static struct phy_driver realtek_drvs[] + .match_phy_device = rtl8226_match_phy_device, + .get_features = rtl822x_get_features, + .config_aneg = rtl822x_config_aneg, ++ .probe = rtl822x_probe, + .read_status = rtl822x_read_status, + .suspend = genphy_suspend, + .resume = rtlgen_resume, +@@ -1046,6 +1070,7 @@ static struct phy_driver realtek_drvs[] + .name = "RTL8226B_RTL8221B 2.5Gbps PHY", + .get_features = rtl822x_get_features, + .config_aneg = rtl822x_config_aneg, ++ .probe = rtl822x_probe, + .read_status = rtl822x_read_status, + .suspend = genphy_suspend, + .resume = rtlgen_resume, +@@ -1059,6 +1084,7 @@ static struct phy_driver realtek_drvs[] + .name = "RTL8226-CG 2.5Gbps PHY", + .get_features = rtl822x_get_features, + .config_aneg = rtl822x_config_aneg, ++ .probe = rtl822x_probe, + .read_status = rtl822x_read_status, + .suspend = genphy_suspend, + .resume = rtlgen_resume, +@@ -1070,6 +1096,7 @@ static struct phy_driver realtek_drvs[] + .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", + .get_features = rtl822x_get_features, + .config_aneg = rtl822x_config_aneg, ++ .probe = rtl822x_probe, + .read_status = rtl822x_read_status, + .suspend = genphy_suspend, + .resume = rtlgen_resume, +@@ -1082,6 +1109,7 @@ static struct phy_driver realtek_drvs[] + .get_features = rtl822x_get_features, + .config_init = rtl8221b_config_init, + .config_aneg = rtl822x_config_aneg, ++ .probe = rtl822x_probe, + .read_status = rtl822x_read_status, + .suspend = genphy_suspend, + .resume = rtlgen_resume, +@@ -1094,6 +1122,7 @@ static struct phy_driver realtek_drvs[] + .get_features = rtl822x_get_features, + .config_aneg = rtl822x_config_aneg, + .config_init = rtl8221b_config_init, ++ .probe = rtl822x_probe, + .read_status = rtl822x_read_status, + .suspend = genphy_suspend, + .resume = rtlgen_resume, diff --git a/target/linux/generic/pending-6.1/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 deleted file mode 100644 index d185aed7b..000000000 --- a/target/linux/generic/pending-6.1/730-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 95dcd0f223d7cab6e25bc19088016e5eb4ca1804 Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Tue, 16 Aug 2022 00:22:11 +0200 -Subject: [PATCH 10/10] mtk_sgmii: enable PCS polling to allow SFP work - -Currently there is no IRQ handling (even the SGMII supports it). -Enable polling to support SFP ports. - -Signed-off-by: Alexander Couzens ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -182,6 +182,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - return PTR_ERR(ss->pcs[i].regmap); - - ss->pcs[i].pcs.ops = &mtk_pcs_ops; -+ ss->pcs[i].pcs.poll = 1; - } - - return 0; diff --git a/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch new file mode 100644 index 000000000..ac3855515 --- /dev/null +++ b/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch @@ -0,0 +1,63 @@ +From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 30 Apr 2023 00:15:41 +0100 +Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B + +Early versions (?) of the RTL8221B PHY cannot be identified in a regular +Clause-45 bus scan as the PHY doesn't report the implemented MMDs +correctly but returns 0 instead. +Implement custom identify function using the PKGID instead of iterating +over the implemented MMDs. + +Signed-off-by: Daniel Golle + +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -752,6 +752,38 @@ static int rtl8226_match_phy_device(stru + rtlgen_supports_2_5gbps(phydev); + } + ++static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev) ++{ ++ int val; ++ u32 id; ++ ++ if (phydev->mdio.bus->probe_capabilities >= MDIOBUS_C45) { ++ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1); ++ if (val < 0) ++ return 0; ++ ++ id = val << 16; ++ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2); ++ if (val < 0) ++ return 0; ++ ++ id |= val; ++ } else { ++ val = phy_read(phydev, MII_PHYSID1); ++ if (val < 0) ++ return 0; ++ ++ id = val << 16; ++ val = phy_read(phydev, MII_PHYSID2); ++ if (val < 0) ++ return 0; ++ ++ id |= val; ++ } ++ ++ return (id == 0x001cc849); ++} ++ + static int rtl822x_probe(struct phy_device *phydev) + { + struct device *dev = &phydev->mdio.dev; +@@ -1104,7 +1136,7 @@ static struct phy_driver realtek_drvs[] + .write_page = rtl821x_write_page, + .soft_reset = genphy_soft_reset, + }, { +- PHY_ID_MATCH_EXACT(0x001cc849), ++ .match_phy_device = rtl8221b_vb_cg_match_phy_device, + .name = "RTL8221B-VB-CG 2.5Gbps PHY", + .get_features = rtl822x_get_features, + .config_init = rtl8221b_config_init, diff --git a/target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch b/target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch new file mode 100644 index 000000000..e18b1d0ee --- /dev/null +++ b/target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch @@ -0,0 +1,428 @@ +From patchwork Wed Nov 2 00:58:01 2022 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Daniel Golle +X-Patchwork-Id: 13027653 +X-Patchwork-Delegate: kuba@kernel.org +Return-Path: +Date: Wed, 2 Nov 2022 00:58:01 +0000 +From: Daniel Golle +To: Felix Fietkau , John Crispin , + Sean Wang , + Mark Lee , + "David S. Miller" , + Eric Dumazet , + Jakub Kicinski , + Paolo Abeni , + Matthias Brugger , + netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, + linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org +Subject: [PATCH v4] net: ethernet: mediatek: ppe: add support for flow + accounting +Message-ID: +MIME-Version: 1.0 +Content-Disposition: inline +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +The PPE units found in MT7622 and newer support packet and byte +accounting of hw-offloaded flows. Add support for reading those +counters as found in MediaTek's SDK[1]. + +[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92 +Signed-off-by: Daniel Golle +--- +v4: declare function mtk_mib_entry_read as static +v3: don't bother to set 'false' values in any zero-initialized struct + use mtk_foe_entry_ib2 + both changes were requested by Felix Fietkau + +v2: fix wrong variable name in return value check spotted by Denis Kirjanov + + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + + drivers/net/ethernet/mediatek/mtk_ppe.c | 110 +++++++++++++++++- + drivers/net/ethernet/mediatek/mtk_ppe.h | 23 +++- + .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +- + .../net/ethernet/mediatek/mtk_ppe_offload.c | 7 ++ + drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +++ + 7 files changed, 166 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4696,8 +4696,8 @@ static int mtk_probe(struct platform_dev + for (i = 0; i < num_ppe; i++) { + u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; + +- eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, +- eth->soc->offload_version, i); ++ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i); ++ + if (!eth->ppe[i]) { + err = -ENOMEM; + goto err_deinit_ppe; +@@ -4823,6 +4823,7 @@ static const struct mtk_soc_data mt7622_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 2, ++ .has_accounting = true, + .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), +@@ -4860,6 +4861,7 @@ static const struct mtk_soc_data mt7629_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7629_CLKS_BITMAP, + .required_pctl = false, ++ .has_accounting = true, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4880,6 +4882,7 @@ static const struct mtk_soc_data mt7981_ + .offload_version = 2, + .hash_offset = 4, + .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .has_accounting = true, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +@@ -4899,6 +4902,7 @@ static const struct mtk_soc_data mt7986_ + .required_pctl = false, + .hash_offset = 4, + .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .has_accounting = true, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1017,6 +1017,8 @@ struct mtk_reg_map { + * the extra setup for those pins used by GMAC. + * @hash_offset Flow table hash offset. + * @foe_entry_size Foe table entry size. ++ * @has_accounting Bool indicating support for accounting of ++ * offloaded flows. + * @txd_size Tx DMA descriptor size. + * @rxd_size Rx DMA descriptor size. + * @rx_irq_done_mask Rx irq done register mask. +@@ -1034,6 +1036,7 @@ struct mtk_soc_data { + u8 hash_offset; + u16 foe_entry_size; + netdev_features_t hw_features; ++ bool has_accounting; + struct { + u32 txd_size; + u32 rxd_size; +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_ + return ret; + } + ++static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe) ++{ ++ int ret; ++ u32 val; ++ ++ ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val, ++ !(val & MTK_PPE_MIB_SER_CR_ST), ++ 20, MTK_PPE_WAIT_TIMEOUT_US); ++ ++ if (ret) ++ dev_err(ppe->dev, "MIB table busy"); ++ ++ return ret; ++} ++ ++static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) ++{ ++ u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; ++ u32 val, cnt_r0, cnt_r1, cnt_r2; ++ int ret; ++ ++ val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST; ++ ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val); ++ ++ ret = mtk_ppe_mib_wait_busy(ppe); ++ if (ret) ++ return ret; ++ ++ cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); ++ cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); ++ cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2); ++ ++ byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); ++ byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); ++ pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); ++ pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); ++ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; ++ *packets = (pkt_cnt_high << 16) | pkt_cnt_low; ++ ++ return 0; ++} ++ + static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) + { + ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR); +@@ -459,6 +501,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); + dma_wmb(); + mtk_ppe_cache_clear(ppe); ++ if (ppe->accounting) { ++ struct mtk_foe_accounting *acct; ++ ++ acct = ppe->acct_table + entry->hash * sizeof(*acct); ++ acct->packets = 0; ++ acct->bytes = 0; ++ } + } + entry->hash = 0xffff; + +@@ -566,6 +615,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + wmb(); + hwe->ib1 = entry->ib1; + ++ if (ppe->accounting) ++ *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT; ++ + dma_wmb(); + + mtk_ppe_cache_clear(ppe); +@@ -757,11 +809,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe + return mtk_ppe_wait_busy(ppe); + } + +-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, +- int version, int index) ++struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, ++ struct mtk_foe_accounting *diff) ++{ ++ struct mtk_foe_accounting *acct; ++ int size = sizeof(struct mtk_foe_accounting); ++ u64 bytes, packets; ++ ++ if (!ppe->accounting) ++ return NULL; ++ ++ if (mtk_mib_entry_read(ppe, index, &bytes, &packets)) ++ return NULL; ++ ++ acct = ppe->acct_table + index * size; ++ ++ acct->bytes += bytes; ++ acct->packets += packets; ++ ++ if (diff) { ++ diff->bytes = bytes; ++ diff->packets = packets; ++ } ++ ++ return acct; ++} ++ ++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) + { ++ bool accounting = eth->soc->has_accounting; + const struct mtk_soc_data *soc = eth->soc; ++ struct mtk_foe_accounting *acct; + struct device *dev = eth->dev; ++ struct mtk_mib_entry *mib; + struct mtk_ppe *ppe; + u32 foe_flow_size; + void *foe; +@@ -778,7 +858,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + ppe->base = base; + ppe->eth = eth; + ppe->dev = dev; +- ppe->version = version; ++ ppe->version = eth->soc->offload_version; ++ ppe->accounting = accounting; + + foe = dmam_alloc_coherent(ppe->dev, + MTK_PPE_ENTRIES * soc->foe_entry_size, +@@ -794,6 +875,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + if (!ppe->foe_flow) + goto err_free_l2_flows; + ++ if (accounting) { ++ mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib), ++ &ppe->mib_phys, GFP_KERNEL); ++ if (!mib) ++ return NULL; ++ ++ ppe->mib_table = mib; ++ ++ acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct), ++ GFP_KERNEL); ++ ++ if (!acct) ++ return NULL; ++ ++ ppe->acct_table = acct; ++ } ++ + mtk_ppe_debugfs_init(ppe, index); + + return ppe; +@@ -923,6 +1021,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); + ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); + } ++ ++ if (ppe->accounting && ppe->mib_phys) { ++ ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys); ++ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN, ++ MTK_PPE_MIB_CFG_EN); ++ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR, ++ MTK_PPE_MIB_CFG_RD_CLR); ++ ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN, ++ MTK_PPE_MIB_CFG_RD_CLR); ++ } + } + + int mtk_ppe_stop(struct mtk_ppe *ppe) +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -57,6 +57,7 @@ enum { + #define MTK_FOE_IB2_MULTICAST BIT(8) + + #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12) ++#define MTK_FOE_IB2_MIB_CNT BIT(15) + #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16) + #define MTK_FOE_IB2_WDMA_WINFO BIT(17) + +@@ -285,16 +286,34 @@ struct mtk_flow_entry { + unsigned long cookie; + }; + ++struct mtk_mib_entry { ++ u32 byt_cnt_l; ++ u16 byt_cnt_h; ++ u32 pkt_cnt_l; ++ u8 pkt_cnt_h; ++ u8 _rsv0; ++ u32 _rsv1; ++} __packed; ++ ++struct mtk_foe_accounting { ++ u64 bytes; ++ u64 packets; ++}; ++ + struct mtk_ppe { + struct mtk_eth *eth; + struct device *dev; + void __iomem *base; + int version; + char dirname[5]; ++ bool accounting; + + void *foe_table; + dma_addr_t foe_phys; + ++ struct mtk_mib_entry *mib_table; ++ dma_addr_t mib_phys; ++ + u16 foe_check_time[MTK_PPE_ENTRIES]; + struct hlist_head *foe_flow; + +@@ -303,8 +322,7 @@ struct mtk_ppe { + void *acct_table; + }; + +-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, +- int version, int index); ++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index); + void mtk_ppe_deinit(struct mtk_eth *eth); + void mtk_ppe_start(struct mtk_ppe *ppe); + int mtk_ppe_stop(struct mtk_ppe *ppe); +@@ -359,5 +377,7 @@ int mtk_foe_entry_commit(struct mtk_ppe + 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); + int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); ++struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, ++ struct mtk_foe_accounting *diff); + + #endif +--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file + struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i); + struct mtk_foe_mac_info *l2; + struct mtk_flow_addr_info ai = {}; ++ struct mtk_foe_accounting *acct; + unsigned char h_source[ETH_ALEN]; + unsigned char h_dest[ETH_ALEN]; + int type, state; +@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file + if (bind && state != MTK_FOE_STATE_BIND) + continue; + ++ acct = mtk_foe_entry_get_mib(ppe, i, NULL); ++ + type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); + seq_printf(m, "%05x %s %7s", i, + mtk_foe_entry_state_str(state), +@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file + *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo); + + seq_printf(m, " eth=%pM->%pM etype=%04x" +- " vlan=%d,%d ib1=%08x ib2=%08x\n", ++ " vlan=%d,%d ib1=%08x ib2=%08x" ++ " packets=%llu bytes=%llu\n", + h_source, h_dest, ntohs(l2->etype), +- l2->vlan1, l2->vlan2, entry->ib1, ib2); ++ l2->vlan1, l2->vlan2, entry->ib1, ib2, ++ acct ? acct->packets : 0, acct ? acct->bytes : 0); + } + + return 0; +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -497,6 +497,7 @@ static int + mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) + { + struct mtk_flow_entry *entry; ++ struct mtk_foe_accounting diff; + u32 idle; + + entry = rhashtable_lookup(ð->flow_table, &f->cookie, +@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e + idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); + f->stats.lastused = jiffies - idle * HZ; + ++ if (entry->hash != 0xFFFF && ++ mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash, ++ &diff)) { ++ f->stats.pkts += diff.packets; ++ f->stats.bytes += diff.bytes; ++ } ++ + return 0; + } + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +@@ -149,6 +149,20 @@ enum { + + #define MTK_PPE_MIB_TB_BASE 0x338 + ++#define MTK_PPE_MIB_SER_CR 0x33C ++#define MTK_PPE_MIB_SER_CR_ST BIT(16) ++#define MTK_PPE_MIB_SER_CR_ADDR GENMASK(13, 0) ++ ++#define MTK_PPE_MIB_SER_R0 0x340 ++#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW GENMASK(31, 0) ++ ++#define MTK_PPE_MIB_SER_R1 0x344 ++#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW GENMASK(31, 16) ++#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH GENMASK(15, 0) ++ ++#define MTK_PPE_MIB_SER_R2 0x348 ++#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0) ++ + #define MTK_PPE_MIB_CACHE_CTL 0x350 + #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) + #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) 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 index 1cd036629..d1203d76c 100644 --- 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 @@ -17,7 +17,7 @@ Signed-off-by: Christian Marangi --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2171,7 +2171,7 @@ struct net_device { +@@ -2170,7 +2170,7 @@ struct net_device { #if IS_ENABLED(CONFIG_AX25) void *ax25_ptr; #endif 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-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch similarity index 75% rename from target/linux/generic/pending-6.1/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch rename to target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch index ab2ea7c1c..e55375f3a 100644 --- 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-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch @@ -17,27 +17,42 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2042,29 +2042,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); +@@ -1898,9 +1898,7 @@ static int mtk_poll_rx(struct napi_struc + while (done < budget) { + unsigned int pktlen, *rxdcsum; +- bool has_hwaccel_tag = false; + struct net_device *netdev; +- u16 vlan_proto, vlan_tci; + dma_addr_t dma_addr; + u32 hash, reason; + int mac = 0; +@@ -2035,36 +2033,21 @@ static int mtk_poll_rx(struct napi_struc + skb_checksum_none_assert(skb); + skb->protocol = eth_type_trans(skb, netdev); + +- 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)); +- if (trxd.rxd3 & RX_DMA_VTAG_V2) { +- vlan_proto = RX_DMA_VPID(trxd.rxd4); +- vlan_tci = RX_DMA_VID(trxd.rxd4); +- has_hwaccel_tag = true; +- } - } else if (trxd.rxd2 & RX_DMA_VTAG) { -- __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)), -- RX_DMA_VID(trxd.rxd3)); +- vlan_proto = RX_DMA_VPID(trxd.rxd3); +- vlan_tci = RX_DMA_VID(trxd.rxd3); +- has_hwaccel_tag = true; - } - } - /* 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 (has_hwaccel_tag && netdev_uses_dsa(netdev)) { +- unsigned int port = 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); @@ -45,12 +60,17 @@ Signed-off-by: Felix Fietkau 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); +- } else if (has_hwaccel_tag) { +- __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci); } ++ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) ++ mtk_ppe_check_skb(eth->ppe[0], skb, hash); ++ skb_record_rx_queue(skb, 0); -@@ -2889,29 +2876,11 @@ static netdev_features_t mtk_fix_feature + napi_gro_receive(napi, skb); + +@@ -2887,29 +2870,11 @@ static netdev_features_t mtk_fix_feature static int mtk_set_features(struct net_device *dev, netdev_features_t features) { @@ -80,7 +100,7 @@ Signed-off-by: Felix Fietkau return 0; } -@@ -3210,30 +3179,6 @@ static int mtk_open(struct net_device *d +@@ -3223,30 +3188,6 @@ static int mtk_open(struct net_device *d struct mtk_eth *eth = mac->hw; int i, err; @@ -111,7 +131,7 @@ Signed-off-by: Felix Fietkau err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); if (err) { netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3272,6 +3217,35 @@ static int mtk_open(struct net_device *d +@@ -3285,6 +3226,35 @@ static int mtk_open(struct net_device *d phylink_start(mac->phylink); netif_tx_start_all_queues(dev); @@ -147,7 +167,7 @@ Signed-off-by: Felix Fietkau return 0; } -@@ -3598,10 +3572,9 @@ static int mtk_hw_init(struct mtk_eth *e +@@ -3769,10 +3739,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); @@ -160,7 +180,7 @@ Signed-off-by: Felix Fietkau /* set interrupt delays based on current Net DIM sample */ mtk_dim_rx(ð->rx_dim.work); -@@ -4205,7 +4178,7 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4419,7 +4388,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 & @@ -176,6 +196,6 @@ Signed-off-by: Felix Fietkau NETIF_F_RXCSUM | \ NETIF_F_HW_VLAN_CTAG_TX | \ - NETIF_F_HW_VLAN_CTAG_RX | \ - NETIF_F_SG | NETIF_F_ALL_TSO | \ + NETIF_F_SG | NETIF_F_TSO | \ + NETIF_F_TSO6 | \ NETIF_F_IPV6_CSUM |\ - NETIF_F_HW_TC) 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-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch similarity index 54% rename from target/linux/generic/pending-6.1/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch rename to target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch index ec7cd02f0..c0a5a93a4 100644 --- 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-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch @@ -1,19 +1,22 @@ 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 +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 +When lots of frames are sent with a number of very small fragments, an +internal FIFO can overflow, causing the DMA engine to lock up lock up and +transmit attempts time out. + +Fix this on MT7986 by increasing the reserved FIFO space. +Fix this on older chips 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 -@@ -1443,12 +1443,28 @@ static void mtk_wake_queue(struct mtk_et +@@ -1469,12 +1469,28 @@ static void mtk_wake_queue(struct mtk_et } } @@ -42,11 +45,12 @@ Signed-off-by: Felix Fietkau bool gso = false; int tx_num; -@@ -1470,6 +1486,17 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1496,6 +1512,18 @@ static netdev_tx_t mtk_start_xmit(struct return NETDEV_TX_BUSY; } -+ if (skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && ++ 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; @@ -60,19 +64,31 @@ Signed-off-by: Felix Fietkau /* TSO: fill MSS info in tcp checksum field */ if (skb_is_gso(skb)) { if (skb_cow_head(skb, 0)) { -@@ -1485,8 +1512,13 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1511,8 +1539,14 @@ 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)) || ++ if ((!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && ++ 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); ++ stats->tx_dropped++; ++ dev_kfree_skb_any(skb); + } + } if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) netif_tx_stop_all_queues(dev); +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -258,7 +258,7 @@ + #define MTK_CHK_DDONE_EN BIT(28) + #define MTK_DMAD_WR_WDONE BIT(26) + #define MTK_WCOMP_EN BIT(24) +-#define MTK_RESV_BUF (0x40 << 16) ++#define MTK_RESV_BUF (0x80 << 16) + #define MTK_MUTLI_CNT (0x4 << 12) + #define MTK_LEAKY_BUCKET_EN BIT(11) + 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-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch similarity index 90% rename from target/linux/generic/pending-6.1/732-11-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch rename to target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch index f89ad6adb..3c6359ee4 100644 --- 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-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch @@ -9,10 +9,10 @@ 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 @@ +@@ -48,8 +48,7 @@ + #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_TSO | \ - NETIF_F_TSO6 | \ + NETIF_F_SG | NETIF_F_ALL_TSO | \ diff --git a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch b/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch new file mode 100644 index 000000000..77973180f --- /dev/null +++ b/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch @@ -0,0 +1,42 @@ +From: Felix Fietkau +Date: Wed, 29 Mar 2023 16:02:54 +0200 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix remaining throughput + regression + +Based on further tests, it seems that the QDMA shaper is not able to +perform shaping close to the MAC link rate without throughput loss. +This cannot be compensated by increasing the shaping rate, so it seems +to be an internal limit. + +Fix the remaining throughput regression by detecting that condition and +limiting shaping to ports with lower link speed. + +This patch intentionally ignores link speed gain from TRGMII, because +even on such links, shaping to 1000 Mbit/s incurs some throughput +degradation. + +Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues") +Reported-by: Frank Wunderlich +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -710,6 +710,7 @@ static void mtk_mac_link_up(struct phyli + MAC_MCR_FORCE_RX_FC); + + /* Configure speed */ ++ mac->speed = speed; + switch (speed) { + case SPEED_2500: + case SPEED_1000: +@@ -3201,6 +3202,9 @@ found: + if (dp->index >= MTK_QDMA_NUM_QUEUES) + return NOTIFY_DONE; + ++ if (mac->speed > 0 && mac->speed <= s.base.speed) ++ s.base.speed = 0; ++ + mtk_set_queue_speed(eth, dp->index + 3, s.base.speed); + + return NOTIFY_DONE; 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 deleted file mode 100644 index 429e5fe78..000000000 --- a/target/linux/generic/pending-6.1/732-13-net-ethernet-mtk_eth_soc-fix-flow_offload-related-re.patch +++ /dev/null @@ -1,52 +0,0 @@ -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,17 +569,19 @@ 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; -- } -- block_cb = flow_block_cb_alloc(cb, dev, dev, NULL); -- if (IS_ERR(block_cb)) -- return PTR_ERR(block_cb); -+ 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; -+ } - flow_block_cb_incref(block_cb); -- flow_block_cb_add(block_cb, f); -- list_add_tail(&block_cb->driver_list, &block_cb_list); -+ -+ 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/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch b/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch new file mode 100644 index 000000000..dc2163959 --- /dev/null +++ b/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch @@ -0,0 +1,33 @@ +From: Felix Fietkau +Date: Tue, 27 Dec 2022 15:02:51 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: ppe: fix L2 offloading with DSA + untagging offload enabled + +Check for skb metadata in order to detect the case where the DSA header is not +present. + +Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include "mtk_eth_soc.h" + #include "mtk_ppe.h" +@@ -752,7 +753,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe + skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) + goto out; + +- tag += 4; ++ if (!skb_metadata_dst(skb)) ++ tag += 4; ++ + if (get_unaligned_be16(tag) != ETH_P_8021Q) + break; + diff --git a/target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch b/target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch new file mode 100644 index 000000000..c5654a606 --- /dev/null +++ b/target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch @@ -0,0 +1,266 @@ +From: Felix Fietkau +Date: Mon, 20 Mar 2023 11:44:30 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add code for offloading flows + from wlan devices + +WED version 2 (on MT7986 and later) can offload flows originating from wireless +devices. In order to make that work, ndo_setup_tc needs to be implemented on +the netdevs. This adds the required code to offload flows coming in from WED, +while keeping track of the incoming wed index used for selecting the correct +PPE device. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1280,6 +1280,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk + int mtk_eth_offload_init(struct mtk_eth *eth); + int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, + void *type_data); ++int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, ++ int ppe_index); ++void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); + void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); + + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -235,7 +235,8 @@ out: + } + + static int +-mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f) ++mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f, ++ int ppe_index) + { + struct flow_rule *rule = flow_cls_offload_flow_rule(f); + struct flow_action_entry *act; +@@ -452,6 +453,7 @@ mtk_flow_offload_replace(struct mtk_eth + entry->cookie = f->cookie; + memcpy(&entry->data, &foe, sizeof(entry->data)); + entry->wed_index = wed_index; ++ entry->ppe_index = ppe_index; + + err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry); + if (err < 0) +@@ -520,25 +522,15 @@ mtk_flow_offload_stats(struct mtk_eth *e + + static DEFINE_MUTEX(mtk_flow_offload_mutex); + +-static int +-mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) ++int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, ++ int ppe_index) + { +- struct flow_cls_offload *cls = type_data; +- struct net_device *dev = cb_priv; +- struct mtk_mac *mac = netdev_priv(dev); +- struct mtk_eth *eth = mac->hw; + int err; + +- if (!tc_can_offload(dev)) +- return -EOPNOTSUPP; +- +- if (type != TC_SETUP_CLSFLOWER) +- return -EOPNOTSUPP; +- + mutex_lock(&mtk_flow_offload_mutex); + switch (cls->command) { + case FLOW_CLS_REPLACE: +- err = mtk_flow_offload_replace(eth, cls); ++ err = mtk_flow_offload_replace(eth, cls, ppe_index); + break; + case FLOW_CLS_DESTROY: + err = mtk_flow_offload_destroy(eth, cls); +@@ -556,6 +548,23 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_ + } + + static int ++mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) ++{ ++ struct flow_cls_offload *cls = type_data; ++ struct net_device *dev = cb_priv; ++ struct mtk_mac *mac = netdev_priv(dev); ++ struct mtk_eth *eth = mac->hw; ++ ++ if (!tc_can_offload(dev)) ++ return -EOPNOTSUPP; ++ ++ if (type != TC_SETUP_CLSFLOWER) ++ return -EOPNOTSUPP; ++ ++ return mtk_flow_offload_cmd(eth, cls, 0); ++} ++ ++static int + mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f) + { + struct mtk_mac *mac = netdev_priv(dev); +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -13,6 +13,8 @@ + #include + #include + #include ++#include ++#include + #include "mtk_eth_soc.h" + #include "mtk_wed_regs.h" + #include "mtk_wed.h" +@@ -41,6 +43,11 @@ + static struct mtk_wed_hw *hw_list[2]; + static DEFINE_MUTEX(hw_lock); + ++struct mtk_wed_flow_block_priv { ++ struct mtk_wed_hw *hw; ++ struct net_device *dev; ++}; ++ + static void + wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) + { +@@ -1745,6 +1752,99 @@ out: + mutex_unlock(&hw_lock); + } + ++static int ++mtk_wed_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) ++{ ++ struct mtk_wed_flow_block_priv *priv = cb_priv; ++ struct flow_cls_offload *cls = type_data; ++ struct mtk_wed_hw *hw = priv->hw; ++ ++ if (!tc_can_offload(priv->dev)) ++ return -EOPNOTSUPP; ++ ++ if (type != TC_SETUP_CLSFLOWER) ++ return -EOPNOTSUPP; ++ ++ return mtk_flow_offload_cmd(hw->eth, cls, hw->index); ++} ++ ++static int ++mtk_wed_setup_tc_block(struct mtk_wed_hw *hw, struct net_device *dev, ++ struct flow_block_offload *f) ++{ ++ struct mtk_wed_flow_block_priv *priv; ++ static LIST_HEAD(block_cb_list); ++ struct flow_block_cb *block_cb; ++ struct mtk_eth *eth = hw->eth; ++ flow_setup_cb_t *cb; ++ ++ if (!eth->soc->offload_version) ++ return -EOPNOTSUPP; ++ ++ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) ++ return -EOPNOTSUPP; ++ ++ cb = mtk_wed_setup_tc_block_cb; ++ f->driver_block_list = &block_cb_list; ++ ++ 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; ++ } ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->hw = hw; ++ priv->dev = dev; ++ block_cb = flow_block_cb_alloc(cb, dev, priv, NULL); ++ if (IS_ERR(block_cb)) { ++ kfree(priv); ++ return PTR_ERR(block_cb); ++ } ++ ++ flow_block_cb_incref(block_cb); ++ 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); ++ if (!block_cb) ++ return -ENOENT; ++ ++ if (!flow_block_cb_decref(block_cb)) { ++ flow_block_cb_remove(block_cb, f); ++ list_del(&block_cb->driver_list); ++ kfree(block_cb->cb_priv); ++ } ++ return 0; ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int ++mtk_wed_setup_tc(struct mtk_wed_device *wed, struct net_device *dev, ++ enum tc_setup_type type, void *type_data) ++{ ++ struct mtk_wed_hw *hw = wed->hw; ++ ++ if (hw->version < 2) ++ return -EOPNOTSUPP; ++ ++ switch (type) { ++ case TC_SETUP_BLOCK: ++ case TC_SETUP_FT: ++ return mtk_wed_setup_tc_block(hw, dev, type_data); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ + void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, + void __iomem *wdma, phys_addr_t wdma_phy, + int index) +@@ -1764,6 +1864,7 @@ void mtk_wed_add_hw(struct device_node * + .irq_set_mask = mtk_wed_irq_set_mask, + .detach = mtk_wed_detach, + .ppe_check = mtk_wed_ppe_check, ++ .setup_tc = mtk_wed_setup_tc, + }; + struct device_node *eth_np = eth->dev->of_node; + struct platform_device *pdev; +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #define MTK_WED_TX_QUEUES 2 + #define MTK_WED_RX_QUEUES 2 +@@ -180,6 +181,8 @@ struct mtk_wed_ops { + + u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask); + void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); ++ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, ++ enum tc_setup_type type, void *type_data); + }; + + extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; +@@ -238,6 +241,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic + (_dev)->ops->msg_update(_dev, _id, _msg, _len) + #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) + #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) ++#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ ++ (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) + #else + static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) + { +@@ -256,6 +261,7 @@ static inline bool mtk_wed_device_active + #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV + #define mtk_wed_device_stop(_dev) do {} while (0) + #define mtk_wed_device_dma_reset(_dev) do {} while (0) ++#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP + #endif + + #endif diff --git a/target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch b/target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch new file mode 100644 index 000000000..08036e0b1 --- /dev/null +++ b/target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch @@ -0,0 +1,37 @@ +From: Felix Fietkau +Date: Mon, 20 Mar 2023 15:37:55 +0100 +Subject: [PATCH] net: ethernet: mediatek: mtk_ppe: prefer newly added l2 + flows over existing ones + +When a device is roaming between interfaces and a new flow entry is created, +we should assume that its output device is more up to date than whatever +entry existed already. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -634,10 +634,20 @@ void mtk_foe_entry_clear(struct mtk_ppe + static int + mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { ++ struct mtk_flow_entry *prev; ++ + entry->type = MTK_FLOW_TYPE_L2; + +- return rhashtable_insert_fast(&ppe->l2_flows, &entry->l2_node, +- mtk_flow_l2_ht_params); ++ prev = rhashtable_lookup_get_insert_fast(&ppe->l2_flows, &entry->l2_node, ++ mtk_flow_l2_ht_params); ++ if (likely(!prev)) ++ return 0; ++ ++ if (IS_ERR(prev)) ++ return PTR_ERR(prev); ++ ++ return rhashtable_replace_fast(&ppe->l2_flows, &prev->l2_node, ++ &entry->l2_node, mtk_flow_l2_ht_params); + } + + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) diff --git a/target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch b/target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch new file mode 100644 index 000000000..ec04fb354 --- /dev/null +++ b/target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch @@ -0,0 +1,331 @@ +From: Felix Fietkau +Date: Thu, 23 Mar 2023 10:24:11 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: improve keeping track of + offloaded flows + +Unify tracking of L2 and L3 flows. Use the generic list field in struct +mtk_foe_entry for tracking L2 subflows. Preparation for improving +flow accounting support. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -460,42 +460,43 @@ int mtk_foe_entry_set_queue(struct mtk_e + return 0; + } + ++static int ++mtk_flow_entry_match_len(struct mtk_eth *eth, struct mtk_foe_entry *entry) ++{ ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); ++ ++ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) ++ return offsetof(struct mtk_foe_entry, ipv6._rsv); ++ else ++ return offsetof(struct mtk_foe_entry, ipv4.ib2); ++} ++ + static bool + mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, +- struct mtk_foe_entry *data) ++ struct mtk_foe_entry *data, int len) + { +- int type, len; +- + if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) + return false; + +- type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); +- if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) +- len = offsetof(struct mtk_foe_entry, ipv6._rsv); +- else +- len = offsetof(struct mtk_foe_entry, ipv4.ib2); +- + return !memcmp(&entry->data.data, &data->data, len - 4); + } + + static void +-__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) ++__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, ++ bool set_state) + { +- struct hlist_head *head; + struct hlist_node *tmp; + + if (entry->type == MTK_FLOW_TYPE_L2) { + rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node, + mtk_flow_l2_ht_params); + +- head = &entry->l2_flows; +- hlist_for_each_entry_safe(entry, tmp, head, l2_data.list) +- __mtk_foe_entry_clear(ppe, entry); ++ hlist_for_each_entry_safe(entry, tmp, &entry->l2_flows, l2_list) ++ __mtk_foe_entry_clear(ppe, entry, set_state); + return; + } + +- hlist_del_init(&entry->list); +- if (entry->hash != 0xffff) { ++ if (entry->hash != 0xffff && set_state) { + struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); + + hwe->ib1 &= ~MTK_FOE_IB1_STATE; +@@ -515,7 +516,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW) + return; + +- hlist_del_init(&entry->l2_data.list); ++ hlist_del_init(&entry->l2_list); ++ hlist_del_init(&entry->list); + kfree(entry); + } + +@@ -531,66 +533,55 @@ static int __mtk_foe_entry_idle_time(str + return now - timestamp; + } + ++static bool ++mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) ++{ ++ struct mtk_foe_entry foe = {}; ++ struct mtk_foe_entry *hwe; ++ u16 hash = entry->hash; ++ int len; ++ ++ if (hash == 0xffff) ++ return false; ++ ++ hwe = mtk_foe_get_entry(ppe, hash); ++ len = mtk_flow_entry_match_len(ppe->eth, &entry->data); ++ memcpy(&foe, hwe, len); ++ ++ if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || ++ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) ++ return false; ++ ++ entry->data.ib1 = foe.ib1; ++ ++ return true; ++} ++ + static void + mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { + u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); + struct mtk_flow_entry *cur; +- struct mtk_foe_entry *hwe; + struct hlist_node *tmp; + int idle; + + idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); +- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) { ++ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { + int cur_idle; +- u32 ib1; +- +- hwe = mtk_foe_get_entry(ppe, cur->hash); +- ib1 = READ_ONCE(hwe->ib1); + +- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) { +- cur->hash = 0xffff; +- __mtk_foe_entry_clear(ppe, cur); ++ if (!mtk_flow_entry_update(ppe, cur)) { ++ __mtk_foe_entry_clear(ppe, entry, false); + continue; + } + +- cur_idle = __mtk_foe_entry_idle_time(ppe, ib1); ++ cur_idle = __mtk_foe_entry_idle_time(ppe, cur->data.ib1); + if (cur_idle >= idle) + continue; + + idle = cur_idle; + entry->data.ib1 &= ~ib1_ts_mask; +- entry->data.ib1 |= hwe->ib1 & ib1_ts_mask; +- } +-} +- +-static void +-mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) +-{ +- struct mtk_foe_entry foe = {}; +- struct mtk_foe_entry *hwe; +- +- spin_lock_bh(&ppe_lock); +- +- if (entry->type == MTK_FLOW_TYPE_L2) { +- mtk_flow_entry_update_l2(ppe, entry); +- goto out; ++ entry->data.ib1 |= cur->data.ib1 & ib1_ts_mask; + } +- +- if (entry->hash == 0xffff) +- goto out; +- +- hwe = mtk_foe_get_entry(ppe, entry->hash); +- memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); +- if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { +- entry->hash = 0xffff; +- goto out; +- } +- +- entry->data.ib1 = foe.ib1; +- +-out: +- spin_unlock_bh(&ppe_lock); + } + + static void +@@ -627,7 +618,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { + spin_lock_bh(&ppe_lock); +- __mtk_foe_entry_clear(ppe, entry); ++ __mtk_foe_entry_clear(ppe, entry, true); ++ hlist_del_init(&entry->list); + spin_unlock_bh(&ppe_lock); + } + +@@ -674,8 +666,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ + { + const struct mtk_soc_data *soc = ppe->eth->soc; + struct mtk_flow_entry *flow_info; +- struct mtk_foe_entry foe = {}, *hwe; + struct mtk_foe_mac_info *l2; ++ struct mtk_foe_entry *hwe; + u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; + int type; + +@@ -683,30 +675,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ + if (!flow_info) + return; + +- flow_info->l2_data.base_flow = entry; + flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW; + flow_info->hash = hash; + hlist_add_head(&flow_info->list, + &ppe->foe_flow[hash / soc->hash_offset]); +- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); ++ hlist_add_head(&flow_info->l2_list, &entry->l2_flows); + + hwe = mtk_foe_get_entry(ppe, hash); +- memcpy(&foe, hwe, soc->foe_entry_size); +- foe.ib1 &= ib1_mask; +- foe.ib1 |= entry->data.ib1 & ~ib1_mask; ++ memcpy(&flow_info->data, hwe, soc->foe_entry_size); ++ flow_info->data.ib1 &= ib1_mask; ++ flow_info->data.ib1 |= entry->data.ib1 & ~ib1_mask; + +- l2 = mtk_foe_entry_l2(ppe->eth, &foe); ++ l2 = mtk_foe_entry_l2(ppe->eth, &flow_info->data); + memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); + +- type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); ++ type = mtk_get_ib1_pkt_type(ppe->eth, flow_info->data.ib1); + if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) +- memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); ++ memcpy(&flow_info->data.ipv4.new, &flow_info->data.ipv4.orig, ++ sizeof(flow_info->data.ipv4.new)); + else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) + l2->etype = ETH_P_IPV6; + +- *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; ++ *mtk_foe_entry_ib2(ppe->eth, &flow_info->data) = entry->data.bridge.ib2; + +- __mtk_foe_entry_commit(ppe, &foe, hash); ++ __mtk_foe_entry_commit(ppe, &flow_info->data, hash); + } + + void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) +@@ -716,9 +708,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe + struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); + struct mtk_flow_entry *entry; + struct mtk_foe_bridge key = {}; ++ struct mtk_foe_entry foe = {}; + struct hlist_node *n; + struct ethhdr *eh; + bool found = false; ++ int entry_len; + u8 *tag; + + spin_lock_bh(&ppe_lock); +@@ -726,20 +720,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe + if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) + goto out; + +- hlist_for_each_entry_safe(entry, n, head, list) { +- if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) { +- if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == +- MTK_FOE_STATE_BIND)) +- continue; +- +- entry->hash = 0xffff; +- __mtk_foe_entry_clear(ppe, entry); +- continue; +- } ++ entry_len = mtk_flow_entry_match_len(ppe->eth, hwe); ++ memcpy(&foe, hwe, entry_len); + +- if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { ++ hlist_for_each_entry_safe(entry, n, head, list) { ++ if (found || ++ !mtk_flow_entry_match(ppe->eth, entry, &foe, entry_len)) { + if (entry->hash != 0xffff) +- entry->hash = 0xffff; ++ __mtk_foe_entry_clear(ppe, entry, false); + continue; + } + +@@ -790,9 +778,17 @@ out: + + int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { +- mtk_flow_entry_update(ppe, entry); ++ int idle; ++ ++ spin_lock_bh(&ppe_lock); ++ if (entry->type == MTK_FLOW_TYPE_L2) ++ mtk_flow_entry_update_l2(ppe, entry); ++ else ++ mtk_flow_entry_update(ppe, entry); ++ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); ++ spin_unlock_bh(&ppe_lock); + +- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); ++ return idle; + } + + int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -265,7 +265,12 @@ enum { + + struct mtk_flow_entry { + union { +- struct hlist_node list; ++ /* regular flows + L2 subflows */ ++ struct { ++ struct hlist_node list; ++ struct hlist_node l2_list; ++ }; ++ /* L2 flows */ + struct { + struct rhash_head l2_node; + struct hlist_head l2_flows; +@@ -275,13 +280,7 @@ struct mtk_flow_entry { + s8 wed_index; + u8 ppe_index; + u16 hash; +- union { +- struct mtk_foe_entry data; +- struct { +- struct mtk_flow_entry *base_flow; +- struct hlist_node list; +- } l2_data; +- }; ++ struct mtk_foe_entry data; + struct rhash_head node; + unsigned long cookie; + }; diff --git a/target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch b/target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch new file mode 100644 index 000000000..79386d6cf --- /dev/null +++ b/target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch @@ -0,0 +1,333 @@ +From: Felix Fietkau +Date: Thu, 23 Mar 2023 11:05:22 +0100 +Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for L2 + flows + +For L2 flows, the packet/byte counters should report the sum of the +counters of their subflows, both current and expired. +In order to make this work, change the way that accounting data is tracked. +Reset counters when a flow enters bind. Once it expires (or enters unbind), +store the last counter value in struct mtk_flow_entry. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -80,9 +80,9 @@ static int mtk_ppe_mib_wait_busy(struct + int ret; + u32 val; + +- ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val, +- !(val & MTK_PPE_MIB_SER_CR_ST), +- 20, MTK_PPE_WAIT_TIMEOUT_US); ++ ret = readl_poll_timeout_atomic(ppe->base + MTK_PPE_MIB_SER_CR, val, ++ !(val & MTK_PPE_MIB_SER_CR_ST), ++ 20, MTK_PPE_WAIT_TIMEOUT_US); + + if (ret) + dev_err(ppe->dev, "MIB table busy"); +@@ -90,18 +90,32 @@ static int mtk_ppe_mib_wait_busy(struct + return ret; + } + +-static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) ++static inline struct mtk_foe_accounting * ++mtk_ppe_acct_data(struct mtk_ppe *ppe, u16 index) ++{ ++ if (!ppe->acct_table) ++ return NULL; ++ ++ return ppe->acct_table + index * sizeof(struct mtk_foe_accounting); ++} ++ ++struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index) + { + u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; + u32 val, cnt_r0, cnt_r1, cnt_r2; ++ struct mtk_foe_accounting *acct; + int ret; + + val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST; + ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val); + ++ acct = mtk_ppe_acct_data(ppe, index); ++ if (!acct) ++ return NULL; ++ + ret = mtk_ppe_mib_wait_busy(ppe); + if (ret) +- return ret; ++ return acct; + + cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); + cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); +@@ -111,10 +125,11 @@ static int mtk_mib_entry_read(struct mtk + byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); + pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); + pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); +- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; +- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; + +- return 0; ++ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; ++ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low; ++ ++ return acct; + } + + static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) +@@ -503,13 +518,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); + dma_wmb(); + mtk_ppe_cache_clear(ppe); +- if (ppe->accounting) { +- struct mtk_foe_accounting *acct; +- +- acct = ppe->acct_table + entry->hash * sizeof(*acct); +- acct->packets = 0; +- acct->bytes = 0; +- } + } + entry->hash = 0xffff; + +@@ -534,11 +542,14 @@ static int __mtk_foe_entry_idle_time(str + } + + static bool +-mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) ++mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, ++ u64 *packets, u64 *bytes) + { ++ struct mtk_foe_accounting *acct; + struct mtk_foe_entry foe = {}; + struct mtk_foe_entry *hwe; + u16 hash = entry->hash; ++ bool ret = false; + int len; + + if (hash == 0xffff) +@@ -549,18 +560,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp + memcpy(&foe, hwe, len); + + if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || +- FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) +- return false; ++ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) { ++ acct = mtk_ppe_acct_data(ppe, hash); ++ if (acct) { ++ entry->prev_packets += acct->packets; ++ entry->prev_bytes += acct->bytes; ++ } ++ ++ goto out; ++ } + + entry->data.ib1 = foe.ib1; ++ acct = mtk_ppe_mib_entry_read(ppe, hash); ++ ret = true; ++ ++out: ++ if (acct) { ++ *packets += acct->packets; ++ *bytes += acct->bytes; ++ } + +- return true; ++ return ret; + } + + static void + mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { + u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); ++ u64 *packets = &entry->packets; ++ u64 *bytes = &entry->bytes; + struct mtk_flow_entry *cur; + struct hlist_node *tmp; + int idle; +@@ -569,7 +597,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe + hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { + int cur_idle; + +- if (!mtk_flow_entry_update(ppe, cur)) { ++ if (!mtk_flow_entry_update(ppe, cur, packets, bytes)) { ++ entry->prev_packets += cur->prev_packets; ++ entry->prev_bytes += cur->prev_bytes; + __mtk_foe_entry_clear(ppe, entry, false); + continue; + } +@@ -584,10 +614,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe + } + } + ++void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, ++ int *idle) ++{ ++ entry->packets = entry->prev_packets; ++ entry->bytes = entry->prev_bytes; ++ ++ spin_lock_bh(&ppe_lock); ++ ++ if (entry->type == MTK_FLOW_TYPE_L2) ++ mtk_flow_entry_update_l2(ppe, entry); ++ else ++ mtk_flow_entry_update(ppe, entry, &entry->packets, &entry->bytes); ++ ++ *idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); ++ ++ spin_unlock_bh(&ppe_lock); ++} ++ + static void + __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, + u16 hash) + { ++ struct mtk_foe_accounting *acct; + struct mtk_eth *eth = ppe->eth; + u16 timestamp = mtk_eth_timestamp(eth); + struct mtk_foe_entry *hwe; +@@ -612,6 +661,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + + dma_wmb(); + ++ acct = mtk_ppe_mib_entry_read(ppe, hash); ++ if (acct) { ++ acct->packets = 0; ++ acct->bytes = 0; ++ } ++ + mtk_ppe_cache_clear(ppe); + } + +@@ -776,21 +831,6 @@ out: + spin_unlock_bh(&ppe_lock); + } + +-int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) +-{ +- int idle; +- +- spin_lock_bh(&ppe_lock); +- if (entry->type == MTK_FLOW_TYPE_L2) +- mtk_flow_entry_update_l2(ppe, entry); +- else +- mtk_flow_entry_update(ppe, entry); +- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); +- spin_unlock_bh(&ppe_lock); +- +- return idle; +-} +- + int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) + { + if (!ppe) +@@ -818,32 +858,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe + return mtk_ppe_wait_busy(ppe); + } + +-struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, +- struct mtk_foe_accounting *diff) +-{ +- struct mtk_foe_accounting *acct; +- int size = sizeof(struct mtk_foe_accounting); +- u64 bytes, packets; +- +- if (!ppe->accounting) +- return NULL; +- +- if (mtk_mib_entry_read(ppe, index, &bytes, &packets)) +- return NULL; +- +- acct = ppe->acct_table + index * size; +- +- acct->bytes += bytes; +- acct->packets += packets; +- +- if (diff) { +- diff->bytes = bytes; +- diff->packets = packets; +- } +- +- return acct; +-} +- + struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) + { + bool accounting = eth->soc->has_accounting; +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -283,6 +283,8 @@ struct mtk_flow_entry { + struct mtk_foe_entry data; + struct rhash_head node; + unsigned long cookie; ++ u64 prev_packets, prev_bytes; ++ u64 packets, bytes; + }; + + struct mtk_mib_entry { +@@ -326,6 +328,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth) + void mtk_ppe_start(struct mtk_ppe *ppe); + int mtk_ppe_stop(struct mtk_ppe *ppe); + int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); ++struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index); + + void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); + +@@ -374,9 +377,8 @@ int mtk_foe_entry_set_queue(struct mtk_e + 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); + int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); +-struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, +- struct mtk_foe_accounting *diff); ++void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, ++ int *idle); + + #endif +--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +@@ -96,7 +96,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file + if (bind && state != MTK_FOE_STATE_BIND) + continue; + +- acct = mtk_foe_entry_get_mib(ppe, i, NULL); ++ acct = mtk_ppe_mib_entry_read(ppe, i); + + type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); + seq_printf(m, "%05x %s %7s", i, +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -499,24 +499,21 @@ static int + mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) + { + struct mtk_flow_entry *entry; +- struct mtk_foe_accounting diff; +- u32 idle; ++ u64 packets, bytes; ++ int idle; + + entry = rhashtable_lookup(ð->flow_table, &f->cookie, + mtk_flow_ht_params); + if (!entry) + return -ENOENT; + +- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); ++ packets = entry->packets; ++ bytes = entry->bytes; ++ mtk_foe_entry_get_stats(eth->ppe[entry->ppe_index], entry, &idle); ++ f->stats.pkts += entry->packets - packets; ++ f->stats.bytes += entry->bytes - bytes; + f->stats.lastused = jiffies - idle * HZ; + +- if (entry->hash != 0xFFFF && +- mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash, +- &diff)) { +- f->stats.pkts += diff.packets; +- f->stats.bytes += diff.bytes; +- } +- + return 0; + } + diff --git a/target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch new file mode 100644 index 000000000..33c983832 --- /dev/null +++ b/target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch @@ -0,0 +1,51 @@ +From: Felix Fietkau +Date: Thu, 23 Mar 2023 21:45:43 +0100 +Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for v1 + hardware + +Older chips (like MT7622) use a different bit in ib2 to enable hardware +counter support. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -640,6 +640,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + struct mtk_eth *eth = ppe->eth; + u16 timestamp = mtk_eth_timestamp(eth); + struct mtk_foe_entry *hwe; ++ u32 val; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { + entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; +@@ -656,8 +657,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p + wmb(); + hwe->ib1 = entry->ib1; + +- if (ppe->accounting) +- *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT; ++ if (ppe->accounting) { ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ val = MTK_FOE_IB2_MIB_CNT_V2; ++ else ++ val = MTK_FOE_IB2_MIB_CNT; ++ *mtk_foe_entry_ib2(eth, hwe) |= val; ++ } + + dma_wmb(); + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -55,9 +55,10 @@ enum { + #define MTK_FOE_IB2_PSE_QOS BIT(4) + #define MTK_FOE_IB2_DEST_PORT GENMASK(7, 5) + #define MTK_FOE_IB2_MULTICAST BIT(8) ++#define MTK_FOE_IB2_MIB_CNT BIT(10) + + #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12) +-#define MTK_FOE_IB2_MIB_CNT BIT(15) ++#define MTK_FOE_IB2_MIB_CNT_V2 BIT(15) + #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16) + #define MTK_FOE_IB2_WDMA_WINFO BIT(17) + diff --git a/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch b/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch new file mode 100644 index 000000000..d4fb672ea --- /dev/null +++ b/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch @@ -0,0 +1,227 @@ +From: Felix Fietkau +Date: Thu, 16 Feb 2023 18:39:04 +0100 +Subject: [PATCH] net/core: add optional threading for backlog processing + +When dealing with few flows or an imbalance on CPU utilization, static RPS +CPU assignment can be too inflexible. Add support for enabling threaded NAPI +for backlog processing in order to allow the scheduler to better balance +processing. This helps better spread the load across idle CPUs. + +Signed-off-by: Felix Fietkau +--- + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -520,6 +520,7 @@ static inline bool napi_complete(struct + } + + int dev_set_threaded(struct net_device *dev, bool threaded); ++int backlog_set_threaded(bool threaded); + + /** + * napi_disable - prevent NAPI from scheduling +@@ -3130,6 +3131,7 @@ struct softnet_data { + unsigned int processed; + unsigned int time_squeeze; + unsigned int received_rps; ++ unsigned int process_queue_empty; + #ifdef CONFIG_RPS + struct softnet_data *rps_ipi_list; + #endif +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4608,7 +4608,7 @@ static int napi_schedule_rps(struct soft + struct softnet_data *mysd = this_cpu_ptr(&softnet_data); + + #ifdef CONFIG_RPS +- if (sd != mysd) { ++ if (sd != mysd && !test_bit(NAPI_STATE_THREADED, &sd->backlog.state)) { + sd->rps_ipi_next = mysd->rps_ipi_list; + mysd->rps_ipi_list = sd; + +@@ -5789,6 +5789,8 @@ static DEFINE_PER_CPU(struct work_struct + /* Network device is going away, flush any packets still pending */ + static void flush_backlog(struct work_struct *work) + { ++ unsigned int process_queue_empty; ++ bool threaded, flush_processq; + struct sk_buff *skb, *tmp; + struct softnet_data *sd; + +@@ -5803,8 +5805,17 @@ static void flush_backlog(struct work_st + input_queue_head_incr(sd); + } + } ++ ++ threaded = test_bit(NAPI_STATE_THREADED, &sd->backlog.state); ++ flush_processq = threaded && ++ !skb_queue_empty_lockless(&sd->process_queue); ++ if (flush_processq) ++ process_queue_empty = sd->process_queue_empty; + rps_unlock_irq_enable(sd); + ++ if (threaded) ++ goto out; ++ + skb_queue_walk_safe(&sd->process_queue, skb, tmp) { + if (skb->dev->reg_state == NETREG_UNREGISTERING) { + __skb_unlink(skb, &sd->process_queue); +@@ -5812,7 +5823,16 @@ static void flush_backlog(struct work_st + input_queue_head_incr(sd); + } + } ++ ++out: + local_bh_enable(); ++ ++ while (flush_processq) { ++ msleep(1); ++ rps_lock_irq_disable(sd); ++ flush_processq = process_queue_empty == sd->process_queue_empty; ++ rps_unlock_irq_enable(sd); ++ } + } + + static bool flush_required(int cpu) +@@ -5944,6 +5964,7 @@ static int process_backlog(struct napi_s + } + + rps_lock_irq_disable(sd); ++ sd->process_queue_empty++; + if (skb_queue_empty(&sd->input_pkt_queue)) { + /* + * Inline a custom version of __napi_complete(). +@@ -5953,7 +5974,8 @@ static int process_backlog(struct napi_s + * We can use a plain write instead of clear_bit(), + * and we dont need an smp_mb() memory barrier. + */ +- napi->state = 0; ++ napi->state &= ~(NAPIF_STATE_SCHED | ++ NAPIF_STATE_SCHED_THREADED); + again = false; + } else { + skb_queue_splice_tail_init(&sd->input_pkt_queue, +@@ -6369,6 +6391,55 @@ int dev_set_threaded(struct net_device * + } + EXPORT_SYMBOL(dev_set_threaded); + ++int backlog_set_threaded(bool threaded) ++{ ++ static bool backlog_threaded; ++ int err = 0; ++ int i; ++ ++ if (backlog_threaded == threaded) ++ return 0; ++ ++ for_each_possible_cpu(i) { ++ struct softnet_data *sd = &per_cpu(softnet_data, i); ++ struct napi_struct *n = &sd->backlog; ++ ++ if (n->thread) ++ continue; ++ n->thread = kthread_run(napi_threaded_poll, n, "napi/backlog-%d", i); ++ if (IS_ERR(n->thread)) { ++ err = PTR_ERR(n->thread); ++ pr_err("kthread_run failed with err %d\n", err); ++ n->thread = NULL; ++ threaded = false; ++ break; ++ } ++ ++ } ++ ++ backlog_threaded = threaded; ++ ++ /* Make sure kthread is created before THREADED bit ++ * is set. ++ */ ++ smp_mb__before_atomic(); ++ ++ for_each_possible_cpu(i) { ++ struct softnet_data *sd = &per_cpu(softnet_data, i); ++ struct napi_struct *n = &sd->backlog; ++ unsigned long flags; ++ ++ rps_lock_irqsave(sd, &flags); ++ if (threaded) ++ n->state |= NAPIF_STATE_THREADED; ++ else ++ n->state &= ~NAPIF_STATE_THREADED; ++ rps_unlock_irq_restore(sd, &flags); ++ } ++ ++ return err; ++} ++ + void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi, + int (*poll)(struct napi_struct *, int), int weight) + { +@@ -11141,6 +11212,9 @@ static int dev_cpu_dead(unsigned int old + raise_softirq_irqoff(NET_TX_SOFTIRQ); + local_irq_enable(); + ++ if (test_bit(NAPI_STATE_THREADED, &oldsd->backlog.state)) ++ return 0; ++ + #ifdef CONFIG_RPS + remsd = oldsd->rps_ipi_list; + oldsd->rps_ipi_list = NULL; +@@ -11444,6 +11518,7 @@ static int __init net_dev_init(void) + INIT_CSD(&sd->defer_csd, trigger_rx_softirq, sd); + spin_lock_init(&sd->defer_lock); + ++ INIT_LIST_HEAD(&sd->backlog.poll_list); + init_gro_hash(&sd->backlog); + sd->backlog.poll = process_backlog; + sd->backlog.weight = weight_p; +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -29,6 +29,7 @@ static int int_3600 = 3600; + static int min_sndbuf = SOCK_MIN_SNDBUF; + static int min_rcvbuf = SOCK_MIN_RCVBUF; + static int max_skb_frags = MAX_SKB_FRAGS; ++static int backlog_threaded; + + static int net_msg_warn; /* Unused, but still a sysctl */ + +@@ -112,6 +113,23 @@ static int rps_sock_flow_sysctl(struct c + } + #endif /* CONFIG_RPS */ + ++static int backlog_threaded_sysctl(struct ctl_table *table, int write, ++ void *buffer, size_t *lenp, loff_t *ppos) ++{ ++ static DEFINE_MUTEX(backlog_threaded_mutex); ++ int ret; ++ ++ mutex_lock(&backlog_threaded_mutex); ++ ++ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); ++ if (write && !ret) ++ ret = backlog_set_threaded(backlog_threaded); ++ ++ mutex_unlock(&backlog_threaded_mutex); ++ ++ return ret; ++} ++ + #ifdef CONFIG_NET_FLOW_LIMIT + static DEFINE_MUTEX(flow_limit_update_mutex); + +@@ -473,6 +491,15 @@ static struct ctl_table net_core_table[] + .proc_handler = rps_sock_flow_sysctl + }, + #endif ++ { ++ .procname = "backlog_threaded", ++ .data = &backlog_threaded, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = backlog_threaded_sysctl, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE ++ }, + #ifdef CONFIG_NET_FLOW_LIMIT + { + .procname = "flow_limit_cpu_bitmap", diff --git a/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch b/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch new file mode 100644 index 000000000..23859816f --- /dev/null +++ b/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch @@ -0,0 +1,174 @@ +From patchwork Sun Mar 19 22:08:05 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13180645 +X-Patchwork-Delegate: kuba@kernel.org +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id A7A46C6FD1F + for ; Sun, 19 Mar 2023 22:08:15 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230223AbjCSWIN (ORCPT ); + Sun, 19 Mar 2023 18:08:13 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32878 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229565AbjCSWIM (ORCPT + ); Sun, 19 Mar 2023 18:08:12 -0400 +Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com + [IPv6:2a00:1450:4864:20::42e]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 605D3E062; + Sun, 19 Mar 2023 15:08:10 -0700 (PDT) +Received: by mail-wr1-x42e.google.com with SMTP id h17so8695188wrt.8; + Sun, 19 Mar 2023 15:08:10 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1679263689; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=; + b=PSdrywW48P4Lq8z9wOSPXFB/ZdO/JfuyiGlw3Gz1Iriy+Smo/cBnJ0Ve9zKkX3AKTO + Tr7/g8xhSQX8sU5WAOEPC13uVjKpO4VZsamXHTmMKL4mmfII3K/piAsQcMQkkNpgouab + Ci9yr+7ASSmqEUHIbYTM6sl6a47rPwqk3b3DcTIE2CwJsPPNXnpQ/aSVbJAcEdhcZICc + X4rAmjrYjcsl8coFIGHHPlrMH9ShekQWxB84vEb6bO1nXOORNPizOHuY1vJ3wa3WgXsx + YwlvutMFVIUXfgL2ZwCmQAKWJPiAaFk+CCk3oxSeOYoAzkjcbMyapz9VnooStfvR2aV3 + k+2g== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1679263689; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=; + b=NGjqrGERyaxRwINtevHaY97h9X9W+1UY62YYwotqwv5+cfvB8myjBbD3WH2WzaqMes + o9MMER9RE8/arW3jIVlBv4ORDUuEZ7AeGgy5UbFyQZIPHlp+hJ/sxFrGvYUwamg4Qrr9 + ojargh8ORsEiMeqaf+5AkmEagNhrrV3ax0pUuWDzbJ3vXGoHjfCetHz5xyNL46dvXBfb + l/OZqjv9IYob552uUoUmCy/TbEQDqvmjkFrROFK9gtBNxgxUJkwbyiWIOVsf6RR8OarP + f7bbvSJYkvTvzx2u/g0Up7NW5ZyihMGBmDs377M3yW6AnSxW6jlfl30QmMU1aEigYXvy + v3mA== +X-Gm-Message-State: AO0yUKUm1PYmYa4xlHuVD23mZcZm83a+xbhcbs0Xryi3yF/+UnjM4Cho + GAfqSh5MZ/rlOAm3Vnpn//9hOG5Lc8vLYg== +X-Google-Smtp-Source: + AK7set+5pTahGGgk1hF/mHGkGBhsMf0//oQjZd4QFHx+HaeSgP5f6q7g0bRUcTX8kRtgHH0T7l1/hQ== +X-Received: by 2002:a5d:474f:0:b0:2d6:2ae8:70d with SMTP id + o15-20020a5d474f000000b002d62ae8070dmr2382593wrs.39.1679263688549; + Sun, 19 Mar 2023 15:08:08 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + d6-20020a5d6dc6000000b002c53f6c7599sm7354727wrz.29.2023.03.19.15.08.07 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Sun, 19 Mar 2023 15:08:07 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, + olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, + kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, + linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +Subject: [PATCH v2] net: dsa: b53: add support for BCM63xx RGMIIs +Date: Sun, 19 Mar 2023 23:08:05 +0100 +Message-Id: <20230319220805.124024-1-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230319183330.761251-1-noltari@gmail.com> +References: <20230319183330.761251-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +BCM63xx RGMII ports require additional configuration in order to work. + +Signed-off-by: Álvaro Fernández Rojas +Reviewed-by: Andrew Lunn +--- + v2: add changes suggested by Andrew: + - Use a switch statement. + - Use dev_dbg() instead of dev_info(). + + drivers/net/dsa/b53/b53_common.c | 46 ++++++++++++++++++++++++++++++++ + drivers/net/dsa/b53/b53_priv.h | 1 + + 2 files changed, 47 insertions(+) + +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1209,6 +1209,46 @@ static void b53_force_port_config(struct + b53_write8(dev, B53_CTRL_PAGE, off, reg); + } + ++static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port, ++ phy_interface_t interface) ++{ ++ struct b53_device *dev = ds->priv; ++ u8 rgmii_ctrl = 0, off; ++ ++ if (port == dev->imp_port) ++ off = B53_RGMII_CTRL_IMP; ++ else ++ off = B53_RGMII_CTRL_P(port); ++ ++ b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl); ++ ++ switch (interface) { ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); ++ break; ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ rgmii_ctrl &= ~(RGMII_CTRL_DLL_TXC); ++ rgmii_ctrl |= RGMII_CTRL_DLL_RXC; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC); ++ rgmii_ctrl |= RGMII_CTRL_DLL_TXC; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ default: ++ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); ++ break; ++ } ++ ++ if (port != dev->imp_port) ++ rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII; ++ ++ b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); ++ ++ dev_dbg(ds->dev, "Configured port %d for %s\n", port, ++ phy_modes(interface)); ++} ++ + static void b53_adjust_link(struct dsa_switch *ds, int port, + struct phy_device *phydev) + { +@@ -1235,6 +1275,9 @@ static void b53_adjust_link(struct dsa_s + tx_pause, rx_pause); + b53_force_link(dev, port, phydev->link); + ++ if (is63xx(dev) && port >= B53_63XX_RGMII0) ++ b53_adjust_63xx_rgmii(ds, port, phydev->interface); ++ + if (is531x5(dev) && phy_interface_is_rgmii(phydev)) { + if (port == dev->imp_port) + off = B53_RGMII_CTRL_IMP; +@@ -1402,6 +1445,9 @@ void b53_phylink_mac_link_up(struct dsa_ + { + struct b53_device *dev = ds->priv; + ++ if (is63xx(dev) && port >= B53_63XX_RGMII0) ++ b53_adjust_63xx_rgmii(ds, port, interface); ++ + if (mode == MLO_AN_PHY) + return; + +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -211,6 +211,7 @@ static inline int is58xx(struct b53_devi + dev->chip_id == BCM7278_DEVICE_ID; + } + ++#define B53_63XX_RGMII0 4 + #define B53_CPU_PORT_25 5 + #define B53_CPU_PORT 8 + diff --git a/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch b/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch new file mode 100644 index 000000000..8ab701ef5 --- /dev/null +++ b/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch @@ -0,0 +1,108 @@ +From patchwork Tue Mar 21 17:33:57 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13183003 +X-Patchwork-Delegate: kuba@kernel.org +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 823A1C761AF + for ; Tue, 21 Mar 2023 17:35:06 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230490AbjCURfE (ORCPT ); + Tue, 21 Mar 2023 13:35:04 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47440 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230357AbjCURex (ORCPT + ); Tue, 21 Mar 2023 13:34:53 -0400 +Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com + [IPv6:2a00:1450:4864:20::430]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9A45559D8; + Tue, 21 Mar 2023 10:34:26 -0700 (PDT) +Received: by mail-wr1-x430.google.com with SMTP id m2so14547588wrh.6; + Tue, 21 Mar 2023 10:34:26 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1679420063; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=; + b=F0pa8JmQZ1FeXVtdpCygur8UmLrgKwxCcjaMn312u5zNvsXsEPeCAIDqP2tvNNTwv/ + UYjaNaoZ77HSvv/gSqeG808AXGyNs1PvLuHZYuUTJRNuLaMixKtkNFi4ypheCdk0WCiE + IWz0DIm6ojmdwMqafDUKQ6Qwkv5R0vo8Wh5vpjimEmCelOyMvfuLZNqubsiGqpnCguBp + uWlmKh95/VubCGgiGG2xK1IXQayL14ENuWseDds7nVpVK50NycrFgJbL17Bd6qJKYkbo + m70IC+9jM0hjwKXpyi6ipCBNcW+1E6JIwILVC04Xi+BTpOGhbUAQ59Yn2hyq7tQM7dzs + 4PLg== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1679420063; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=; + b=SCX78yTuGjdnE5nuL0p7+kxGnOzsCExsigLdaV+x/JswmwxSpZvxn223i1yM95klj9 + Rk0RnXqATLF1wZA7L1YmbeZ66zxUwW/osnCjJHPeEF8AGgjK/qawtLl/HJQHN67NaRNQ + bDsRn2nWQ2GRTRFpvD+iGRy4uyQCDu9HFxLbn43fBsBmRnXWGPQP5cEb90tL83/Onp4D + Lx/XcyZOh9QRfJNhj+G1BAeRCLRA/sdA0W3Ecu5SCFs+LtS6uvLVGWDKEDfnZhYY8Xqf + Mx9evWzdW2OorEN2FI6+xTglvnEBcVhHIJ7XEGAhCG6ocgMZeck++774S8RWumWl8xpy + /K9Q== +X-Gm-Message-State: AO0yUKUORAlGfbkNwnYmQnTWcGPqW6sp4g9WfgQmRZGCV+9tCB0OebSP + ICq6v4YPmUPNRl/WNnVCbps= +X-Google-Smtp-Source: + AK7set8pFDl8fHRwGPhAguqxIfqnQ4PY+b57IHEsybIaQ/HPNwdJ1cs1+IPBGHe3TL14dTS4aVNpHA== +X-Received: by 2002:a5d:6991:0:b0:2ce:aab5:f96b with SMTP id + g17-20020a5d6991000000b002ceaab5f96bmr2965175wru.67.1679420062764; + Tue, 21 Mar 2023 10:34:22 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.21 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Tue, 21 Mar 2023 10:34:21 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, + olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, + kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, + krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, + devicetree@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +Subject: [PATCH v2 2/4] net: dsa: b53: mmap: add more 63xx SoCs +Date: Tue, 21 Mar 2023 18:33:57 +0100 +Message-Id: <20230321173359.251778-3-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> +References: <20230320155024.164523-1-noltari@gmail.com> + <20230321173359.251778-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +BCM6318, BCM6362 and BCM63268 are SoCs with a B53 MMAP switch. + +Signed-off-by: Álvaro Fernández Rojas +Reviewed-by: Florian Fainelli +--- + v2: no changes. + + drivers/net/dsa/b53/b53_mmap.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/dsa/b53/b53_mmap.c ++++ b/drivers/net/dsa/b53/b53_mmap.c +@@ -345,8 +345,11 @@ static void b53_mmap_shutdown(struct pla + + static const struct of_device_id b53_mmap_of_table[] = { + { .compatible = "brcm,bcm3384-switch" }, ++ { .compatible = "brcm,bcm6318-switch" }, + { .compatible = "brcm,bcm6328-switch" }, ++ { .compatible = "brcm,bcm6362-switch" }, + { .compatible = "brcm,bcm6368-switch" }, ++ { .compatible = "brcm,bcm63268-switch" }, + { .compatible = "brcm,bcm63xx-switch" }, + { /* sentinel */ }, + }; diff --git a/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch b/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch new file mode 100644 index 000000000..de237374a --- /dev/null +++ b/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch @@ -0,0 +1,195 @@ +From patchwork Tue Mar 21 17:33:58 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13183004 +X-Patchwork-Delegate: kuba@kernel.org +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id B2B12C74A5B + for ; Tue, 21 Mar 2023 17:35:12 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230297AbjCURfK (ORCPT ); + Tue, 21 Mar 2023 13:35:10 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47438 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230374AbjCURex (ORCPT + ); Tue, 21 Mar 2023 13:34:53 -0400 +Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com + [IPv6:2a00:1450:4864:20::432]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C906B5550A; + Tue, 21 Mar 2023 10:34:26 -0700 (PDT) +Received: by mail-wr1-x432.google.com with SMTP id y14so14546846wrq.4; + Tue, 21 Mar 2023 10:34:26 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1679420064; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=; + b=eFv+mwe94Y2YZMiJP5gydXVrGlbIAR5HCrY0rdcoGoMPzQUHLFckZeYCgEKudI55I7 + gMLZYCtLwvDXvKeHM2AUigsq2YuJSeF5QwICPrhTnMwUGBg4yyyltrc3+J0lSd6/4kQv + h0yM1Oo4v0d8CuqjBU6bXienIk34AFVJfsPq+vWQTjAbUL7ht4WHZ2Ez2MFoTvZpkIJA + 5iWMyVoMbugZl6eqNRjvDHFmtBtrZIv8AFs10r2Ca6+Yxm+aq0v33DRkbSVVqgFPNEzy + q5QOXOeLBPL6BvyovOpmVSWGoHf1zFV7lrzcqi+uc+FuYxQ9dyN3ND73DrrhWSkLaSg9 + r8yA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1679420064; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=; + b=jIRB8pIlrLA/ovhnEoePs/6SX8fn6l7l4fY2CxX2pLrTbP1JI8AAetPavvrNVQTr2M + Vm0iLbKyL/VpTq9+bSN1SMjaoi4lAMj0pgafoHrwABMVZpFauYvtCfSYTstZ2pw4Dr1j + wYQGj3BUSpFIYHtSIDMkb5449WA3T3TONhaQLRFAUCBD6gAFyEky5fY+DIHrGaj352B6 + 9ST/tkqHgPpuFlmromr42KQWoTFU+Pj0Uhyp7ru4BsnF7tTshWroZZIHUJmSACudEadr + fBPiuurX9jgp9zNqj8Oy0HjiVUnULFCapj8yICGp5s44uDAK/XFqFXpOuJ8ptS6uPazU + xUwg== +X-Gm-Message-State: AO0yUKX2w6QZfaGDHtlZAlY/U8F8VuJa3HwlgXbxgGChgdgvIoFThawv + oDyFAhWbVfe4DxwXTwxgJ/I= +X-Google-Smtp-Source: + AK7set+sH60XiJYup7bqrZTzFJVNe1YGcX/UTfjWV9xfGwNyodc34cHvKpqNagw5J+vEpv6CKvNHaA== +X-Received: by 2002:adf:f344:0:b0:2cd:de25:1c76 with SMTP id + e4-20020adff344000000b002cdde251c76mr12989754wrp.17.1679420064464; + Tue, 21 Mar 2023 10:34:24 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.22 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Tue, 21 Mar 2023 10:34:23 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, + olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, + kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, + krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, + devicetree@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +Subject: [PATCH v2 3/4] net: dsa: b53: mmap: allow passing a chip ID +Date: Tue, 21 Mar 2023 18:33:58 +0100 +Message-Id: <20230321173359.251778-4-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> +References: <20230320155024.164523-1-noltari@gmail.com> + <20230321173359.251778-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +BCM6318 and BCM63268 SoCs require a special handling for their RGMIIs, so we +should be able to identify them as a special BCM63xx switch. + +Signed-off-by: Álvaro Fernández Rojas +--- + v2: + - Add missing chip to b53_switch_chips[]. + - Fix device_get_match_data() casting warning. + - Add BCM63268_DEVICE_ID to BCM6318 too. + - Add BCM6318 in commit description. + + drivers/net/dsa/b53/b53_common.c | 13 +++++++++++++ + drivers/net/dsa/b53/b53_mmap.c | 32 +++++++++++++++++++++++--------- + drivers/net/dsa/b53/b53_priv.h | 9 ++++++++- + 3 files changed, 44 insertions(+), 10 deletions(-) + +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2466,6 +2466,19 @@ static const struct b53_chip_data b53_sw + .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, + }, + { ++ .chip_id = BCM63268_DEVICE_ID, ++ .dev_name = "BCM63268", ++ .vlans = 4096, ++ .enabled_ports = 0, /* pdata must provide them */ ++ .arl_bins = 4, ++ .arl_buckets = 1024, ++ .imp_port = 8, ++ .vta_regs = B53_VTA_REGS_63XX, ++ .duplex_reg = B53_DUPLEX_STAT_63XX, ++ .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, ++ .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, ++ }, ++ { + .chip_id = BCM53010_DEVICE_ID, + .dev_name = "BCM53010", + .vlans = 4096, +--- a/drivers/net/dsa/b53/b53_mmap.c ++++ b/drivers/net/dsa/b53/b53_mmap.c +@@ -262,7 +262,7 @@ static int b53_mmap_probe_of(struct plat + return -ENOMEM; + + pdata->regs = mem; +- pdata->chip_id = BCM63XX_DEVICE_ID; ++ pdata->chip_id = (u32)(unsigned long)device_get_match_data(dev); + pdata->big_endian = of_property_read_bool(np, "big-endian"); + + of_ports = of_get_child_by_name(np, "ports"); +@@ -344,14 +344,28 @@ static void b53_mmap_shutdown(struct pla + } + + static const struct of_device_id b53_mmap_of_table[] = { +- { .compatible = "brcm,bcm3384-switch" }, +- { .compatible = "brcm,bcm6318-switch" }, +- { .compatible = "brcm,bcm6328-switch" }, +- { .compatible = "brcm,bcm6362-switch" }, +- { .compatible = "brcm,bcm6368-switch" }, +- { .compatible = "brcm,bcm63268-switch" }, +- { .compatible = "brcm,bcm63xx-switch" }, +- { /* sentinel */ }, ++ { ++ .compatible = "brcm,bcm3384-switch", ++ .data = (void *)BCM63XX_DEVICE_ID, ++ }, { ++ .compatible = "brcm,bcm6318-switch", ++ .data = (void *)BCM63268_DEVICE_ID, ++ }, { ++ .compatible = "brcm,bcm6328-switch", ++ .data = (void *)BCM63XX_DEVICE_ID, ++ }, { ++ .compatible = "brcm,bcm6362-switch", ++ .data = (void *)BCM63XX_DEVICE_ID, ++ }, { ++ .compatible = "brcm,bcm6368-switch", ++ .data = (void *)BCM63XX_DEVICE_ID, ++ }, { ++ .compatible = "brcm,bcm63268-switch", ++ .data = (void *)BCM63268_DEVICE_ID, ++ }, { ++ .compatible = "brcm,bcm63xx-switch", ++ .data = (void *)BCM63XX_DEVICE_ID, ++ }, { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, b53_mmap_of_table); + +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -70,6 +70,7 @@ enum { + BCM53125_DEVICE_ID = 0x53125, + BCM53128_DEVICE_ID = 0x53128, + BCM63XX_DEVICE_ID = 0x6300, ++ BCM63268_DEVICE_ID = 0x63268, + BCM53010_DEVICE_ID = 0x53010, + BCM53011_DEVICE_ID = 0x53011, + BCM53012_DEVICE_ID = 0x53012, +@@ -191,7 +192,13 @@ static inline int is531x5(struct b53_dev + + static inline int is63xx(struct b53_device *dev) + { +- return dev->chip_id == BCM63XX_DEVICE_ID; ++ return dev->chip_id == BCM63XX_DEVICE_ID || ++ dev->chip_id == BCM63268_DEVICE_ID; ++} ++ ++static inline int is63268(struct b53_device *dev) ++{ ++ return dev->chip_id == BCM63268_DEVICE_ID; + } + + static inline int is5301x(struct b53_device *dev) diff --git a/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch b/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch new file mode 100644 index 000000000..d90d757fb --- /dev/null +++ b/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch @@ -0,0 +1,123 @@ +From patchwork Tue Mar 21 17:33:59 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13183005 +X-Patchwork-Delegate: kuba@kernel.org +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 31BE4C761A6 + for ; Tue, 21 Mar 2023 17:35:16 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S229674AbjCURfN (ORCPT ); + Tue, 21 Mar 2023 13:35:13 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47684 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230327AbjCURfB (ORCPT + ); Tue, 21 Mar 2023 13:35:01 -0400 +Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com + [IPv6:2a00:1450:4864:20::436]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1D855507D; + Tue, 21 Mar 2023 10:34:27 -0700 (PDT) +Received: by mail-wr1-x436.google.com with SMTP id i9so14537769wrp.3; + Tue, 21 Mar 2023 10:34:27 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1679420066; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=; + b=Cqj2C6aG5vEOlhh9N3ybvDA0CV38nhQODnfdnr7utNddd323iDagoJty1Wmi3MAzj1 + 5ORmYT5fQvUnild7C4RhcCNTBn+MoYZ+wDZwZYelu6BKHkW11YFK949ax5B50by+ASR2 + z+rGI3wR5fVXd4VDgmcsT6zF5x69wKyhbhqIfrhG9BVFTctfaBgDS/l+bX1C56kSqv82 + bQkKSSAehSLGpFoCU3q62OGoZVi3jDe6HDb5M1Dp2mgHhqsW19otZpJ57DjtZ1CmtPai + o7T/ew6WoIYSl6whBmV36jeNaDJ3TItOBrKc4nMJBDWaCg4DNzUSe0ei5Xz7Oik5lb3p + y9ew== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1679420066; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=; + b=UdI2iQNBYwRf40ivf3ROR132t95BU/p3RUzXdZLCyz6c6JWtECQ5byyGeEwoX10n5u + HlepoNTJxMFLYrAHGvNLDPpWPuLXMa645S1mCVZ7NyWp8W96XzSynNZPeXHuJdb464QU + A7UTRSW3mlvKe9OR3EcB2CfBZv0yHWR0ldbnxcxGUFw8z78PNqpOVnITtjBdfpGesJ9c + VJw+fiM6hCcahor4nk9LLcAryPm8xmhDLxBKaLILO8wyTUiHY8G9hsXnFCtcpetnF5wS + pW13beAE+odb7ZZaXZUYpWGYhCe/hLzNjbo8YpgzHwadZthxPrT5YvNIYwyrvoViLM0n + KDRQ== +X-Gm-Message-State: AO0yUKW+9H/kqcAUyWeZhZJhiJjsBcYn1THmZaSDrPrk/pNuGXJXGtJd + NgsGZW8iSqLEv81yK+U5Os8= +X-Google-Smtp-Source: + AK7set/lzQZwCSxVaOe5dZ+7TR3xaQty/vg5xvZDpRW8TwTiPQblIbw5kJJTPLp67RySehrPIlCqSg== +X-Received: by 2002:a5d:65c9:0:b0:2ce:ac31:54ff with SMTP id + e9-20020a5d65c9000000b002ceac3154ffmr2776515wrw.2.1679420066191; + Tue, 21 Mar 2023 10:34:26 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.24 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Tue, 21 Mar 2023 10:34:25 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, + olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, + kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, + krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, + devicetree@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , + Simon Horman +Subject: [PATCH v2 4/4] net: dsa: b53: add BCM63268 RGMII configuration +Date: Tue, 21 Mar 2023 18:33:59 +0100 +Message-Id: <20230321173359.251778-5-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> +References: <20230320155024.164523-1-noltari@gmail.com> + <20230321173359.251778-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +BCM63268 requires special RGMII configuration to work. + +Signed-off-by: Álvaro Fernández Rojas +Reviewed-by: Florian Fainelli +Reviewed-by: Simon Horman +--- + v2: no changes. + + drivers/net/dsa/b53/b53_common.c | 6 +++++- + drivers/net/dsa/b53/b53_regs.h | 1 + + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1240,8 +1240,12 @@ static void b53_adjust_63xx_rgmii(struct + break; + } + +- if (port != dev->imp_port) ++ if (port != dev->imp_port) { ++ if (is63268(dev)) ++ rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE; ++ + rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII; ++ } + + b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); + +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -138,6 +138,7 @@ + + #define B53_RGMII_CTRL_IMP 0x60 + #define RGMII_CTRL_ENABLE_GMII BIT(7) ++#define RGMII_CTRL_MII_OVERRIDE BIT(6) + #define RGMII_CTRL_TIMING_SEL BIT(2) + #define RGMII_CTRL_DLL_RXC BIT(1) + #define RGMII_CTRL_DLL_TXC BIT(0) diff --git a/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch b/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch new file mode 100644 index 000000000..f0ae2defc --- /dev/null +++ b/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch @@ -0,0 +1,189 @@ +From patchwork Fri Mar 24 08:41:38 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13186549 +X-Patchwork-Delegate: kuba@kernel.org +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id EF744C76195 + for ; Fri, 24 Mar 2023 08:42:01 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S231807AbjCXImA (ORCPT ); + Fri, 24 Mar 2023 04:42:00 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32956 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S231272AbjCXIly (ORCPT + ); Fri, 24 Mar 2023 04:41:54 -0400 +Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com + [IPv6:2a00:1450:4864:20::535]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 113A517CF3; + Fri, 24 Mar 2023 01:41:46 -0700 (PDT) +Received: by mail-ed1-x535.google.com with SMTP id ek18so4877175edb.6; + Fri, 24 Mar 2023 01:41:45 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1679647304; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=; + b=JMrl6Eay1FS0JZqgPHsbcVzuNAbFELc0SLNGyzYtOVQXcI+YwKDM9Ls7I9PsQVEPoZ + CthomCTYoz5G9DU7uBuia207rnjOhssZJRu0syrCoU+O/ZiQyGLJDvq61z5oZJxC2S40 + kzRsUsC6MRjn64DKPWmxhsSTMKLzn2+P233LKNFbHtfi3NWF5Qu/85sUkxMurnfUgja0 + qQhl25qYY7ZIvmlFHYefaI5UkITQFuiybrqJW9tztCdHf/gS+f33YkkvQ8njmMQa1DW0 + ppedfOUotX+6kmHZGX1yea2V5ezEGGvRourZtYMoecTiD0E5d1J1bKhktKslVLIDm0ig + oc2g== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1679647304; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=; + b=b3Gmga5ZDbnmQfnw1GCz+eU2JwgsVzfciZuSmfYAiVxpW4c6cur3MHbpzDPhi99wzA + ZYAM7ryLv88rXl/tQB5g2Nte5rvMfxUeHXsT/JpsRcSSocFRbRrk0QJyiA/Xj86NiD5N + C1sKz50Im190FmrvPcBh6OHQbv/3MQyE+1fQx+9q3jW5rQiAWQaYk4Ng8GlWA7gtG3jB + fHO6Fuoenn32pgkveJbQLYL/2t2f53wGf3QLQ3IeKW7jdfIHNThwrwqBMxdHoIDaTBT9 + UWMeJuiYtylIibo/3zbORbWOgIERlWxZRf3BCOFpnzUn4eBzio4LgjtNxZ77ITRxsmbk + 3+Hg== +X-Gm-Message-State: AAQBX9dfyBfbR7Sdd5wqxMiAv3Yhk47pK1XzD87MZyAF3AxyoFyKcMaF + EbwJLyRvTGQEFdVWCGw1eMU= +X-Google-Smtp-Source: + AKy350bpDVLq7k1FxG2Mek/VIobZL4KhufiKx8qfmpxpcWmLI3bLg8wfQKEAKJRNJBleo/7CZuCL5g== +X-Received: by 2002:aa7:c711:0:b0:4a2:588f:b3c5 with SMTP id + i17-20020aa7c711000000b004a2588fb3c5mr2261236edq.21.1679647304260; + Fri, 24 Mar 2023 01:41:44 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + z21-20020a50cd15000000b004acbda55f6bsm10323728edi.27.2023.03.24.01.41.43 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 24 Mar 2023 01:41:43 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: paul.geurts@prodrive-technologies.com, f.fainelli@gmail.com, + jonas.gorski@gmail.com, andrew@lunn.ch, olteanv@gmail.com, + davem@davemloft.net, edumazet@google.com, kuba@kernel.org, + pabeni@redhat.com, robh+dt@kernel.org, + krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, + devicetree@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +Subject: [PATCH v2 2/2] net: dsa: b53: mdio: add support for BCM53134 +Date: Fri, 24 Mar 2023 09:41:38 +0100 +Message-Id: <20230324084138.664285-3-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230324084138.664285-1-noltari@gmail.com> +References: <20230323121804.2249605-1-noltari@gmail.com> + <20230324084138.664285-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: netdev@vger.kernel.org +X-Patchwork-Delegate: kuba@kernel.org + +From: Paul Geurts + +Add support for the BCM53134 Ethernet switch in the existing b53 dsa driver. +BCM53134 is very similar to the BCM58XX series. + +Signed-off-by: Paul Geurts +Signed-off-by: Álvaro Fernández Rojas +--- + v2: add BCM53134 to is531x5() and remove special RGMII config + + drivers/net/dsa/b53/b53_common.c | 15 +++++++++++++++ + drivers/net/dsa/b53/b53_mdio.c | 5 ++++- + drivers/net/dsa/b53/b53_priv.h | 7 +++++-- + 3 files changed, 24 insertions(+), 3 deletions(-) + +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2613,6 +2613,20 @@ static const struct b53_chip_data b53_sw + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + }, ++ { ++ .chip_id = BCM53134_DEVICE_ID, ++ .dev_name = "BCM53134", ++ .vlans = 4096, ++ .enabled_ports = 0x12f, ++ .imp_port = 8, ++ .cpu_port = B53_CPU_PORT, ++ .vta_regs = B53_VTA_REGS, ++ .arl_bins = 4, ++ .arl_buckets = 1024, ++ .duplex_reg = B53_DUPLEX_STAT_GE, ++ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, ++ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ }, + }; + + static int b53_switch_init(struct b53_device *dev) +@@ -2790,6 +2804,7 @@ int b53_switch_detect(struct b53_device + case BCM53012_DEVICE_ID: + case BCM53018_DEVICE_ID: + case BCM53019_DEVICE_ID: ++ case BCM53134_DEVICE_ID: + dev->chip_id = id32; + break; + default: +--- a/drivers/net/dsa/b53/b53_mdio.c ++++ b/drivers/net/dsa/b53/b53_mdio.c +@@ -286,6 +286,7 @@ static const struct b53_io_ops b53_mdio_ + #define B53_BRCM_OUI_2 0x03625c00 + #define B53_BRCM_OUI_3 0x00406000 + #define B53_BRCM_OUI_4 0x01410c00 ++#define B53_BRCM_OUI_5 0xae025000 + + static int b53_mdio_probe(struct mdio_device *mdiodev) + { +@@ -313,7 +314,8 @@ static int b53_mdio_probe(struct mdio_de + if ((phy_id & 0xfffffc00) != B53_BRCM_OUI_1 && + (phy_id & 0xfffffc00) != B53_BRCM_OUI_2 && + (phy_id & 0xfffffc00) != B53_BRCM_OUI_3 && +- (phy_id & 0xfffffc00) != B53_BRCM_OUI_4) { ++ (phy_id & 0xfffffc00) != B53_BRCM_OUI_4 && ++ (phy_id & 0xfffffc00) != B53_BRCM_OUI_5) { + dev_err(&mdiodev->dev, "Unsupported device: 0x%08x\n", phy_id); + return -ENODEV; + } +@@ -375,6 +377,7 @@ static const struct of_device_id b53_of_ + { .compatible = "brcm,bcm53115" }, + { .compatible = "brcm,bcm53125" }, + { .compatible = "brcm,bcm53128" }, ++ { .compatible = "brcm,bcm53134" }, + { .compatible = "brcm,bcm5365" }, + { .compatible = "brcm,bcm5389" }, + { .compatible = "brcm,bcm5395" }, +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -80,6 +80,7 @@ enum { + BCM583XX_DEVICE_ID = 0x58300, + BCM7445_DEVICE_ID = 0x7445, + BCM7278_DEVICE_ID = 0x7278, ++ BCM53134_DEVICE_ID = 0x5075, + }; + + struct b53_pcs { +@@ -187,7 +188,8 @@ static inline int is531x5(struct b53_dev + { + return dev->chip_id == BCM53115_DEVICE_ID || + dev->chip_id == BCM53125_DEVICE_ID || +- dev->chip_id == BCM53128_DEVICE_ID; ++ dev->chip_id == BCM53128_DEVICE_ID || ++ dev->chip_id == BCM53134_DEVICE_ID; + } + + static inline int is63xx(struct b53_device *dev) +@@ -215,7 +217,8 @@ static inline int is58xx(struct b53_devi + return dev->chip_id == BCM58XX_DEVICE_ID || + dev->chip_id == BCM583XX_DEVICE_ID || + dev->chip_id == BCM7445_DEVICE_ID || +- dev->chip_id == BCM7278_DEVICE_ID; ++ dev->chip_id == BCM7278_DEVICE_ID || ++ dev->chip_id == BCM53134_DEVICE_ID; + } + + #define B53_63XX_RGMII0 4 diff --git a/target/linux/generic/pending-6.1/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch b/target/linux/generic/pending-6.1/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch new file mode 100644 index 000000000..26f40d9f8 --- /dev/null +++ b/target/linux/generic/pending-6.1/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch @@ -0,0 +1,43 @@ +From 1d81e51d6d79d9098013b2e8cdd677bae998c5d8 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Fri, 28 Apr 2023 02:22:59 +0200 +Subject: [PATCH 1/2] mt7530: register OF node for internal MDIO bus + +The MT753x switches provide a switch-internal MDIO bus for the embedded +PHYs. + +Register a OF sub-node on the switch OF-node for this internal MDIO bus. +This allows to configure the embedded PHYs using device-tree. + +Signed-off-by: David Bauer +--- + drivers/net/dsa/mt7530.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -2126,10 +2126,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr + { + struct dsa_switch *ds = priv->ds; + struct device *dev = priv->dev; ++ struct device_node *np, *mnp; + struct mii_bus *bus; + static int idx; + int ret; + ++ np = priv->dev->of_node; ++ + bus = devm_mdiobus_alloc(dev); + if (!bus) + return -ENOMEM; +@@ -2146,7 +2149,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr + if (priv->irq) + mt7530_setup_mdio_irq(priv); + +- ret = devm_mdiobus_register(dev, bus); ++ mnp = of_get_child_by_name(np, "mdio"); ++ ret = devm_of_mdiobus_register(dev, bus, mnp); ++ of_node_put(mnp); + if (ret) { + dev_err(dev, "failed to register MDIO bus: %d\n", ret); + if (priv->irq) diff --git a/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch new file mode 100644 index 000000000..9b111050e --- /dev/null +++ b/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch @@ -0,0 +1,47 @@ +From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001 +From: INAGAKI Hiroshi +Date: Thu, 13 Oct 2022 00:51:33 +0900 +Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch fixes crc32 error on Big-Endianness system by conversion of +calculated crc32 value. + +Little-Endianness system: + + obtained crc32: Little +calculated crc32: Little + +Big-Endianness system: + + obtained crc32: Little +calculated crc32: Big + +log (APRESIA ApresiaLightGS120GT-SS, RTL8382M, Big-Endianness): + +[ 8.570000] u_boot_env 18001200.spi:flash@0:partitions:partition@c0000: Invalid calculated CRC32: 0x88cd6f09 (expected: 0x096fcd88) +[ 8.580000] u_boot_env: probe of 18001200.spi:flash@0:partitions:partition@c0000 failed with error -22 + +Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables") + +Signed-off-by: INAGAKI Hiroshi +Acked-by: Rafał Miłecki +Tested-by: Christian Lamparter +Signed-off-by: Srinivas Kandagatla +--- + drivers/nvmem/u-boot-env.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nvmem/u-boot-env.c ++++ b/drivers/nvmem/u-boot-env.c +@@ -182,7 +182,7 @@ static int u_boot_env_parse(struct u_boo + crc32_data_len = priv->mtd->size - crc32_data_offset; + data_len = priv->mtd->size - data_offset; + +- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; ++ calc = le32_to_cpu((__le32)crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L); + if (calc != crc32) { + dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); + err = -EINVAL; diff --git a/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch b/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch new file mode 100644 index 000000000..cc6f1e0d9 --- /dev/null +++ b/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch @@ -0,0 +1,114 @@ +From patchwork Wed Mar 22 17:15:12 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13184389 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 73F2DC6FD1C + for ; Wed, 22 Mar 2023 17:15:59 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S231363AbjCVRP5 (ORCPT ); + Wed, 22 Mar 2023 13:15:57 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58824 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S231408AbjCVRPy (ORCPT + ); Wed, 22 Mar 2023 13:15:54 -0400 +Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com + [IPv6:2a00:1450:4864:20::32d]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70E4C64B28; + Wed, 22 Mar 2023 10:15:24 -0700 (PDT) +Received: by mail-wm1-x32d.google.com with SMTP id n19so1740892wms.0; + Wed, 22 Mar 2023 10:15:24 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1679505322; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=; + b=LTOQ75W3s5nYo+nEfiJAKqytSopONB4jCtU3zRygzPMasugVOrYFMsUR+WrpsAjuRT + v4HgWpJxEsIWeRXrUN9W21mFXhGgJLJXSxRnrio0CsZZBNMdkebbNOphgKXIWAdm+2iM + PzqAdGm5t38wT2mmm6V/9hCy90+12raHM82tNFdhhiezfg2cukVOKP3j/TeOVCwas0gQ + iFc+CuZB6y73zYXvMUMUpTsqI5vev4xJsSMHIQJVmUxJAwqhOBhN9JCRo7Ao+wayjn2d + Fxo6AV3A8v68nVfoQ0K0I+eWXG48nMCX45iWh/lVvVTOFcR99kn4va7NY1oVnPsh+WQz + WcLA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1679505322; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=; + b=wv2NSR1B5RnsdoEE7mgJSHAfSs1JHZbQ1HPMldyaGWAk1dcucqh/uDzM3Flz+ADRi1 + 19NoaB2Ur7QaWZejbuplnIOK/nte3PnmqJ9ZNw8HejmuS4eU8mB1V1aJUSKSPGsfUi4a + LYe3HSw87l0jrAC7ptdKvdUtzBoIkX0CeFvfguTQQkDhUTyAFIG144hY6uPXY9Mga96b + gnNe2dLCzHQLbEJpaDaavT7FEEcLDxaq7jNcR2xqEEZaIwfcew+Q05t4xL/3i8GAj9Ru + 6ivQjIbBKfYQF88o7KnOW9o1wjrGsk+Nd4Iy0OLZix3JQasCJGrKV7ib5awI9J39upYV + fa4A== +X-Gm-Message-State: AO0yUKWw75I1M5Vjrd4vXq4GTruQu0H84pycgyi2CT3bczTYRJpWmEWg + +bHDhvp1n5IWW85GI9vKWpbclB13a/S0RQ== +X-Google-Smtp-Source: + AK7set9T/2oJsVetUb2L4mPEWu8YqDrnK8EzHK5bJf1ABIa1Et8f7BFJ7AA3j14ITZuf8cH0HqlRtg== +X-Received: by 2002:a05:600c:2304:b0:3ed:2949:985b with SMTP id + 4-20020a05600c230400b003ed2949985bmr206833wmo.23.1679505322457; + Wed, 22 Mar 2023 10:15:22 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.21 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Wed, 22 Mar 2023 10:15:22 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, + krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, + f.fainelli@gmail.com, jonas.gorski@gmail.com, + william.zhang@broadcom.com, linux-clk@vger.kernel.org, + devicetree@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , + Rob Herring +Subject: [PATCH v4 1/4] dt-bindings: clk: add BCM63268 timer clock definitions +Date: Wed, 22 Mar 2023 18:15:12 +0100 +Message-Id: <20230322171515.120353-2-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> +References: <20230322171515.120353-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: linux-clk@vger.kernel.org + +Add missing timer clock definitions for BCM63268. + +Signed-off-by: Álvaro Fernández Rojas +Acked-by: Rob Herring +--- + v4: no changes + v3: no changes + v2: change commit title, as suggested by Stephen Boyd + + include/dt-bindings/clock/bcm63268-clock.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/include/dt-bindings/clock/bcm63268-clock.h ++++ b/include/dt-bindings/clock/bcm63268-clock.h +@@ -27,4 +27,17 @@ + #define BCM63268_CLK_TBUS 27 + #define BCM63268_CLK_ROBOSW250 31 + ++#define BCM63268_TCLK_EPHY1 0 ++#define BCM63268_TCLK_EPHY2 1 ++#define BCM63268_TCLK_EPHY3 2 ++#define BCM63268_TCLK_GPHY1 3 ++#define BCM63268_TCLK_DSL 4 ++#define BCM63268_TCLK_WAKEON_EPHY 6 ++#define BCM63268_TCLK_WAKEON_DSL 7 ++#define BCM63268_TCLK_FAP1 11 ++#define BCM63268_TCLK_FAP2 15 ++#define BCM63268_TCLK_UTO_50 16 ++#define BCM63268_TCLK_UTO_EXTIN 17 ++#define BCM63268_TCLK_USB_REF 18 ++ + #endif /* __DT_BINDINGS_CLOCK_BCM63268_H */ diff --git a/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch b/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch new file mode 100644 index 000000000..5f1be105a --- /dev/null +++ b/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch @@ -0,0 +1,107 @@ +From patchwork Wed Mar 22 17:15:13 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13184390 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id D0B1AC6FD1C + for ; Wed, 22 Mar 2023 17:16:08 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S231472AbjCVRQI (ORCPT ); + Wed, 22 Mar 2023 13:16:08 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58934 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S231435AbjCVRP5 (ORCPT + ); Wed, 22 Mar 2023 13:15:57 -0400 +Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com + [IPv6:2a00:1450:4864:20::329]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9655064863; + Wed, 22 Mar 2023 10:15:25 -0700 (PDT) +Received: by mail-wm1-x329.google.com with SMTP id + v4-20020a05600c470400b003ee4f06428fso2424553wmo.4; + Wed, 22 Mar 2023 10:15:25 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1679505324; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=; + b=WRZRU2SM9n1LfUj4SgTPfQczADC2pfvoIrOsNpBLTym2eOfmkTetb/WbGSla5kw2Wb + SH5MIC2fFeScJg6T5FFAUOOLmRVW9xvl8Q3T3NKb3z/9wvPHO767nrdIbffRWMJFs7gW + wT/kuTpn8GYdfY0sZ/dMTkq41DVusEkxfX6GxtG85O98ZP8xMHQog8aPs9fRfUvI5ZKB + eGYcRz/Wn1cHhjey9jtWzQEEmZ/BT3b0HQTF9Tl88oofhiEgbyjFXr91+vRsLbsJpGXH + /1FjjaLG5DnonKubV9rmbuCU8KzwH331gi2KuRjvLD2V+OMewqSa5i+GvgVv8x2zC8y+ + /mLQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1679505324; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=; + b=bhd0fNh0jDOMlGSC4F+p5igV8AUlGEPj2cXUwgdgqRfSSuUy9z+Li8cT0MbY/aWH5Z + qInRVA+R1cWV3ubrDyKag6oEc0LDU234bnMFcP9b7MRlrM8Dpit9TFSyqJU4sDUWNDs5 + KOe2k/SNIdat6munC9VOuEBDO0eB/UDMN+repKwXNdHChp/Toq9qMvW4Uy8uHxosbQlD + 8P88GbKFjynb1E8I8croGjfub7+y8PPsWB0xNUcafIv6xs3MnVOP1Mk4KwBCbqS509la + mfjsriXtIybO8XFqtn100ungjvbFWdogEplLdSPVdgAqdfF5J8gHxAoApoeYejYkL5/R + kOhQ== +X-Gm-Message-State: AO0yUKWdzr3dMmjKhD8tF+ec4Dfdq9VGZ/WCU4d85npKQvxSwhNPZZ1J + 5WYRIqivh0suFC1OqEidwenpiJYvXedYjw== +X-Google-Smtp-Source: + AK7set87ew2/mKWeShXTTW/YBbBJNR2zeGFV0CfuqLXhiJEU6tqFuyKcW+vFEoKHIbNUS8wRy1SzLA== +X-Received: by 2002:a05:600c:290:b0:3ee:6d88:774a with SMTP id + 16-20020a05600c029000b003ee6d88774amr160734wmk.14.1679505323514; + Wed, 22 Mar 2023 10:15:23 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.22 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Wed, 22 Mar 2023 10:15:23 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, + krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, + f.fainelli@gmail.com, jonas.gorski@gmail.com, + william.zhang@broadcom.com, linux-clk@vger.kernel.org, + devicetree@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , + Rob Herring +Subject: [PATCH v4 2/4] dt-bindings: reset: add BCM63268 timer reset + definitions +Date: Wed, 22 Mar 2023 18:15:13 +0100 +Message-Id: <20230322171515.120353-3-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> +References: <20230322171515.120353-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: linux-clk@vger.kernel.org + +Add missing timer reset definitions for BCM63268. + +Signed-off-by: Álvaro Fernández Rojas +Acked-by: Rob Herring +--- + v4: no changes + v3: no changes + v2: change commit title, as suggested by Stephen Boyd + + include/dt-bindings/reset/bcm63268-reset.h | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/include/dt-bindings/reset/bcm63268-reset.h ++++ b/include/dt-bindings/reset/bcm63268-reset.h +@@ -23,4 +23,8 @@ + #define BCM63268_RST_PCIE_HARD 17 + #define BCM63268_RST_GPHY 18 + ++#define BCM63268_TRST_SW 29 ++#define BCM63268_TRST_HW 30 ++#define BCM63268_TRST_POR 31 ++ + #endif /* __DT_BINDINGS_RESET_BCM63268_H */ diff --git a/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch b/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch new file mode 100644 index 000000000..7e500cd1b --- /dev/null +++ b/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch @@ -0,0 +1,345 @@ +From patchwork Wed Mar 22 17:15:15 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= + +X-Patchwork-Id: 13184392 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 199D9C76196 + for ; Wed, 22 Mar 2023 17:16:11 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S231512AbjCVRQJ (ORCPT ); + Wed, 22 Mar 2023 13:16:09 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58942 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S231442AbjCVRP5 (ORCPT + ); Wed, 22 Mar 2023 13:15:57 -0400 +Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com + [IPv6:2a00:1450:4864:20::32c]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DDB36487D; + Wed, 22 Mar 2023 10:15:27 -0700 (PDT) +Received: by mail-wm1-x32c.google.com with SMTP id + i5-20020a05600c354500b003edd24054e0so6717370wmq.4; + Wed, 22 Mar 2023 10:15:27 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; t=1679505325; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=; + b=Y1mva2Bt3sUbKxLgEUS331CJbGxUc4z8kTQW8qiHWGhYlFKtm+d5z4sT40E5BeZAnU + zmTbCI7jbroe9NYBxGUmSli6LNVDPjND80ChbhWTqbqMQTmeQFWut9KmeBWK6Oze2lC/ + XMSOorUzowjcU2xtHNrzoq2KH2pstW573lsB8WnzFVfhMaRkE9DfRr6WNyA7zC8DyxM5 + ezxlCQtCmgPfCqlyksbIDKrgrRf3GiUR0yUd6xRU+MssyvH1FkYGDCerPctDto6lGHBz + 8Y15jT3l6OnQMT6dkekgpPF5/XrSUY93u9g0B4U8+0dhNj+K7vmDen+jqdess+tpLnq/ + gFrA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; t=1679505325; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=; + b=Ym4+u8bbTQGNkewUBrLf+89vE0EFJBQp2f1crwUxZFboKTROF9ltZonY1CGepo7b0B + fkx3TbWQy5X65g3ScuieqtClCI8WanPeNBJ48+JipJYO3ODVNBxnVaTuW/0FOIcahfqe + sG5GvggHhzRz+Yeybsbnupmzxnw8Ez0BpMl3p7zcjHL7BGZDdOOX2Zbw3zfyYa5sg2nX + UXYJT36zy2h39gxUsy9QkhQ76CG3w6omniohZpYidpojpiDjbOy0nKFky4kUe+YyA1fF + 4IBhjAm6mH+uh6wHSG1qj+NAXHs0xDDJps16PbJwAgL7Qt9K5WW+R/UAYPmHFgaRIHOw + /seA== +X-Gm-Message-State: AO0yUKXRtoYO8Nfus6Ca8lhM39P1Xn6TGkhatEfoISd1YNOkTJJN2hW+ + xRphLgxlzNfCLcVPlpGK9dk= +X-Google-Smtp-Source: + AK7set9VnMEykugk8ZYnkXuqK41bX1dzlvKsAXHEjr8i2NZBld0buKhQLcGYEcwxnBgVTtC7eRGfXw== +X-Received: by 2002:a1c:7c0b:0:b0:3e2:1dac:b071 with SMTP id + x11-20020a1c7c0b000000b003e21dacb071mr178053wmc.13.1679505325582; + Wed, 22 Mar 2023 10:15:25 -0700 (PDT) +Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. + [79.146.124.255]) + by smtp.gmail.com with ESMTPSA id + v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.24 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Wed, 22 Mar 2023 10:15:25 -0700 (PDT) +From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, + krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, + f.fainelli@gmail.com, jonas.gorski@gmail.com, + william.zhang@broadcom.com, linux-clk@vger.kernel.org, + devicetree@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= +Subject: [PATCH v4 4/4] clk: bcm: Add BCM63268 timer clock and reset driver +Date: Wed, 22 Mar 2023 18:15:15 +0100 +Message-Id: <20230322171515.120353-5-noltari@gmail.com> +X-Mailer: git-send-email 2.30.2 +In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> +References: <20230322171515.120353-1-noltari@gmail.com> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: linux-clk@vger.kernel.org + +Add driver for BCM63268 timer clock and reset controller. + +Signed-off-by: Álvaro Fernández Rojas +--- + v4: add changes suggested by Stephen Boyd: + - Usage of of_device_get_match_data() isn't needed. + - Use devm_clk_hw_register_gate(). + - Drop clk_hw_unregister_gate(). + v3: add missing include to fix build warning + v2: add changes suggested by Stephen Boyd + + drivers/clk/bcm/Kconfig | 9 ++ + drivers/clk/bcm/Makefile | 1 + + drivers/clk/bcm/clk-bcm63268-timer.c | 215 +++++++++++++++++++++++++++ + 3 files changed, 225 insertions(+) + create mode 100644 drivers/clk/bcm/clk-bcm63268-timer.c + +--- a/drivers/clk/bcm/Kconfig ++++ b/drivers/clk/bcm/Kconfig +@@ -37,6 +37,15 @@ config CLK_BCM_63XX_GATE + Enable common clock framework support for Broadcom BCM63xx DSL SoCs + based on the MIPS architecture + ++config CLK_BCM63268_TIMER ++ bool "Broadcom BCM63268 timer clock and reset support" ++ depends on BMIPS_GENERIC || COMPILE_TEST ++ default BMIPS_GENERIC ++ select RESET_CONTROLLER ++ help ++ Enable timer clock and reset support for Broadcom BCM63268 DSL SoCs ++ based on the MIPS architecture. ++ + config CLK_BCM_KONA + bool "Broadcom Kona CCU clock support" + depends on ARCH_BCM_MOBILE || COMPILE_TEST +--- a/drivers/clk/bcm/Makefile ++++ b/drivers/clk/bcm/Makefile +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o + obj-$(CONFIG_CLK_BCM_63XX_GATE) += clk-bcm63xx-gate.o ++obj-$(CONFIG_CLK_BCM63268_TIMER) += clk-bcm63268-timer.o + obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o + obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o + obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o +--- /dev/null ++++ b/drivers/clk/bcm/clk-bcm63268-timer.c +@@ -0,0 +1,215 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * BCM63268 Timer Clock and Reset Controller Driver ++ * ++ * Copyright (C) 2023 Álvaro Fernández Rojas ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define BCM63268_TIMER_RESET_SLEEP_MIN_US 10000 ++#define BCM63268_TIMER_RESET_SLEEP_MAX_US 20000 ++ ++struct bcm63268_tclkrst_hw { ++ void __iomem *regs; ++ spinlock_t lock; ++ ++ struct reset_controller_dev rcdev; ++ struct clk_hw_onecell_data data; ++}; ++ ++struct bcm63268_tclk_table_entry { ++ const char * const name; ++ u8 bit; ++}; ++ ++static const struct bcm63268_tclk_table_entry bcm63268_timer_clocks[] = { ++ { ++ .name = "ephy1", ++ .bit = BCM63268_TCLK_EPHY1, ++ }, { ++ .name = "ephy2", ++ .bit = BCM63268_TCLK_EPHY2, ++ }, { ++ .name = "ephy3", ++ .bit = BCM63268_TCLK_EPHY3, ++ }, { ++ .name = "gphy1", ++ .bit = BCM63268_TCLK_GPHY1, ++ }, { ++ .name = "dsl", ++ .bit = BCM63268_TCLK_DSL, ++ }, { ++ .name = "wakeon_ephy", ++ .bit = BCM63268_TCLK_WAKEON_EPHY, ++ }, { ++ .name = "wakeon_dsl", ++ .bit = BCM63268_TCLK_WAKEON_DSL, ++ }, { ++ .name = "fap1_pll", ++ .bit = BCM63268_TCLK_FAP1, ++ }, { ++ .name = "fap2_pll", ++ .bit = BCM63268_TCLK_FAP2, ++ }, { ++ .name = "uto_50", ++ .bit = BCM63268_TCLK_UTO_50, ++ }, { ++ .name = "uto_extin", ++ .bit = BCM63268_TCLK_UTO_EXTIN, ++ }, { ++ .name = "usb_ref", ++ .bit = BCM63268_TCLK_USB_REF, ++ }, { ++ /* sentinel */ ++ } ++}; ++ ++static inline struct bcm63268_tclkrst_hw * ++to_bcm63268_timer_reset(struct reset_controller_dev *rcdev) ++{ ++ return container_of(rcdev, struct bcm63268_tclkrst_hw, rcdev); ++} ++ ++static int bcm63268_timer_reset_update(struct reset_controller_dev *rcdev, ++ unsigned long id, bool assert) ++{ ++ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev); ++ unsigned long flags; ++ uint32_t val; ++ ++ spin_lock_irqsave(&reset->lock, flags); ++ val = __raw_readl(reset->regs); ++ if (assert) ++ val &= ~BIT(id); ++ else ++ val |= BIT(id); ++ __raw_writel(val, reset->regs); ++ spin_unlock_irqrestore(&reset->lock, flags); ++ ++ return 0; ++} ++ ++static int bcm63268_timer_reset_assert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ return bcm63268_timer_reset_update(rcdev, id, true); ++} ++ ++static int bcm63268_timer_reset_deassert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ return bcm63268_timer_reset_update(rcdev, id, false); ++} ++ ++static int bcm63268_timer_reset_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ bcm63268_timer_reset_update(rcdev, id, true); ++ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US, ++ BCM63268_TIMER_RESET_SLEEP_MAX_US); ++ ++ bcm63268_timer_reset_update(rcdev, id, false); ++ /* ++ * Ensure component is taken out reset state by sleeping also after ++ * deasserting the reset. Otherwise, the component may not be ready ++ * for operation. ++ */ ++ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US, ++ BCM63268_TIMER_RESET_SLEEP_MAX_US); ++ ++ return 0; ++} ++ ++static int bcm63268_timer_reset_status(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev); ++ ++ return !(__raw_readl(reset->regs) & BIT(id)); ++} ++ ++static struct reset_control_ops bcm63268_timer_reset_ops = { ++ .assert = bcm63268_timer_reset_assert, ++ .deassert = bcm63268_timer_reset_deassert, ++ .reset = bcm63268_timer_reset_reset, ++ .status = bcm63268_timer_reset_status, ++}; ++ ++static int bcm63268_tclk_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ const struct bcm63268_tclk_table_entry *entry; ++ struct bcm63268_tclkrst_hw *hw; ++ struct clk_hw *clk; ++ u8 maxbit = 0; ++ int i, ret; ++ ++ for (entry = bcm63268_timer_clocks; entry->name; entry++) ++ maxbit = max(maxbit, entry->bit); ++ maxbit++; ++ ++ hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit), ++ GFP_KERNEL); ++ if (!hw) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, hw); ++ ++ spin_lock_init(&hw->lock); ++ ++ hw->data.num = maxbit; ++ for (i = 0; i < maxbit; i++) ++ hw->data.hws[i] = ERR_PTR(-ENODEV); ++ ++ hw->regs = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(hw->regs)) ++ return PTR_ERR(hw->regs); ++ ++ for (entry = bcm63268_timer_clocks; entry->name; entry++) { ++ clk = devm_clk_hw_register_gate(dev, entry->name, NULL, 0, ++ hw->regs, entry->bit, ++ CLK_GATE_BIG_ENDIAN, ++ &hw->lock); ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ hw->data.hws[entry->bit] = clk; ++ } ++ ++ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, ++ &hw->data); ++ if (ret) ++ return ret; ++ ++ hw->rcdev.of_node = dev->of_node; ++ hw->rcdev.ops = &bcm63268_timer_reset_ops; ++ ++ ret = devm_reset_controller_register(dev, &hw->rcdev); ++ if (ret) ++ dev_err(dev, "Failed to register reset controller\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm63268_tclk_dt_ids[] = { ++ { .compatible = "brcm,bcm63268-timer-clocks" }, ++ { /* sentinel */ } ++}; ++ ++static struct platform_driver bcm63268_tclk = { ++ .probe = bcm63268_tclk_probe, ++ .driver = { ++ .name = "bcm63268-timer-clock", ++ .of_match_table = bcm63268_tclk_dt_ids, ++ }, ++}; ++builtin_platform_driver(bcm63268_tclk); 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 deleted file mode 100644 index e32b46569..000000000 --- a/target/linux/generic/pending-6.1/930-qcom-qmi-helpers.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/soc/qcom/Kconfig -+++ b/drivers/soc/qcom/Kconfig -@@ -93,7 +93,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