]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
generic: 6.18: remove obsolete backport patches
authorMieczyslaw Nalewaj <namiltd@yahoo.com>
Fri, 27 Mar 2026 16:48:03 +0000 (17:48 +0100)
committerRobert Marko <robimarko@gmail.com>
Sat, 28 Mar 2026 10:51:09 +0000 (11:51 +0100)
Remove obsolete backport patches already included in kernel 6.18.

Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
Link: https://github.com/openwrt/openwrt/pull/21078
Signed-off-by: Robert Marko <robimarko@gmail.com>
281 files changed:
target/linux/generic/backport-6.18/152-v6.16-net-wireguard-add-nonstring-annotation-to-fix-build-with-GCC15.patch [deleted file]
target/linux/generic/backport-6.18/200-01-v6.13-jiffies-Define-secs_to_jiffies.patch [deleted file]
target/linux/generic/backport-6.18/200-02-v6.14-jiffies-Cast-to-unsigned-long-in-secs_to_jiffies-con.patch [deleted file]
target/linux/generic/backport-6.18/201-v6.13-of-property-add-of_graph_get_next_port.patch [deleted file]
target/linux/generic/backport-6.18/202-v6.13-clk-Provide-devm_clk_bulk_get_all_enabled-helper.patch [deleted file]
target/linux/generic/backport-6.18/203-01-v6.13-of-address-Rework-bus-matching-to-avoid-warnings.patch [deleted file]
target/linux/generic/backport-6.18/203-02-v6.13-of-address-Fix-WARN-when-attempting-translating-non-.patch [deleted file]
target/linux/generic/backport-6.18/205-v6.16-of-reserved_mem-Add-functions-to-parse-memory-region.patch [deleted file]
target/linux/generic/backport-6.18/210-v6.13-fortify-Hide-run-time-copy-size-from-value-range-tracking.patch [deleted file]
target/linux/generic/backport-6.18/212-v6.17-of-reserved_mem-Add-missing-IORESOURCE_MEM-flag-on-r.patch [deleted file]
target/linux/generic/backport-6.18/400-v6.14-mtd-spinand-add-support-for-FORESEE-F35SQA001G.patch [deleted file]
target/linux/generic/backport-6.18/401-v6.17-mtd-spinand-add-support-for-FudanMicro-FM25S01A.patch [deleted file]
target/linux/generic/backport-6.18/402-v6.18-mtd-nand-move-chunk-to-core.patch [deleted file]
target/linux/generic/backport-6.18/404-v6.19-mtd-spinand-fmsh-remove-QE-bit-for-FM25S01A-flash.patch [deleted file]
target/linux/generic/backport-6.18/410-01-v6.14-mtd-rawnand-qcom-cleanup-qcom_nandc-driver.patch [deleted file]
target/linux/generic/backport-6.18/410-02-v6.14-mtd-rawnand-qcom-Add-qcom-prefix-to-common-api.patch [deleted file]
target/linux/generic/backport-6.18/410-03-v6.14-mtd-nand-Add-qpic_common-API-file.patch [deleted file]
target/linux/generic/backport-6.18/410-04-v6.14-mtd-rawnand-qcom-use-FIELD_PREP-and-GENMASK.patch [deleted file]
target/linux/generic/backport-6.18/410-05-v6.14-mtd-rawnand-qcom-fix-broken-config-in-qcom_param_pag.patch [deleted file]
target/linux/generic/backport-6.18/410-06-v6.14-mtd-rawnand-qcom-Fix-build-issue-on-x86-architecture.patch [deleted file]
target/linux/generic/backport-6.18/410-07-v6.15-spi-spi-qpic-add-driver-for-QCOM-SPI-NAND-flash-Inte.patch [deleted file]
target/linux/generic/backport-6.18/410-08-v6.15-spi-spi-qpic-snand-Fix-ECC_CFG_ECC_DISABLE-shift-in-.patch [deleted file]
target/linux/generic/backport-6.18/410-09-v6.15-spi-spi-qpic-snand-avoid-memleak-in-qcom_spi_ecc_ini.patch [deleted file]
target/linux/generic/backport-6.18/410-10-v6.15-spi-SPI_QPIC_SNAND-should-be-tristate-and-depend-on-.patch [deleted file]
target/linux/generic/backport-6.18/410-11-v6.15-spi-spi-qpic-snand-propagate-errors-from-qcom_spi_block_erase.patch [deleted file]
target/linux/generic/backport-6.18/410-12-v6.15-spi-spi-qpic-snand-fix-NAND_READ_LOCATION_2-register-handling.patch [deleted file]
target/linux/generic/backport-6.18/410-13-v6.15-spi-spi-qpic-snand-use-kmalloc-for-OOB-buffer-alloca.patch [deleted file]
target/linux/generic/backport-6.18/410-14-v6.16-spi-spi-qpic-snand-remove-unused-wlen-member-of-struct-qpic_spi_nand.patch [deleted file]
target/linux/generic/backport-6.18/411-v6.15-mtd-nand-Drop-explicit-test-for-built-in-CONFIG_SPI_.patch [deleted file]
target/linux/generic/backport-6.18/412-v6.16-next-spi-spi-qpic-snand-validate-user-chip-specific-ECC-properties.patch [deleted file]
target/linux/generic/backport-6.18/413-v6.16-spi-spi-qpic-snand-use-CW_PER_PAGE_MASK-bitmask.patch [deleted file]
target/linux/generic/backport-6.18/414-v6.16-spi-spi-qpic-snand-reallocate-BAM-transactions.patch [deleted file]
target/linux/generic/backport-6.18/415-v6.16-spi-spi-qpic-snand-don-t-hardcode-ECC-steps.patch [deleted file]
target/linux/generic/backport-6.18/416-v6.17-mtd-nand-qpic-common-add-defines-for-ECC_MODE-values.patch [deleted file]
target/linux/generic/backport-6.18/417-v6.17-spi-spi-qpic-snand-add-support-for-8-bits-ECC-strength.patch [deleted file]
target/linux/generic/backport-6.18/418-v6.17-spi-spi-qpic-snand-use-correct-CW_PER_PAGE-value-for.patch [deleted file]
target/linux/generic/backport-6.18/419-v6.17-spi-spi-qpic-snand-fix-calculating-of-ECC-OOB-region.patch [deleted file]
target/linux/generic/backport-6.18/420-01-v6.16-mtd-rawnand-brcmnand-remove-unused-parameters.patch [deleted file]
target/linux/generic/backport-6.18/420-02-v6.16-mtd-nand-brcmnand-fix-NAND-timeout-when-accessing-eM.patch [deleted file]
target/linux/generic/backport-6.18/420-03-v6.16-mtd-rawnand-brcmnand-legacy-exec_op-implementation.patch [deleted file]
target/linux/generic/backport-6.18/422-v6.17-spi-spi-qpic-snand-unregister-ECC-engine-on-probe-er.patch [deleted file]
target/linux/generic/backport-6.18/429-01-v6.18-mtd-spinand-fix-direct-mapping-creation-sizes.patch [deleted file]
target/linux/generic/backport-6.18/429-02-v6.18-mtd-spinand-try-a-regular-dirmap-if-creating-a-di.patch [deleted file]
target/linux/generic/backport-6.18/429-03-v6.18-mtd-spinand-repeat-reading-in-regular-mode-if-con.patch [deleted file]
target/linux/generic/backport-6.18/430-v6.14-mtd-spinand-Introduce-a-way-to-avoid-raw-access.patch [deleted file]
target/linux/generic/backport-6.18/431-v6.14-mtd-spinand-Add-support-for-SkyHigh-S35ML-3-family.patch [deleted file]
target/linux/generic/backport-6.18/500-01-v6.13-block-add-support-for-defining-read-only-partitions.patch [deleted file]
target/linux/generic/backport-6.18/500-02-v6.13-block-introduce-add_disk_fwnode.patch [deleted file]
target/linux/generic/backport-6.18/500-03-v6.13-mmc-block-attach-partitions-fwnode-if-found-in-mmc-c.patch [deleted file]
target/linux/generic/backport-6.18/500-04-v6.13-block-add-support-for-partition-table-defined-in-OF.patch [deleted file]
target/linux/generic/backport-6.18/600-01-v6.13-net-phylink-move-manual-flow-control-setting.patch [deleted file]
target/linux/generic/backport-6.18/600-02-v6.13-net-phylink-move-MLO_AN_FIXED-resolve-handling-to-if.patch [deleted file]
target/linux/generic/backport-6.18/600-03-v6.13-net-phylink-move-MLO_AN_PHY-resolve-handling-to-if-s.patch [deleted file]
target/linux/generic/backport-6.18/600-04-v6.13-net-phylink-remove-switch-statement-in-resolve-handl.patch [deleted file]
target/linux/generic/backport-6.18/600-05-v6.13-net-phylink-clean-up-phylink_resolve.patch [deleted file]
target/linux/generic/backport-6.18/601-01-v6.14-net-phylink-pass-phylink-and-pcs-into-phylink_pcs_ne.patch [deleted file]
target/linux/generic/backport-6.18/601-02-v6.14-net-phylink-split-cur_link_an_mode-into-requested-an.patch [deleted file]
target/linux/generic/backport-6.18/601-03-v6.14-net-phylink-add-debug-for-phylink_major_config.patch [deleted file]
target/linux/generic/backport-6.18/601-04-v6.14-net-phy-add-phy_inband_caps.patch [deleted file]
target/linux/generic/backport-6.18/601-05-v6.14-net-phy-bcm84881-implement-phy_inband_caps-method.patch [deleted file]
target/linux/generic/backport-6.18/601-06-v6.14-net-phy-marvell-implement-phy_inband_caps-method.patch [deleted file]
target/linux/generic/backport-6.18/601-07-v6.14-net-phy-add-phy_config_inband.patch [deleted file]
target/linux/generic/backport-6.18/601-08-v6.14-net-phy-marvell-implement-config_inband-method.patch [deleted file]
target/linux/generic/backport-6.18/601-09-v6.14-net-phylink-add-pcs_inband_caps-method.patch [deleted file]
target/linux/generic/backport-6.18/601-10-v6.14-net-mvneta-implement-pcs_inband_caps-method.patch [deleted file]
target/linux/generic/backport-6.18/601-11-v6.14-net-mvpp2-implement-pcs_inband_caps-method.patch [deleted file]
target/linux/generic/backport-6.18/601-12-v6.14-net-phylink-add-negotiation-of-in-band-capabilities.patch [deleted file]
target/linux/generic/backport-6.18/601-13-v6.14-net-phylink-remove-phylink_phy_no_inband.patch [deleted file]
target/linux/generic/backport-6.18/602-01-v6.14-net-pcs-pcs-lynx-implement-pcs_inband_caps-method.patch [deleted file]
target/linux/generic/backport-6.18/602-02-v6.14-net-pcs-pcs-mtk-lynxi-implement-pcs_inband_caps-meth.patch [deleted file]
target/linux/generic/backport-6.18/602-03-v6.14-net-pcs-xpcs-implement-pcs_inband_caps-method.patch [deleted file]
target/linux/generic/backport-6.18/605-02-v6.17-net-phylink-provide-phylink_get_inband_type.patch [deleted file]
target/linux/generic/backport-6.18/605-03-v6.17-net-phylink-disable-autoneg-for-interfaces-that-have.patch [deleted file]
target/linux/generic/backport-6.18/610-01-v6.13-net-dsa-use-ethtool-string-helpers.patch [deleted file]
target/linux/generic/backport-6.18/610-02-v6.15-net-dsa-b53-mdio-add-support-for-BCM53101.patch [deleted file]
target/linux/generic/backport-6.18/610-03-v6.16-net-dsa-b53-implement-setting-ageing-time.patch [deleted file]
target/linux/generic/backport-6.18/610-04-v6.16-net-dsa-b53-do-not-configure-bcm63xx-s-IMP-port-inte.patch [deleted file]
target/linux/generic/backport-6.18/611-01-v6.17-net-dsa-tag_brcm-add-support-for-legacy-FCS-tags.patch [deleted file]
target/linux/generic/backport-6.18/611-02-v6.17-net-dsa-b53-support-legacy-FCS-tags.patch [deleted file]
target/linux/generic/backport-6.18/611-03-v6.17-net-dsa-b53-detect-BCM5325-variants.patch [deleted file]
target/linux/generic/backport-6.18/611-04-v6.17-net-dsa-b53-add-support-for-FDB-operations-on-5325-5365.patch [deleted file]
target/linux/generic/backport-6.18/611-05-v6.17-net-dsa-b53-prevent-FAST_AGE-access-on-BCM5325.patch [deleted file]
target/linux/generic/backport-6.18/611-06-v6.17-net-dsa-b53-prevent-BRCM_HDR-access-on-older-devices.patch [deleted file]
target/linux/generic/backport-6.18/611-07-v6.17-net-dsa-b53-fix-unicast-multicast-flooding-on-BCM5325.patch [deleted file]
target/linux/generic/backport-6.18/611-08-v6.18-net-dsa-b53-Add-phy_enable-phy_disable-methods.patch [deleted file]
target/linux/generic/backport-6.18/611-09-v6.18-net-dsa-b53-Define-chip-IDs-for-more-bcm63xx-SoCs.patch [deleted file]
target/linux/generic/backport-6.18/611-10-v6.18-net-dsa-b53-mmap-Add-syscon-reference-and-register-layout-for-bcm63268.patch [deleted file]
target/linux/generic/backport-6.18/611-11-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6318.patch [deleted file]
target/linux/generic/backport-6.18/611-12-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6368.patch [deleted file]
target/linux/generic/backport-6.18/611-13-v6.18-net-dsa-b53-mmap-Implement-bcm63xx-ephy-power-control.patch [deleted file]
target/linux/generic/backport-6.18/611-14-v6.18-net-dsa-b53-mmap-Add-gphy-port-to-phy-info-for-bcm63268.patch [deleted file]
target/linux/generic/backport-6.18/611-15-v6.18-net-dsa-b53-mmap-Implement-bcm63268-gphy-power-control.patch [deleted file]
target/linux/generic/backport-6.18/611-16-v6.18-net-dsa-b53-fix-reserved-register-access-in-b53_fdb_dump.patch [deleted file]
target/linux/generic/backport-6.18/611-17-v6.18-net-dsa-b53-fix-ageing-time-for-BCM53101.patch [deleted file]
target/linux/generic/backport-6.18/611-18-v6.18-net-dsa-b53-properly-bound-ARL-searches-for-4-ARL-bin-chips.patch [deleted file]
target/linux/generic/backport-6.18/611-19-v6.18-net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-offloaded.patch [deleted file]
target/linux/generic/backport-6.18/612-01-v6.19-net-dsa-b53-b53_arl_read-25-use-the-entry-for-comparision.patch [deleted file]
target/linux/generic/backport-6.18/612-02-v6.19-net-dsa-b53-move-reading-ARL-entries-into-their-own-function.patch [deleted file]
target/linux/generic/backport-6.18/612-03-v6.19-net-dsa-b53-move-writing-ARL-entries-into-their-own-functions.patch [deleted file]
target/linux/generic/backport-6.18/612-04-v6.19-net-dsa-b53-provide-accessors-for-accessing-ARL_SRCH_CTL.patch [deleted file]
target/linux/generic/backport-6.18/612-05-v6.19-net-dsa-b53-split-reading-search-entry-into-their-own-functions.patch [deleted file]
target/linux/generic/backport-6.18/612-06-v6.19-net-dsa-b53-move-ARL-entry-functions-into-ops-struct.patch [deleted file]
target/linux/generic/backport-6.18/612-07-v6.19-net-dsa-b53-add-support-for-5389-5397-5398-ARL-entry-format.patch [deleted file]
target/linux/generic/backport-6.18/612-08-v6.19-net-dsa-b53-add-support-for-bcm63xx-ARL-entry-format.patch [deleted file]
target/linux/generic/backport-6.18/613-01-v6.19-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch [deleted file]
target/linux/generic/backport-6.18/613-02-v6.19-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch [deleted file]
target/linux/generic/backport-6.18/613-03-v6.19-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch [deleted file]
target/linux/generic/backport-6.18/613-04-v6.19-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch [deleted file]
target/linux/generic/backport-6.18/613-05-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch [deleted file]
target/linux/generic/backport-6.18/613-06-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch [deleted file]
target/linux/generic/backport-6.18/620-v6.15-ppp-use-IFF_NO_QUEUE-in-virtual-interfaces.patch [deleted file]
target/linux/generic/backport-6.18/621-v6.17-ppp-convert-to-percpu-netstats.patch [deleted file]
target/linux/generic/backport-6.18/622-v6.18-ppp-remove-rwlock-usage.patch [deleted file]
target/linux/generic/backport-6.18/623-v6.18-pppoe-remove-rwlock-usage.patch [deleted file]
target/linux/generic/backport-6.18/624-v6.18-pppoe-drop-sock-reference-counting-on-fast-path.patch [deleted file]
target/linux/generic/backport-6.18/626-01-v6.13-net-pse-pd-Add-power-limit-check.patch [deleted file]
target/linux/generic/backport-6.18/626-02-v6.13-net-pse-pd-tps23881-Simplify-function-returns.patch [deleted file]
target/linux/generic/backport-6.18/626-03-v6.13-net-pse-pd-tps23881-Use-helpers-to-calculate-bit-offset.patch [deleted file]
target/linux/generic/backport-6.18/626-04-v6.13-net-pse-pd-tps23881-Add-missing-configuration-register.patch [deleted file]
target/linux/generic/backport-6.18/626-05-v6.13-net-pse-pd-Split-ethtool_get_status-into-multiple-callbacks.patch [deleted file]
target/linux/generic/backport-6.18/626-06-v6.13-net-pse-pd-Remove-is_enabled-callback-from-drivers.patch [deleted file]
target/linux/generic/backport-6.18/626-07-v6.13-net-pse-pd-tps23881-Add-power-limit-and-measurement-features.patch [deleted file]
target/linux/generic/backport-6.18/626-08-v6.13-net-pse-pd-Fix-missing-PI-of_node-description.patch [deleted file]
target/linux/generic/backport-6.18/626-09-v6.13-net-pse-pd-Clean-ethtool-header-of-PSE-structures.patch [deleted file]
target/linux/generic/backport-6.18/626-10-v6.17-net-pse-pd-Introduce-attached_phydev-to-pse-control.patch [deleted file]
target/linux/generic/backport-6.18/626-11-v6.17-net-pse-pd-Add-support-for-reporting-events.patch [deleted file]
target/linux/generic/backport-6.18/626-12-v6.17-net-pse-pd-tps23881-Add-support-for-PSE-events.patch [deleted file]
target/linux/generic/backport-6.18/626-13-v6.17-net-pse-pd-Add-support-for-PSE-power-domains.patch [deleted file]
target/linux/generic/backport-6.18/626-14-v6.17-net-pse-pd-ethtool-Add-support-for-power-domains-index.patch [deleted file]
target/linux/generic/backport-6.18/626-15-v6.17-net-pse-pd-Add-helper-to-report-hw-enable-status.patch [deleted file]
target/linux/generic/backport-6.18/626-16-v6.17-net-pse-pd-Add-support-for-budget-evaluation-strategies.patch [deleted file]
target/linux/generic/backport-6.18/626-16b-v6.17-regulator-Add-support-for-power-budget.patch [deleted file]
target/linux/generic/backport-6.18/626-17-v6.17-net-pse-pd-pd692x0-Add-PSE-PI-priority-feature.patch [deleted file]
target/linux/generic/backport-6.18/626-18-v6.17-net-pse-pd-pd692x0-Add-controller-and-manager-power.patch [deleted file]
target/linux/generic/backport-6.18/626-19-v6.17-net-pse-pd-tps23881-Add-static-port-priority-feature.patch [deleted file]
target/linux/generic/backport-6.18/626-20-v6.17-net-pse-pd-pd692x0-reduce-stack-usage.patch [deleted file]
target/linux/generic/backport-6.18/626-21-v6.18-net-pse-pd-pd692x0-Fix-power-budget-leak.patch [deleted file]
target/linux/generic/backport-6.18/626-22-v6.18-net-pse-pd-pd692x0-Skip-power-budget-when-undefined.patch [deleted file]
target/linux/generic/backport-6.18/626-23-v6.18-net-pse-pd-Add-Si3474-PSE-controller-driver.patch [deleted file]
target/linux/generic/backport-6.18/626-24-v6.19-net-pse-pd-tps23881-Fix-current-measurement-scaling.patch [deleted file]
target/linux/generic/backport-6.18/626-v6.16-net-bridge-locally-receive-all-multicast-packets-if-.patch [deleted file]
target/linux/generic/backport-6.18/627-01-v6.17-net-pse-pd-Add-ethtool_netlink_generated-header.patch [deleted file]
target/linux/generic/backport-6.18/627-02-v6.17-net-ethtool-Add-PSE-port-priority-support.patch [deleted file]
target/linux/generic/backport-6.18/630-v6.13-net-usb-qmi_wwan-add-Quectel-RG255C.patch [deleted file]
target/linux/generic/backport-6.18/630-v6.14-PM-sleep-wakeirq-Introduce-device-managed-variant-of.patch [deleted file]
target/linux/generic/backport-6.18/710-v6.16-igc-enable-HW-vlan-tag-insertion-stripping-by-defaul.patch [deleted file]
target/linux/generic/backport-6.18/720-01-v6.13-net-phy-mediatek-ge-soc-Fix-coding-style.patch [deleted file]
target/linux/generic/backport-6.18/720-02-v6.13-net-phy-mediatek-ge-soc-Shrink-line-wrapping-to-80-c.patch [deleted file]
target/linux/generic/backport-6.18/720-03-v6.13-net-phy-mediatek-ge-soc-Propagate-error-code-correct.patch [deleted file]
target/linux/generic/backport-6.18/720-04-v6.13-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch [deleted file]
target/linux/generic/backport-6.18/720-05-v6.13-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch [deleted file]
target/linux/generic/backport-6.18/720-06-v6.13-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch [deleted file]
target/linux/generic/backport-6.18/720-07-v6.13-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch [deleted file]
target/linux/generic/backport-6.18/720-08-v6.13-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch [deleted file]
target/linux/generic/backport-6.18/720-09-v6.14-net-phy-Constify-struct-mdio_device_id.patch [deleted file]
target/linux/generic/backport-6.18/720-10-v6.15-net-phy-mediatek-Change-to-more-meaningful-macros.patch [deleted file]
target/linux/generic/backport-6.18/720-11-v6.15-net-phy-mediatek-Add-token-ring-access-helper-functi.patch [deleted file]
target/linux/generic/backport-6.18/720-12-v6.15-net-phy-mediatek-Add-token-ring-set-bit-operation-su.patch [deleted file]
target/linux/generic/backport-6.18/720-13-v6.15-net-phy-mediatek-Add-token-ring-clear-bit-operation-.patch [deleted file]
target/linux/generic/backport-6.18/720-14-v6.15-net-phy-mediatek-Move-some-macros-to-phy-lib-for-lat.patch [deleted file]
target/linux/generic/backport-6.18/720-15-v6.16-net-phy-mediatek-permit-to-compile-test-GE-SOC-PHY-d.patch [deleted file]
target/linux/generic/backport-6.18/720-16-v6.16-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch [deleted file]
target/linux/generic/backport-6.18/720-17-v6.16-net-phy-mediatek-init-val-in-.phy_led_polarity_set-f.patch [deleted file]
target/linux/generic/backport-6.18/721-01-v6.15-net-ethernet-mediatek-add-EEE-support.patch [deleted file]
target/linux/generic/backport-6.18/730-01-v6.13-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch [deleted file]
target/linux/generic/backport-6.18/730-02-v6.13-net-phy-aquantia-fix-return-value-check-in-aqr107_co.patch [deleted file]
target/linux/generic/backport-6.18/730-03-v6.13-net-phy-support-active-high-property-for-PHY-LEDs.patch [deleted file]
target/linux/generic/backport-6.18/730-04-v6.13-net-phy-aquantia-correctly-describe-LED-polarity-ove.patch [deleted file]
target/linux/generic/backport-6.18/730-05-v6.13-net-phy-mxl-gpy-add-basic-LED-support.patch [deleted file]
target/linux/generic/backport-6.18/730-06-v6.13-net-phy-mxl-gpy-add-missing-support-for-TRIGGER_NETD.patch [deleted file]
target/linux/generic/backport-6.18/730-07-v6.13-net-phy-mxl-gpy-correctly-describe-LED-polarity.patch [deleted file]
target/linux/generic/backport-6.18/730-08-v6.13-net-phy-intel-xway-add-support-for-PHY-LEDs.patch [deleted file]
target/linux/generic/backport-6.18/730-09-v6.18-net-phy-mxl-gpy-fix-link-properties-on-USXGMII-and-i.patch [deleted file]
target/linux/generic/backport-6.18/731-v6.18-net-mediatek-wed-Introduce-MT7992-WED-support-to-MT7.patch [deleted file]
target/linux/generic/backport-6.18/732-v6.18-wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch [deleted file]
target/linux/generic/backport-6.18/733-v6.18-net-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-fo.patch [deleted file]
target/linux/generic/backport-6.18/735-v6.13-net-phy-avoid-undefined-behavior-in-_led_polarity_se.patch [deleted file]
target/linux/generic/backport-6.18/740-v6.13-net-dsa-mv88e6xxx-Support-LED-control.patch [deleted file]
target/linux/generic/backport-6.18/741-v6.13-net-dsa-mv88e6xxx-fix-unreleased-fwnode_handle-in-se.patch [deleted file]
target/linux/generic/backport-6.18/742-v6.17-net-dsa-mv88e6xxx-Fix-fwnode-reference-leaks-in-mv88.patch [deleted file]
target/linux/generic/backport-6.18/760-v6.18-net-phy-introduce-phy_id_compare_model-PHY-ID-helper.patch [deleted file]
target/linux/generic/backport-6.18/780-01-v6.13-r8169-remove-original-workaround-for-RTL8125-broken-.patch [deleted file]
target/linux/generic/backport-6.18/780-02-v6.13-r8169-enable-SG-TSO-on-selected-chip-versions-per-de.patch [deleted file]
target/linux/generic/backport-6.18/780-03-v6.13-r8169-implement-additional-ethtool-stats-ops.patch [deleted file]
target/linux/generic/backport-6.18/780-04-v6.13-r8169-don-t-take-RTNL-lock-in-rtl_task.patch [deleted file]
target/linux/generic/backport-6.18/780-05-v6.13-replace-custom-flag-with-disable_work-et-al.patch [deleted file]
target/linux/generic/backport-6.18/780-06-v6.13-r8169-avoid-duplicated-messages-if-loading-firmware-.patch [deleted file]
target/linux/generic/backport-6.18/780-07-v6.13-r8169-remove-rtl_dash_loop_wait_high-low.patch [deleted file]
target/linux/generic/backport-6.18/780-08-v6.13-r8169-enable-EEE-at-2.5G-per-default-on-RTL8125B.patch [deleted file]
target/linux/generic/backport-6.18/780-10-v6.13-r8169-fix-inconsistent-indenting-in-rtl8169_get_eth_.patch [deleted file]
target/linux/generic/backport-6.18/780-11-v6.13-r8169-align-RTL8125-EEE-config-with-vendor-driver.patch [deleted file]
target/linux/generic/backport-6.18/780-12-v6.13-r8169-align-RTL8125-RTL8126-PHY-config-with-vendor-d.patch [deleted file]
target/linux/generic/backport-6.18/780-13-v6.13-r8169-align-RTL8126-EEE-config-with-vendor-driver.patch [deleted file]
target/linux/generic/backport-6.18/780-14-v6.13-r8169-improve-initialization-of-RSS-registers-on-RTL.patch [deleted file]
target/linux/generic/backport-6.18/780-15-v6.13-r8169-remove-leftover-locks-after-reverted-change.patch [deleted file]
target/linux/generic/backport-6.18/780-16-v6.13-r8169-improve-__rtl8169_set_wol.patch [deleted file]
target/linux/generic/backport-6.18/780-17-v6.13-r8169-improve-rtl_set_d3_pll_down.patch [deleted file]
target/linux/generic/backport-6.18/780-18-v6.13-r8169-align-WAKE_PHY-handling-with-r8125-r8126-vendo.patch [deleted file]
target/linux/generic/backport-6.18/780-19-v6.13-r8169-use-helper-r8169_mod_reg8_cond-to-simplify-rtl.patch [deleted file]
target/linux/generic/backport-6.18/780-20-v6.13-r8169-copy-vendor-driver-2.5G-5G-EEE-advertisement-c.patch [deleted file]
target/linux/generic/backport-6.18/780-21-v6.14-r8169-remove-unused-flag-RTL_FLAG_TASK_RESET_NO_QUEU.patch [deleted file]
target/linux/generic/backport-6.18/780-22-v6.14-r8169-remove-support-for-chip-version-11.patch [deleted file]
target/linux/generic/backport-6.18/780-23-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch [deleted file]
target/linux/generic/backport-6.18/780-24-v6.14-r8169-add-support-for-RTL8125D-rev.b.patch [deleted file]
target/linux/generic/backport-6.18/780-25-v6.14-r8169-add-support-for-RTL8125BP-rev.b.patch [deleted file]
target/linux/generic/backport-6.18/780-26-v6.15-r8169-make-Kconfig-option-for-LED-support-user-visib.patch [deleted file]
target/linux/generic/backport-6.18/780-28-v6.15-r8169-add-support-for-Intel-Killer-E5000.patch [deleted file]
target/linux/generic/backport-6.18/780-29-v6.15-r8169-add-PHY-c45-ops-for-MDIO_MMD_VENDOR2-registers.patch [deleted file]
target/linux/generic/backport-6.18/780-30-v6.15-r8169-increase-max-jumbo-packet-size-on-RTL8125-RTL8.patch [deleted file]
target/linux/generic/backport-6.18/780-31-v6.15-r8169-switch-away-from-deprecated-pcim_iomap_table.patch [deleted file]
target/linux/generic/backport-6.18/780-32-v6.15-r8169-enable-RTL8168H-RTL8168EP-RTL8168FP-ASPM-suppo.patch [deleted file]
target/linux/generic/backport-6.18/780-34-v6.16-r8169-add-helper-rtl_csi_mod-for-accessing-extended.patch [deleted file]
target/linux/generic/backport-6.18/780-35-v6.16-r8169-add-helper-rtl8125_phy_param.patch [deleted file]
target/linux/generic/backport-6.18/780-36-v6.16-r8169-refactor-chip-version-detection.patch [deleted file]
target/linux/generic/backport-6.18/780-37-v6.16-r8169-add-RTL_GIGA_MAC_VER_LAST-to-facilitate-adding.patch [deleted file]
target/linux/generic/backport-6.18/780-38-v6.16-r8169-use-pci_prepare_to_sleep-in-rtl_shutdown.patch [deleted file]
target/linux/generic/backport-6.18/780-39-v6.16-r8169-merge-chip-versions-70-and-71-RTL8126A.patch [deleted file]
target/linux/generic/backport-6.18/780-40-v6.16-r8169-merge-chip-versions-64-and-65-RTL8125D.patch [deleted file]
target/linux/generic/backport-6.18/780-41-v6.16-r8169-merge-chip-versions-52-and-53-RTL8117.patch [deleted file]
target/linux/generic/backport-6.18/780-42-v6.16-r8169-add-support-for-RTL8127A.patch [deleted file]
target/linux/generic/backport-6.18/781-01-v6.13-net-phy-realtek-read-duplex-and-gbit-master-from-PHY.patch [deleted file]
target/linux/generic/backport-6.18/781-02-v6.13-net-phy-realtek-change-order-of-calls-in-C22-read_st.patch [deleted file]
target/linux/generic/backport-6.18/781-03-v6.13-net-phy-realtek-clear-1000Base-T-link-partner-advert.patch [deleted file]
target/linux/generic/backport-6.18/781-06-v6.14-net-phy-realtek-add-support-for-reading-MDIO_MMD_VEN.patch [deleted file]
target/linux/generic/backport-6.18/781-07-v6.14-net-phy-realtek-clear-1000Base-T-lpa-if-link-is-down.patch [deleted file]
target/linux/generic/backport-6.18/781-08-v6.14-net-phy-realtek-clear-master_slave_state-if-link-is-.patch [deleted file]
target/linux/generic/backport-6.18/781-09-v6.14-net-phy-realtek-always-clear-NBase-T-lpa.patch [deleted file]
target/linux/generic/backport-6.18/781-10-v6.14-net-phy-move-realtek-PHY-driver-to-its-own-subdirect.patch [deleted file]
target/linux/generic/backport-6.18/781-11-v6.14-net-phy-realtek-add-hwmon-support-for-temp-sensor-on.patch [deleted file]
target/linux/generic/backport-6.18/781-12-v6.14-net-phy-realtek-HWMON-support-for-standalone-version.patch [deleted file]
target/linux/generic/backport-6.18/781-13-v6.15-net-phy-realtek-make-HWMON-support-a-user-visible-Kc.patch [deleted file]
target/linux/generic/backport-6.18/781-14-v6.15-net-phy-realtek-use-string-choices-helpers.patch [deleted file]
target/linux/generic/backport-6.18/781-15-v6.15-net-phy-realtek-improve-mmd-register-access-for-inte.patch [deleted file]
target/linux/generic/backport-6.18/781-16-v6.15-net-phy-realtek-switch-from-paged-to-MMD-ops-in-rtl8.patch [deleted file]
target/linux/generic/backport-6.18/781-17-v6.15-net-phy-realtek-add-helper-RTL822X_VND2_C22_REG.patch [deleted file]
target/linux/generic/backport-6.18/781-18-v6.15-net-phy-realtek-add-defines-for-shadowed-c45-standar.patch [deleted file]
target/linux/generic/backport-6.18/781-19-v6.15-net-phy-realtek-disable-PHY-mode-EEE.patch [deleted file]
target/linux/generic/backport-6.18/781-20-v6.16-net-phy-realtek-Add-support-for-WOL-magic-packet-on.patch [deleted file]
target/linux/generic/backport-6.18/781-21-v6.16-net-phy-realtek-remove-unsed-RTL821x_PHYSR-macros.patch [deleted file]
target/linux/generic/backport-6.18/781-22-v6.16-net-phy-realtek-Clean-up-RTL821x-ExtPage-access.patch [deleted file]
target/linux/generic/backport-6.18/781-23-v6.16-net-phy-realtek-add-RTL8211F-register-defines.patch [deleted file]
target/linux/generic/backport-6.18/781-24-v6.16-net-phy-realtek-Group-RTL82-macro-definitions.patch [deleted file]
target/linux/generic/backport-6.18/781-25-v6.16-net-phy-realtek-use-__set_bit-in-rtl8211f_led_hw_con.patch [deleted file]
target/linux/generic/backport-6.18/781-26-v6.16-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211E.patch [deleted file]
target/linux/generic/backport-6.18/781-27-v6.16-net-phy-realtek-add-RTL8127-internal-PHY.patch [deleted file]
target/linux/generic/backport-6.18/781-28-v6.18-net-phy-realtek-convert-RTL8226-CG-to-c45-only.patch [deleted file]
target/linux/generic/backport-6.18/781-29-v6.18-net-phy-realtek-enable-serdes-option-mode-for-RTL8226-CG.patch [deleted file]
target/linux/generic/backport-6.18/782-01-v6.16-net-phy-pass-PHY-driver-to-.match_phy_device-OP.patch [deleted file]
target/linux/generic/backport-6.18/782-04-v6.16-net-phy-introduce-genphy_match_phy_device.patch [deleted file]
target/linux/generic/backport-6.18/782-05-v6.16-net-phy-Add-support-for-Aeonsemi-AS21xxx-PHYs.patch [deleted file]
target/linux/generic/backport-6.18/783-01-v6.18-net-dsa-Move-KS8995-to-the-DSA-subsystem.patch [deleted file]
target/linux/generic/backport-6.18/783-02-v6.18-net-dsa-ks8995-Add-proper-RESET-delay.patch [deleted file]
target/linux/generic/backport-6.18/783-03-v6.18-net-dsa-ks8995-Delete-sysfs-register-access.patch [deleted file]
target/linux/generic/backport-6.18/783-04-v6.18-net-dsa-ks8995-Add-basic-switch-set-up.patch [deleted file]
target/linux/generic/backport-6.18/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch [deleted file]
target/linux/generic/backport-6.18/784-02-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch [deleted file]
target/linux/generic/backport-6.18/784-02-v6.18-net-phy-realtek-fix-RTL8211F-wake-on-lan-support.patch [deleted file]
target/linux/generic/backport-6.18/784-03-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch [deleted file]
target/linux/generic/backport-6.18/784-03-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch [deleted file]
target/linux/generic/backport-6.18/784-08-v6.19-net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch [deleted file]
target/linux/generic/backport-6.18/784-09-v6.19-net-phy-realtek-eliminate-priv-phycr2-variable.patch [deleted file]
target/linux/generic/backport-6.18/784-10-v6.19-net-phy-realtek-eliminate-has_phycr2-variable.patch [deleted file]
target/linux/generic/backport-6.18/784-11-v6.19-net-phy-realtek-allow-CLKOUT-to-be-disabled-on-RTL82.patch [deleted file]
target/linux/generic/backport-6.18/784-12-v6.19-net-phy-realtek-eliminate-priv-phycr1-variable.patch [deleted file]
target/linux/generic/backport-6.18/784-13-v6.19-net-phy-realtek-create-rtl8211f_config_phy_eee-helpe.patch [deleted file]
target/linux/generic/backport-6.18/785-v6.18-r8169-fix-RTL8127-hang-on-suspend-shutdown.patch [deleted file]
target/linux/generic/backport-6.18/786-01-v6.18-net-phy-introduce-phy_id_compare_vendor-PHY-ID-helpe.patch [deleted file]
target/linux/generic/backport-6.18/786-02-v6.18-net-phy-as21xxx-better-handle-PHY-HW-reset-on-soft-r.patch [deleted file]
target/linux/generic/backport-6.18/787-v6.19-net-phy-RTL8211FVD-Restore-disabling-of-PHY-mode-EEE.patch [deleted file]
target/linux/generic/backport-6.18/800-v6.13-hwmon-Add-static-visibility-member-to-struct-hwmon_o.patch [deleted file]
target/linux/generic/backport-6.18/801-01-v6.13-dt-bindings-clocks-add-binding-for-gated-fixed-clock.patch [deleted file]
target/linux/generic/backport-6.18/801-02-v6.13-clk-clk-gpio-update-documentation-for-gpio-gate-cloc.patch [deleted file]
target/linux/generic/backport-6.18/801-03-v6.13-clk-clk-gpio-use-dev_err_probe-for-gpio-get-failure.patch [deleted file]
target/linux/generic/backport-6.18/801-04-v6.13-clk-clk-gpio-add-driver-for-gated-fixed-clocks.patch [deleted file]
target/linux/generic/backport-6.18/810-v6.14-gpio-regmap-Use-generic-request-free-ops.patch [deleted file]
target/linux/generic/backport-6.18/813-v6.16-pinctrl-aw9523-fix-can_sleep-flag-for-GPIO-chip.patch [deleted file]
target/linux/generic/backport-6.18/820-v6.15-power-supply-sysfs-remove-duplicate-nul-termination-to-fix-build-with-GCC15.patch [deleted file]
target/linux/generic/backport-6.18/891-v6.14-dt-bindings-leds-Add-LED1202-LED-Controller.patch [deleted file]
target/linux/generic/backport-6.18/892-v6.14-leds-Add-LED1202-I2C-driver.patch [deleted file]
target/linux/generic/backport-6.18/893-v6.14-leds_st1202-Fix-NULL-pointer-access-error.patch [deleted file]
target/linux/generic/backport-6.18/900-v6.14-driver-core-add-a-faux-bus-for-use-when-a-simple-dev.patch [deleted file]

diff --git a/target/linux/generic/backport-6.18/152-v6.16-net-wireguard-add-nonstring-annotation-to-fix-build-with-GCC15.patch b/target/linux/generic/backport-6.18/152-v6.16-net-wireguard-add-nonstring-annotation-to-fix-build-with-GCC15.patch
deleted file mode 100644 (file)
index 1fdf2f1..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-From 71e5da46e78c1cd24e2feed251a2845327447ad8 Mon Sep 17 00:00:00 2001
-From: Kees Cook <kees@kernel.org>
-Date: Wed, 21 May 2025 23:27:04 +0200
-Subject: wireguard: global: add __nonstring annotations for unterminated
- strings
-
-When a character array without a terminating NUL character has a static
-initializer, GCC 15's -Wunterminated-string-initialization will only
-warn if the array lacks the "nonstring" attribute[1]. Mark the arrays
-with __nonstring to correctly identify the char array as "not a C string"
-and thereby eliminate the warning:
-
-../drivers/net/wireguard/cookie.c:29:56: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (9 chars into 8 available) [-Wunterminated-string-initialization]
-   29 | static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] = "mac1----";
-      |                                                        ^~~~~~~~~~
-../drivers/net/wireguard/cookie.c:30:58: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (9 chars into 8 available) [-Wunterminated-string-initialization]
-   30 | static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] = "cookie--";
-      |                                                          ^~~~~~~~~~
-../drivers/net/wireguard/noise.c:28:38: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (38 chars into 37 available) [-Wunterminated-string-initialization]
-   28 | static const u8 handshake_name[37] = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s";
-      |                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-../drivers/net/wireguard/noise.c:29:39: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (35 chars into 34 available) [-Wunterminated-string-initialization]
-   29 | static const u8 identifier_name[34] = "WireGuard v1 zx2c4 Jason@zx2c4.com";
-      |                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The arrays are always used with their fixed size, so use __nonstring.
-
-Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117178 [1]
-Signed-off-by: Kees Cook <kees@kernel.org>
-Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-Link: https://patch.msgid.link/20250521212707.1767879-3-Jason@zx2c4.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/wireguard/cookie.c | 4 ++--
- drivers/net/wireguard/noise.c  | 4 ++--
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/wireguard/cookie.c
-+++ b/drivers/net/wireguard/cookie.c
-@@ -26,8 +26,8 @@ void wg_cookie_checker_init(struct cooki
- }
- enum { COOKIE_KEY_LABEL_LEN = 8 };
--static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] = "mac1----";
--static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] = "cookie--";
-+static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] __nonstring = "mac1----";
-+static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] __nonstring = "cookie--";
- static void precompute_key(u8 key[NOISE_SYMMETRIC_KEY_LEN],
-                          const u8 pubkey[NOISE_PUBLIC_KEY_LEN],
---- a/drivers/net/wireguard/noise.c
-+++ b/drivers/net/wireguard/noise.c
-@@ -25,8 +25,8 @@
-  * <- e, ee, se, psk, {}
-  */
--static const u8 handshake_name[37] = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s";
--static const u8 identifier_name[34] = "WireGuard v1 zx2c4 Jason@zx2c4.com";
-+static const u8 handshake_name[37] __nonstring = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s";
-+static const u8 identifier_name[34] __nonstring = "WireGuard v1 zx2c4 Jason@zx2c4.com";
- static u8 handshake_init_hash[NOISE_HASH_LEN] __ro_after_init;
- static u8 handshake_init_chaining_key[NOISE_HASH_LEN] __ro_after_init;
- static atomic64_t keypair_counter = ATOMIC64_INIT(0);
diff --git a/target/linux/generic/backport-6.18/200-01-v6.13-jiffies-Define-secs_to_jiffies.patch b/target/linux/generic/backport-6.18/200-01-v6.13-jiffies-Define-secs_to_jiffies.patch
deleted file mode 100644 (file)
index ad9af1d..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-From b35108a51cf7bab58d7eace1267d7965978bcdb8 Mon Sep 17 00:00:00 2001
-From: Easwar Hariharan <eahariha@linux.microsoft.com>
-Date: Wed, 30 Oct 2024 17:47:35 +0000
-Subject: [PATCH] jiffies: Define secs_to_jiffies()
-
-secs_to_jiffies() is defined in hci_event.c and cannot be reused by
-other call sites. Hoist it into the core code to allow conversion of the
-~1150 usages of msecs_to_jiffies() that either:
-
- - use a multiplier value of 1000 or equivalently MSEC_PER_SEC, or
- - have timeouts that are denominated in seconds (i.e. end in 000)
-
-It's implemented as a macro to allow usage in static initializers.
-
-This will also allow conversion of yet more sites that use (sec * HZ)
-directly, and improve their readability.
-
-Suggested-by: Michael Kelley <mhklinux@outlook.com>
-Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Reviewed-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
-Link: https://lore.kernel.org/all/20241030-open-coded-timeouts-v3-1-9ba123facf88@linux.microsoft.com
----
- include/linux/jiffies.h   | 13 +++++++++++++
- net/bluetooth/hci_event.c |  2 --
- 2 files changed, 13 insertions(+), 2 deletions(-)
-
---- a/include/linux/jiffies.h
-+++ b/include/linux/jiffies.h
-@@ -526,6 +526,19 @@ static __always_inline unsigned long mse
-       }
- }
-+/**
-+ * secs_to_jiffies: - convert seconds to jiffies
-+ * @_secs: time in seconds
-+ *
-+ * Conversion is done by simple multiplication with HZ
-+ *
-+ * secs_to_jiffies() is defined as a macro rather than a static inline
-+ * function so it can be used in static initializers.
-+ *
-+ * Return: jiffies value
-+ */
-+#define secs_to_jiffies(_secs) ((_secs) * HZ)
-+
- extern unsigned long __usecs_to_jiffies(const unsigned int u);
- #if !(USEC_PER_SEC % HZ)
- static inline unsigned long _usecs_to_jiffies(const unsigned int u)
---- a/net/bluetooth/hci_event.c
-+++ b/net/bluetooth/hci_event.c
-@@ -42,8 +42,6 @@
- #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
-                "\x00\x00\x00\x00\x00\x00\x00\x00"
--#define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000)
--
- /* Handle HCI Event packets */
- static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
diff --git a/target/linux/generic/backport-6.18/200-02-v6.14-jiffies-Cast-to-unsigned-long-in-secs_to_jiffies-con.patch b/target/linux/generic/backport-6.18/200-02-v6.14-jiffies-Cast-to-unsigned-long-in-secs_to_jiffies-con.patch
deleted file mode 100644 (file)
index cddd558..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From bb2784d9ab49587ba4fbff37a319fff2924db289 Mon Sep 17 00:00:00 2001
-From: Easwar Hariharan <eahariha@linux.microsoft.com>
-Date: Thu, 30 Jan 2025 19:26:58 +0000
-Subject: [PATCH] jiffies: Cast to unsigned long in secs_to_jiffies()
- conversion
-
-While converting users of msecs_to_jiffies(), lkp reported that some range
-checks would always be true because of the mismatch between the implied int
-value of secs_to_jiffies() vs the unsigned long return value of the
-msecs_to_jiffies() calls it was replacing.
-
-Fix this by casting the secs_to_jiffies() input value to unsigned long.
-
-Fixes: b35108a51cf7ba ("jiffies: Define secs_to_jiffies()")
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Cc: stable@vger.kernel.org
-Link: https://lore.kernel.org/all/20250130192701.99626-1-eahariha@linux.microsoft.com
-Closes: https://lore.kernel.org/oe-kbuild-all/202501301334.NB6NszQR-lkp@intel.com/
----
- include/linux/jiffies.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/linux/jiffies.h
-+++ b/include/linux/jiffies.h
-@@ -537,7 +537,7 @@ static __always_inline unsigned long mse
-  *
-  * Return: jiffies value
-  */
--#define secs_to_jiffies(_secs) ((_secs) * HZ)
-+#define secs_to_jiffies(_secs) (unsigned long)((_secs) * HZ)
- extern unsigned long __usecs_to_jiffies(const unsigned int u);
- #if !(USEC_PER_SEC % HZ)
diff --git a/target/linux/generic/backport-6.18/201-v6.13-of-property-add-of_graph_get_next_port.patch b/target/linux/generic/backport-6.18/201-v6.13-of-property-add-of_graph_get_next_port.patch
deleted file mode 100644 (file)
index 5178dc8..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-From 02ac5f9d6caec96071103f7c62b5117526e47b64 Mon Sep 17 00:00:00 2001
-From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
-Date: Thu, 24 Oct 2024 02:20:02 +0000
-Subject: [PATCH] of: property: add of_graph_get_next_port()
-
-We have endpoint base functions
-       - of_graph_get_next_endpoint()
-       - of_graph_get_endpoint_count()
-       - for_each_endpoint_of_node()
-
-Here, for_each_endpoint_of_node() loop finds each endpoints
-
-       ports {
-               port@0 {
-(1)                    endpoint {...};
-               };
-               port@1 {
-(2)                    endpoint {...};
-               };
-               ...
-       };
-
-In above case, it finds endpoint as (1) -> (2) -> ...
-
-Basically, user/driver knows which port is used for what, but not in
-all cases. For example on flexible/generic driver case, how many ports
-are used is not fixed.
-
-For example Sound Generic Card driver which is very flexible/generic and
-used from many venders can't know how many ports are used, and used for
-what, because it depends on each vender SoC and/or its used board.
-
-And more, the port can have multi endpoints. For example Generic Sound
-Card case, it supports many type of connection between CPU / Codec, and
-some of them uses multi endpoint in one port. see below.
-
-       ports {
-(A)            port@0 {
-(1)                    endpoint@0 {...};
-(2)                    endpoint@1 {...};
-               };
-(B)            port@1 {
-(3)                    endpoint {...};
-               };
-               ...
-       };
-
-Generic Sound Card want to handle each connection via "port" base instead
-of "endpoint" base. But, it is very difficult to handle each "port" via
-existing for_each_endpoint_of_node(). Because getting each "port" via
-of_get_parent() from each "endpoint" doesn't work. For example in above
-case, both (1) (2) endpoint has same "port" (= A).
-
-Add "port" base functions.
-
-Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
-Link: https://lore.kernel.org/r/87ldyeb5t9.wl-kuninori.morimoto.gx@renesas.com
-Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
----
- drivers/of/property.c    | 54 ++++++++++++++++++++++++++++++++++++++++
- include/linux/of_graph.h | 28 +++++++++++++++++++++
- 2 files changed, 82 insertions(+)
-
---- a/drivers/of/property.c
-+++ b/drivers/of/property.c
-@@ -631,6 +631,43 @@ struct device_node *of_graph_get_port_by
- EXPORT_SYMBOL(of_graph_get_port_by_id);
- /**
-+ * of_graph_get_next_port() - get next port node.
-+ * @parent: pointer to the parent device node, or parent ports node
-+ * @prev: previous port node, or NULL to get first
-+ *
-+ * Parent device node can be used as @parent whether device node has ports node
-+ * or not. It will work same as ports@0 node.
-+ *
-+ * Return: A 'port' node pointer with refcount incremented. Refcount
-+ * of the passed @prev node is decremented.
-+ */
-+struct device_node *of_graph_get_next_port(const struct device_node *parent,
-+                                         struct device_node *prev)
-+{
-+      if (!parent)
-+              return NULL;
-+
-+      if (!prev) {
-+              struct device_node *node __free(device_node) =
-+                      of_get_child_by_name(parent, "ports");
-+
-+              if (node)
-+                      parent = node;
-+
-+              return of_get_child_by_name(parent, "port");
-+      }
-+
-+      do {
-+              prev = of_get_next_child(parent, prev);
-+              if (!prev)
-+                      break;
-+      } while (!of_node_name_eq(prev, "port"));
-+
-+      return prev;
-+}
-+EXPORT_SYMBOL(of_graph_get_next_port);
-+
-+/**
-  * of_graph_get_next_endpoint() - get next endpoint node
-  * @parent: pointer to the parent device node
-  * @prev: previous endpoint node, or NULL to get first
-@@ -824,6 +861,23 @@ unsigned int of_graph_get_endpoint_count
- EXPORT_SYMBOL(of_graph_get_endpoint_count);
- /**
-+ * of_graph_get_port_count() - get the number of port in a device or ports node
-+ * @np: pointer to the device or ports node
-+ *
-+ * Return: count of port of this device or ports node
-+ */
-+unsigned int of_graph_get_port_count(struct device_node *np)
-+{
-+      unsigned int num = 0;
-+
-+      for_each_of_graph_port(np, port)
-+              num++;
-+
-+      return num;
-+}
-+EXPORT_SYMBOL(of_graph_get_port_count);
-+
-+/**
-  * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
-  * @node: pointer to parent device_node containing graph port/endpoint
-  * @port: identifier (value of reg property) of the parent port node
---- a/include/linux/of_graph.h
-+++ b/include/linux/of_graph.h
-@@ -11,6 +11,7 @@
- #ifndef __LINUX_OF_GRAPH_H
- #define __LINUX_OF_GRAPH_H
-+#include <linux/cleanup.h>
- #include <linux/types.h>
- #include <linux/errno.h>
-@@ -37,14 +38,29 @@ struct of_endpoint {
-       for (child = of_graph_get_next_endpoint(parent, NULL); child != NULL; \
-            child = of_graph_get_next_endpoint(parent, child))
-+/**
-+ * for_each_of_graph_port - iterate over every port in a device or ports node
-+ * @parent: parent device or ports node containing port
-+ * @child: loop variable pointing to the current port node
-+ *
-+ * When breaking out of the loop, and continue to use the @child, you need to
-+ * use return_ptr(@child) or no_free_ptr(@child) not to call __free() for it.
-+ */
-+#define for_each_of_graph_port(parent, child)                 \
-+      for (struct device_node *child __free(device_node) = of_graph_get_next_port(parent, NULL);\
-+           child != NULL; child = of_graph_get_next_port(parent, child))
-+
- #ifdef CONFIG_OF
- bool of_graph_is_present(const struct device_node *node);
- int of_graph_parse_endpoint(const struct device_node *node,
-                               struct of_endpoint *endpoint);
- unsigned int of_graph_get_endpoint_count(const struct device_node *np);
-+unsigned int of_graph_get_port_count(struct device_node *np);
- struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
- struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
-                                       struct device_node *previous);
-+struct device_node *of_graph_get_next_port(const struct device_node *parent,
-+                                         struct device_node *port);
- struct device_node *of_graph_get_endpoint_by_regs(
-               const struct device_node *parent, int port_reg, int reg);
- struct device_node *of_graph_get_remote_endpoint(
-@@ -73,6 +89,11 @@ static inline unsigned int of_graph_get_
-       return 0;
- }
-+static inline unsigned int of_graph_get_port_count(struct device_node *np)
-+{
-+      return 0;
-+}
-+
- static inline struct device_node *of_graph_get_port_by_id(
-                                       struct device_node *node, u32 id)
- {
-@@ -83,6 +104,13 @@ static inline struct device_node *of_gra
-                                       const struct device_node *parent,
-                                       struct device_node *previous)
- {
-+      return NULL;
-+}
-+
-+static inline struct device_node *of_graph_get_next_port(
-+                                      const struct device_node *parent,
-+                                      struct device_node *previous)
-+{
-       return NULL;
- }
diff --git a/target/linux/generic/backport-6.18/202-v6.13-clk-Provide-devm_clk_bulk_get_all_enabled-helper.patch b/target/linux/generic/backport-6.18/202-v6.13-clk-Provide-devm_clk_bulk_get_all_enabled-helper.patch
deleted file mode 100644 (file)
index c02e4ed..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-From 51e32e897539663957f7a0950f66b48f8896efee Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sat, 19 Oct 2024 14:16:00 +0300
-Subject: [PATCH] clk: Provide devm_clk_bulk_get_all_enabled() helper
-
-Commit 265b07df758a ("clk: Provide managed helper to get and enable bulk
-clocks") added devm_clk_bulk_get_all_enable() function, but missed to
-return the number of clocks stored in the clk_bulk_data table referenced
-by the clks argument.  Without knowing the number, it's not possible to
-iterate these clocks when needed, hence the argument is useless and
-could have been simply removed.
-
-Introduce devm_clk_bulk_get_all_enabled() variant, which is consistent
-with devm_clk_bulk_get_all() in terms of the returned value:
-
- > 0 if one or more clocks have been stored
- = 0 if there are no clocks
- < 0 if an error occurred
-
-Moreover, the naming is consistent with devm_clk_get_enabled(), i.e. use
-the past form of 'enable'.
-
-To reduce code duplication and improve patch readability, make
-devm_clk_bulk_get_all_enable() use the new helper, as suggested by
-Stephen Boyd.
-
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Link: https://lore.kernel.org/r/20241019-clk_bulk_ena_fix-v4-1-57f108f64e70@collabora.com
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/clk-devres.c |  9 +++++----
- include/linux/clk.h      | 21 ++++++++++++++++-----
- 2 files changed, 21 insertions(+), 9 deletions(-)
-
---- a/drivers/clk/clk-devres.c
-+++ b/drivers/clk/clk-devres.c
-@@ -218,8 +218,8 @@ static void devm_clk_bulk_release_all_en
-       clk_bulk_put_all(devres->num_clks, devres->clks);
- }
--int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
--                                            struct clk_bulk_data **clks)
-+int __must_check devm_clk_bulk_get_all_enabled(struct device *dev,
-+                                             struct clk_bulk_data **clks)
- {
-       struct clk_bulk_devres *devres;
-       int ret;
-@@ -244,11 +244,12 @@ int __must_check devm_clk_bulk_get_all_e
-       } else {
-               clk_bulk_put_all(devres->num_clks, devres->clks);
-               devres_free(devres);
-+              return ret;
-       }
--      return ret;
-+      return devres->num_clks;
- }
--EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable);
-+EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enabled);
- static int devm_clk_match(struct device *dev, void *res, void *data)
- {
---- a/include/linux/clk.h
-+++ b/include/linux/clk.h
-@@ -520,11 +520,13 @@ int __must_check devm_clk_bulk_get_all(s
-                                      struct clk_bulk_data **clks);
- /**
-- * devm_clk_bulk_get_all_enable - Get and enable all clocks of the consumer (managed)
-+ * devm_clk_bulk_get_all_enabled - Get and enable all clocks of the consumer (managed)
-  * @dev: device for clock "consumer"
-  * @clks: pointer to the clk_bulk_data table of consumer
-  *
-- * Returns success (0) or negative errno.
-+ * Returns a positive value for the number of clocks obtained while the
-+ * clock references are stored in the clk_bulk_data table in @clks field.
-+ * Returns 0 if there're none and a negative value if something failed.
-  *
-  * This helper function allows drivers to get all clocks of the
-  * consumer and enables them in one operation with management.
-@@ -532,8 +534,8 @@ int __must_check devm_clk_bulk_get_all(s
-  * is unbound.
-  */
--int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
--                                            struct clk_bulk_data **clks);
-+int __must_check devm_clk_bulk_get_all_enabled(struct device *dev,
-+                                             struct clk_bulk_data **clks);
- /**
-  * devm_clk_get - lookup and obtain a managed reference to a clock producer.
-@@ -1041,7 +1043,7 @@ static inline int __must_check devm_clk_
-       return 0;
- }
--static inline int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
-+static inline int __must_check devm_clk_bulk_get_all_enabled(struct device *dev,
-                                               struct clk_bulk_data **clks)
- {
-       return 0;
-@@ -1136,6 +1138,15 @@ static inline struct clk *clk_get_sys(co
- #endif
-+/* Deprecated. Use devm_clk_bulk_get_all_enabled() */
-+static inline int __must_check
-+devm_clk_bulk_get_all_enable(struct device *dev, struct clk_bulk_data **clks)
-+{
-+      int ret = devm_clk_bulk_get_all_enabled(dev, clks);
-+
-+      return ret > 0 ? 0 : ret;
-+}
-+
- /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
- static inline int clk_prepare_enable(struct clk *clk)
- {
diff --git a/target/linux/generic/backport-6.18/203-01-v6.13-of-address-Rework-bus-matching-to-avoid-warnings.patch b/target/linux/generic/backport-6.18/203-01-v6.13-of-address-Rework-bus-matching-to-avoid-warnings.patch
deleted file mode 100644 (file)
index d7a6751..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From 64ee3cf096ac590e7da2ceac1c390546bff5e240 Mon Sep 17 00:00:00 2001
-From: "Rob Herring (Arm)" <robh@kernel.org>
-Date: Fri, 8 Nov 2024 13:35:48 -0600
-Subject: [PATCH] of/address: Rework bus matching to avoid warnings
-
-With warnings added for deprecated #address-cells/#size-cells handling,
-the DT address handling code causes warnings when used on nodes with no
-address. This happens frequently with calls to of_platform_populate() as
-it is perfectly acceptable to have devices without a 'reg' property. The
-desired behavior is to just silently return an error when retrieving an
-address.
-
-The warnings can be avoided by checking for "#address-cells" presence
-first and checking for an address property before fetching
-"#address-cells" and "#size-cells".
-
-Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Reported-by: Steven Price <steven.price@arm.com>
-Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Link: https://lore.kernel.org/r/20241108193547.2647986-2-robh@kernel.org
-Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
----
- drivers/of/address.c | 14 +++++++++-----
- 1 file changed, 9 insertions(+), 5 deletions(-)
-
---- a/drivers/of/address.c
-+++ b/drivers/of/address.c
-@@ -331,7 +331,11 @@ static unsigned int of_bus_isa_get_flags
- static int of_bus_default_flags_match(struct device_node *np)
- {
--      return of_bus_n_addr_cells(np) == 3;
-+      /*
-+       * Check for presence first since of_bus_n_addr_cells() will warn when
-+       * walking parent nodes.
-+       */
-+      return of_property_present(np, "#address-cells") && (of_bus_n_addr_cells(np) == 3);
- }
- /*
-@@ -700,16 +704,16 @@ const __be32 *__of_get_address(struct de
-       if (strcmp(bus->name, "pci") && (bar_no >= 0))
-               return NULL;
--      bus->count_cells(dev, &na, &ns);
--      if (!OF_CHECK_ADDR_COUNT(na))
--              return NULL;
--
-       /* Get "reg" or "assigned-addresses" property */
-       prop = of_get_property(dev, bus->addresses, &psize);
-       if (prop == NULL)
-               return NULL;
-       psize /= 4;
-+      bus->count_cells(dev, &na, &ns);
-+      if (!OF_CHECK_ADDR_COUNT(na))
-+              return NULL;
-+
-       onesize = na + ns;
-       for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) {
-               u32 val = be32_to_cpu(prop[0]);
diff --git a/target/linux/generic/backport-6.18/203-02-v6.13-of-address-Fix-WARN-when-attempting-translating-non-.patch b/target/linux/generic/backport-6.18/203-02-v6.13-of-address-Fix-WARN-when-attempting-translating-non-.patch
deleted file mode 100644 (file)
index 2ad67cb..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From 6e5773d52f4a2d9c80692245f295069260cff6fc Mon Sep 17 00:00:00 2001
-From: "Rob Herring (Arm)" <robh@kernel.org>
-Date: Fri, 10 Jan 2025 15:50:29 -0600
-Subject: [PATCH] of/address: Fix WARN when attempting translating
- non-translatable addresses
-
-The recently added WARN() for deprecated #address-cells and #size-cells
-triggered a WARN when of_platform_populate() (which calls
-of_address_to_resource()) is used on nodes with non-translatable
-addresses. This case is expected to return an error.
-
-Rework the bus matching to allow no match and make the default require
-an #address-cells property. That should be safe to do as any platform
-missing #address-cells would have a warning already.
-
-Fixes: 045b14ca5c36 ("of: WARN on deprecated #address-cells/#size-cells handling")
-Tested-by: Sean Anderson <sean.anderson@linux.dev>
-Link: https://lore.kernel.org/r/20250110215030.3637845-2-robh@kernel.org
-Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
----
- drivers/of/address.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
---- a/drivers/of/address.c
-+++ b/drivers/of/address.c
-@@ -338,6 +338,15 @@ static int of_bus_default_flags_match(st
-       return of_property_present(np, "#address-cells") && (of_bus_n_addr_cells(np) == 3);
- }
-+static int of_bus_default_match(struct device_node *np)
-+{
-+      /*
-+       * Check for presence first since of_bus_n_addr_cells() will warn when
-+       * walking parent nodes.
-+       */
-+      return of_property_present(np, "#address-cells");
-+}
-+
- /*
-  * Array of bus specific translators
-  */
-@@ -382,7 +391,7 @@ static struct of_bus of_busses[] = {
-       {
-               .name = "default",
-               .addresses = "reg",
--              .match = NULL,
-+              .match = of_bus_default_match,
-               .count_cells = of_bus_default_count_cells,
-               .map = of_bus_default_map,
-               .translate = of_bus_default_translate,
-@@ -397,7 +406,6 @@ static struct of_bus *of_match_bus(struc
-       for (i = 0; i < ARRAY_SIZE(of_busses); i++)
-               if (!of_busses[i].match || of_busses[i].match(np))
-                       return &of_busses[i];
--      BUG();
-       return NULL;
- }
-@@ -519,6 +527,8 @@ static u64 __of_translate_address(struct
-       if (parent == NULL)
-               return OF_BAD_ADDR;
-       bus = of_match_bus(parent);
-+      if (!bus)
-+              return OF_BAD_ADDR;
-       /* Count address cells & copy address locally */
-       bus->count_cells(dev, &na, &ns);
-@@ -562,6 +572,8 @@ static u64 __of_translate_address(struct
-               /* Get new parent bus and counts */
-               pbus = of_match_bus(parent);
-+              if (!pbus)
-+                      return OF_BAD_ADDR;
-               pbus->count_cells(dev, &pna, &pns);
-               if (!OF_CHECK_COUNTS(pna, pns)) {
-                       pr_err("Bad cell count for %pOF\n", dev);
-@@ -701,7 +713,7 @@ const __be32 *__of_get_address(struct de
-       /* match the parent's bus type */
-       bus = of_match_bus(parent);
--      if (strcmp(bus->name, "pci") && (bar_no >= 0))
-+      if (!bus || (strcmp(bus->name, "pci") && (bar_no >= 0)))
-               return NULL;
-       /* Get "reg" or "assigned-addresses" property */
diff --git a/target/linux/generic/backport-6.18/205-v6.16-of-reserved_mem-Add-functions-to-parse-memory-region.patch b/target/linux/generic/backport-6.18/205-v6.16-of-reserved_mem-Add-functions-to-parse-memory-region.patch
deleted file mode 100644 (file)
index b5bbb6e..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-From f4fcfdda2fd8834c62dcb9bfddcf1f89d190b70e Mon Sep 17 00:00:00 2001
-From: "Rob Herring (Arm)" <robh@kernel.org>
-Date: Wed, 23 Apr 2025 14:42:13 -0500
-Subject: [PATCH] of: reserved_mem: Add functions to parse "memory-region"
-
-Drivers with "memory-region" properties currently have to do their own
-parsing of "memory-region" properties. The result is all the drivers
-have similar patterns of a call to parse "memory-region" and then get
-the region's address and size. As this is a standard property, it should
-have common functions for drivers to use. Add new functions to count the
-number of regions and retrieve the region's address as a resource.
-
-Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
-Acked-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
-Link: https://lore.kernel.org/r/20250423-dt-memory-region-v2-v2-1-2fbd6ebd3c88@kernel.org
-Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
----
- drivers/of/of_reserved_mem.c    | 80 +++++++++++++++++++++++++++++++++
- include/linux/of_reserved_mem.h | 26 +++++++++++
- 2 files changed, 106 insertions(+)
-
---- a/drivers/of/of_reserved_mem.c
-+++ b/drivers/of/of_reserved_mem.c
-@@ -12,6 +12,7 @@
- #define pr_fmt(fmt)   "OF: reserved mem: " fmt
- #include <linux/err.h>
-+#include <linux/ioport.h>
- #include <linux/libfdt.h>
- #include <linux/of.h>
- #include <linux/of_fdt.h>
-@@ -694,3 +695,82 @@ struct reserved_mem *of_reserved_mem_loo
-       return NULL;
- }
- EXPORT_SYMBOL_GPL(of_reserved_mem_lookup);
-+
-+/**
-+ * of_reserved_mem_region_to_resource() - Get a reserved memory region as a resource
-+ * @np:               node containing 'memory-region' property
-+ * @idx:      index of 'memory-region' property to lookup
-+ * @res:      Pointer to a struct resource to fill in with reserved region
-+ *
-+ * This function allows drivers to lookup a node's 'memory-region' property
-+ * entries by index and return a struct resource for the entry.
-+ *
-+ * Returns 0 on success with @res filled in. Returns -ENODEV if 'memory-region'
-+ * is missing or unavailable, -EINVAL for any other error.
-+ */
-+int of_reserved_mem_region_to_resource(const struct device_node *np,
-+                                     unsigned int idx, struct resource *res)
-+{
-+      struct reserved_mem *rmem;
-+
-+      if (!np)
-+              return -EINVAL;
-+
-+      struct device_node __free(device_node) *target = of_parse_phandle(np, "memory-region", idx);
-+      if (!target || !of_device_is_available(target))
-+              return -ENODEV;
-+
-+      rmem = of_reserved_mem_lookup(target);
-+      if (!rmem)
-+              return -EINVAL;
-+
-+      resource_set_range(res, rmem->base, rmem->size);
-+      res->name = rmem->name;
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(of_reserved_mem_region_to_resource);
-+
-+/**
-+ * of_reserved_mem_region_to_resource_byname() - Get a reserved memory region as a resource
-+ * @np:               node containing 'memory-region' property
-+ * @name:     name of 'memory-region' property entry to lookup
-+ * @res:      Pointer to a struct resource to fill in with reserved region
-+ *
-+ * This function allows drivers to lookup a node's 'memory-region' property
-+ * entries by name and return a struct resource for the entry.
-+ *
-+ * Returns 0 on success with @res filled in, or a negative error-code on
-+ * failure.
-+ */
-+int of_reserved_mem_region_to_resource_byname(const struct device_node *np,
-+                                            const char *name,
-+                                            struct resource *res)
-+{
-+      int idx;
-+
-+      if (!name)
-+              return -EINVAL;
-+
-+      idx = of_property_match_string(np, "memory-region-names", name);
-+      if (idx < 0)
-+              return idx;
-+
-+      return of_reserved_mem_region_to_resource(np, idx, res);
-+}
-+EXPORT_SYMBOL_GPL(of_reserved_mem_region_to_resource_byname);
-+
-+/**
-+ * of_reserved_mem_region_count() - Return the number of 'memory-region' entries
-+ * @np:               node containing 'memory-region' property
-+ *
-+ * This function allows drivers to retrieve the number of entries for a node's
-+ * 'memory-region' property.
-+ *
-+ * Returns the number of entries on success, or negative error code on a
-+ * malformed property.
-+ */
-+int of_reserved_mem_region_count(const struct device_node *np)
-+{
-+      return of_count_phandle_with_args(np, "memory-region", NULL);
-+}
-+EXPORT_SYMBOL_GPL(of_reserved_mem_region_count);
---- a/include/linux/of_reserved_mem.h
-+++ b/include/linux/of_reserved_mem.h
-@@ -7,6 +7,7 @@
- struct of_phandle_args;
- struct reserved_mem_ops;
-+struct resource;
- struct reserved_mem {
-       const char                      *name;
-@@ -39,6 +40,12 @@ int of_reserved_mem_device_init_by_name(
- void of_reserved_mem_device_release(struct device *dev);
- struct reserved_mem *of_reserved_mem_lookup(struct device_node *np);
-+int of_reserved_mem_region_to_resource(const struct device_node *np,
-+                                     unsigned int idx, struct resource *res);
-+int of_reserved_mem_region_to_resource_byname(const struct device_node *np,
-+                                            const char *name, struct resource *res);
-+int of_reserved_mem_region_count(const struct device_node *np);
-+
- #else
- #define RESERVEDMEM_OF_DECLARE(name, compat, init)                    \
-@@ -63,6 +70,25 @@ static inline struct reserved_mem *of_re
- {
-       return NULL;
- }
-+
-+static inline int of_reserved_mem_region_to_resource(const struct device_node *np,
-+                                                   unsigned int idx,
-+                                                   struct resource *res)
-+{
-+      return -ENOSYS;
-+}
-+
-+static inline int of_reserved_mem_region_to_resource_byname(const struct device_node *np,
-+                                                          const char *name,
-+                                                          struct resource *res)
-+{
-+      return -ENOSYS;
-+}
-+
-+static inline int of_reserved_mem_region_count(const struct device_node *np)
-+{
-+      return 0;
-+}
- #endif
- /**
diff --git a/target/linux/generic/backport-6.18/210-v6.13-fortify-Hide-run-time-copy-size-from-value-range-tracking.patch b/target/linux/generic/backport-6.18/210-v6.13-fortify-Hide-run-time-copy-size-from-value-range-tracking.patch
deleted file mode 100644 (file)
index 8dca649..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-From 239d87327dcd361b0098038995f8908f3296864f Mon Sep 17 00:00:00 2001
-From: Kees Cook <kees@kernel.org>
-Date: Thu, 12 Dec 2024 17:28:06 -0800
-Subject: fortify: Hide run-time copy size from value range tracking
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-GCC performs value range tracking for variables as a way to provide better
-diagnostics. One place this is regularly seen is with warnings associated
-with bounds-checking, e.g. -Wstringop-overflow, -Wstringop-overread,
--Warray-bounds, etc. In order to keep the signal-to-noise ratio high,
-warnings aren't emitted when a value range spans the entire value range
-representable by a given variable. For example:
-
-       unsigned int len;
-       char dst[8];
-       ...
-       memcpy(dst, src, len);
-
-If len's value is unknown, it has the full "unsigned int" range of [0,
-UINT_MAX], and GCC's compile-time bounds checks against memcpy() will
-be ignored. However, when a code path has been able to narrow the range:
-
-       if (len > 16)
-               return;
-       memcpy(dst, src, len);
-
-Then the range will be updated for the execution path. Above, len is
-now [0, 16] when reading memcpy(), so depending on other optimizations,
-we might see a -Wstringop-overflow warning like:
-
-       error: '__builtin_memcpy' writing between 9 and 16 bytes into region of size 8 [-Werror=stringop-overflow]
-
-When building with CONFIG_FORTIFY_SOURCE, the fortified run-time bounds
-checking can appear to narrow value ranges of lengths for memcpy(),
-depending on how the compiler constructs the execution paths during
-optimization passes, due to the checks against the field sizes. For
-example:
-
-       if (p_size_field != SIZE_MAX &&
-           p_size != p_size_field && p_size_field < size)
-
-As intentionally designed, these checks only affect the kernel warnings
-emitted at run-time and do not block the potentially overflowing memcpy(),
-so GCC thinks it needs to produce a warning about the resulting value
-range that might be reaching the memcpy().
-
-We have seen this manifest a few times now, with the most recent being
-with cpumasks:
-
-In function ‘bitmap_copy’,
-    inlined from ‘cpumask_copy’ at ./include/linux/cpumask.h:839:2,
-    inlined from ‘__padata_set_cpumasks’ at kernel/padata.c:730:2:
-./include/linux/fortify-string.h:114:33: error: ‘__builtin_memcpy’ reading between 257 and 536870904 bytes from a region of size 256 [-Werror=stringop-overread]
-  114 | #define __underlying_memcpy     __builtin_memcpy
-      |                                 ^
-./include/linux/fortify-string.h:633:9: note: in expansion of macro ‘__underlying_memcpy’
-  633 |         __underlying_##op(p, q, __fortify_size);                        \
-      |         ^~~~~~~~~~~~~
-./include/linux/fortify-string.h:678:26: note: in expansion of macro ‘__fortify_memcpy_chk’
-  678 | #define memcpy(p, q, s)  __fortify_memcpy_chk(p, q, s,                  \
-      |                          ^~~~~~~~~~~~~~~~~~~~
-./include/linux/bitmap.h:259:17: note: in expansion of macro ‘memcpy’
-  259 |                 memcpy(dst, src, len);
-      |                 ^~~~~~
-kernel/padata.c: In function ‘__padata_set_cpumasks’:
-kernel/padata.c:713:48: note: source object ‘pcpumask’ of size [0, 256]
-  713 |                                  cpumask_var_t pcpumask,
-      |                                  ~~~~~~~~~~~~~~^~~~~~~~
-
-This warning is _not_ emitted when CONFIG_FORTIFY_SOURCE is disabled,
-and with the recent -fdiagnostics-details we can confirm the origin of
-the warning is due to FORTIFY's bounds checking:
-
-../include/linux/bitmap.h:259:17: note: in expansion of macro 'memcpy'
-  259 |                 memcpy(dst, src, len);
-      |                 ^~~~~~
-  '__padata_set_cpumasks': events 1-2
-../include/linux/fortify-string.h:613:36:
-  612 |         if (p_size_field != SIZE_MAX &&
-      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  613 |             p_size != p_size_field && p_size_field < size)
-      |             ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
-      |                                    |
-      |                                    (1) when the condition is evaluated to false
-      |                                    (2) when the condition is evaluated to true
-  '__padata_set_cpumasks': event 3
-  114 | #define __underlying_memcpy     __builtin_memcpy
-      |                                 ^
-      |                                 |
-      |                                 (3) out of array bounds here
-
-Note that the cpumask warning started appearing since bitmap functions
-were recently marked __always_inline in commit ed8cd2b3bd9f ("bitmap:
-Switch from inline to __always_inline"), which allowed GCC to gain
-visibility into the variables as they passed through the FORTIFY
-implementation.
-
-In order to silence these false positives but keep otherwise deterministic
-compile-time warnings intact, hide the length variable from GCC with
-OPTIMIZE_HIDE_VAR() before calling the builtin memcpy.
-
-Additionally add a comment about why all the macro args have copies with
-const storage.
-
-Reported-by: "Thomas Weißschuh" <linux@weissschuh.net>
-Closes: https://lore.kernel.org/all/db7190c8-d17f-4a0d-bc2f-5903c79f36c2@t-8ch.de/
-Reported-by: Nilay Shroff <nilay@linux.ibm.com>
-Closes: https://lore.kernel.org/all/20241112124127.1666300-1-nilay@linux.ibm.com/
-Tested-by: Nilay Shroff <nilay@linux.ibm.com>
-Acked-by: Yury Norov <yury.norov@gmail.com>
-Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Kees Cook <kees@kernel.org>
----
- include/linux/fortify-string.h | 14 +++++++++++++-
- 1 file changed, 13 insertions(+), 1 deletion(-)
-
---- a/include/linux/fortify-string.h
-+++ b/include/linux/fortify-string.h
-@@ -616,6 +616,12 @@ __FORTIFY_INLINE bool fortify_memcpy_chk
-       return false;
- }
-+/*
-+ * To work around what seems to be an optimizer bug, the macro arguments
-+ * need to have const copies or the values end up changed by the time they
-+ * reach fortify_warn_once(). See commit 6f7630b1b5bc ("fortify: Capture
-+ * __bos() results in const temp vars") for more details.
-+ */
- #define __fortify_memcpy_chk(p, q, size, p_size, q_size,              \
-                            p_size_field, q_size_field, op) ({         \
-       const size_t __fortify_size = (size_t)(size);                   \
-@@ -623,6 +629,8 @@ __FORTIFY_INLINE bool fortify_memcpy_chk
-       const size_t __q_size = (q_size);                               \
-       const size_t __p_size_field = (p_size_field);                   \
-       const size_t __q_size_field = (q_size_field);                   \
-+      /* Keep a mutable version of the size for the final copy. */    \
-+      size_t __copy_size = __fortify_size;                            \
-       fortify_warn_once(fortify_memcpy_chk(__fortify_size, __p_size,  \
-                                    __q_size, __p_size_field,          \
-                                    __q_size_field, FORTIFY_FUNC_ ##op), \
-@@ -630,7 +638,11 @@ __FORTIFY_INLINE bool fortify_memcpy_chk
-                 __fortify_size,                                       \
-                 "field \"" #p "\" at " FILE_LINE,                     \
-                 __p_size_field);                                      \
--      __underlying_##op(p, q, __fortify_size);                        \
-+      /* Hide only the run-time size from value range tracking to */  \
-+      /* silence compile-time false positive bounds warnings. */      \
-+      if (!__builtin_constant_p(__copy_size))                         \
-+              OPTIMIZER_HIDE_VAR(__copy_size);                        \
-+      __underlying_##op(p, q, __copy_size);                           \
- })
- /*
diff --git a/target/linux/generic/backport-6.18/212-v6.17-of-reserved_mem-Add-missing-IORESOURCE_MEM-flag-on-r.patch b/target/linux/generic/backport-6.18/212-v6.17-of-reserved_mem-Add-missing-IORESOURCE_MEM-flag-on-r.patch
deleted file mode 100644 (file)
index 1f2d52a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From aea70964b5a7ca491a3701f2dde6c9d05d51878d Mon Sep 17 00:00:00 2001
-From: "Rob Herring (Arm)" <robh@kernel.org>
-Date: Wed, 20 Aug 2025 14:28:04 -0500
-Subject: of: reserved_mem: Add missing IORESOURCE_MEM flag on resources
-
-Commit f4fcfdda2fd8 ('of: reserved_mem: Add functions to parse
-"memory-region"') failed to set IORESOURCE_MEM flag on the resources.
-The result is functions such as devm_ioremap_resource_wc() will fail.
-Add the missing flag.
-
-Fixes: f4fcfdda2fd8 ('of: reserved_mem: Add functions to parse "memory-region"')
-Reported-by: Iuliana Prodan <iuliana.prodan@nxp.com>
-Reported-by: Daniel Baluta <daniel.baluta@gmail.com>
-Tested-by: Iuliana Prodan <iuliana.prodan@nxp.com>
-Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com>
-Reviewed-by: Saravana Kannan <saravanak@google.com>
-Link: https://lore.kernel.org/r/20250820192805.565568-1-robh@kernel.org
-Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
----
- drivers/of/of_reserved_mem.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/of/of_reserved_mem.c
-+++ b/drivers/of/of_reserved_mem.c
-@@ -725,6 +725,7 @@ int of_reserved_mem_region_to_resource(c
-               return -EINVAL;
-       resource_set_range(res, rmem->base, rmem->size);
-+      res->flags = IORESOURCE_MEM;
-       res->name = rmem->name;
-       return 0;
- }
diff --git a/target/linux/generic/backport-6.18/400-v6.14-mtd-spinand-add-support-for-FORESEE-F35SQA001G.patch b/target/linux/generic/backport-6.18/400-v6.14-mtd-spinand-add-support-for-FORESEE-F35SQA001G.patch
deleted file mode 100644 (file)
index 84b3b2a..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-From ae461cde5c559675fc4c0ba351c7c31ace705f56 Mon Sep 17 00:00:00 2001
-From: Bohdan Chubuk <chbgdn@gmail.com>
-Date: Sun, 10 Nov 2024 22:50:47 +0200
-Subject: [PATCH] mtd: spinand: add support for FORESEE F35SQA001G
-
-Add support for FORESEE F35SQA001G SPI NAND.
-
-Similar to F35SQA002G, but differs in capacity.
-Datasheet:
-  -  https://cdn.ozdisan.com/ETicaret_Dosya/704795_871495.pdf
-
-Tested on Xiaomi AX3000T flashed with OpenWRT.
-
-Signed-off-by: Bohdan Chubuk <chbgdn@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/spi/foresee.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/mtd/nand/spi/foresee.c
-+++ b/drivers/mtd/nand/spi/foresee.c
-@@ -81,6 +81,16 @@ static const struct spinand_info foresee
-                    SPINAND_HAS_QE_BIT,
-                    SPINAND_ECCINFO(&f35sqa002g_ooblayout,
-                                    f35sqa002g_ecc_get_status)),
-+      SPINAND_INFO("F35SQA001G",
-+                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71, 0x71),
-+                   NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+                   NAND_ECCREQ(1, 512),
-+                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+                                            &write_cache_variants,
-+                                            &update_cache_variants),
-+                   SPINAND_HAS_QE_BIT,
-+                   SPINAND_ECCINFO(&f35sqa002g_ooblayout,
-+                                   f35sqa002g_ecc_get_status)),
- };
- static const struct spinand_manufacturer_ops foresee_spinand_manuf_ops = {
diff --git a/target/linux/generic/backport-6.18/401-v6.17-mtd-spinand-add-support-for-FudanMicro-FM25S01A.patch b/target/linux/generic/backport-6.18/401-v6.17-mtd-spinand-add-support-for-FudanMicro-FM25S01A.patch
deleted file mode 100644 (file)
index 0199fcb..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-From 5f284dc15ca8695d0394414045ac64616a3b0e69 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Mon, 25 Aug 2025 01:00:13 +0800
-Subject: [PATCH] mtd: spinand: add support for FudanMicro FM25S01A
-
-Add support for FudanMicro FM25S01A SPI NAND.
-Datasheet: http://eng.fmsh.com/nvm/FM25S01A_ds_eng.pdf
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20250824170013.3328777-1-cnsztl@gmail.com
----
- drivers/mtd/nand/spi/Makefile |  2 +-
- drivers/mtd/nand/spi/core.c   |  1 +
- drivers/mtd/nand/spi/fmsh.c   | 74 +++++++++++++++++++++++++++++++++++
- include/linux/mtd/spinand.h   |  1 +
- 4 files changed, 77 insertions(+), 1 deletion(-)
- create mode 100644 drivers/mtd/nand/spi/fmsh.c
-
---- a/drivers/mtd/nand/spi/Makefile
-+++ b/drivers/mtd/nand/spi/Makefile
-@@ -1,4 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
--spinand-objs := core.o alliancememory.o ato.o esmt.o foresee.o gigadevice.o macronix.o
-+spinand-objs := core.o alliancememory.o ato.o esmt.o fmsh.o foresee.o gigadevice.o macronix.o
- spinand-objs += micron.o paragon.o toshiba.o winbond.o xtx.o
- obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -1123,6 +1123,7 @@ static const struct spinand_manufacturer
-       &alliancememory_spinand_manufacturer,
-       &ato_spinand_manufacturer,
-       &esmt_c8_spinand_manufacturer,
-+      &fmsh_spinand_manufacturer,
-       &foresee_spinand_manufacturer,
-       &gigadevice_spinand_manufacturer,
-       &macronix_spinand_manufacturer,
---- /dev/null
-+++ b/drivers/mtd/nand/spi/fmsh.c
-@@ -0,0 +1,74 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd.
-+ *
-+ * Author: Dingqiang Lin <jon.lin@rock-chips.com>
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mtd/spinand.h>
-+
-+#define SPINAND_MFR_FMSH              0xA1
-+
-+static SPINAND_OP_VARIANTS(read_cache_variants,
-+              SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(write_cache_variants,
-+              SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
-+              SPINAND_PROG_LOAD(true, 0, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(update_cache_variants,
-+              SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
-+              SPINAND_PROG_LOAD(false, 0, NULL, 0));
-+
-+static int fm25s01a_ooblayout_ecc(struct mtd_info *mtd, int section,
-+                                struct mtd_oob_region *region)
-+{
-+      return -ERANGE;
-+}
-+
-+static int fm25s01a_ooblayout_free(struct mtd_info *mtd, int section,
-+                                 struct mtd_oob_region *region)
-+{
-+      if (section)
-+              return -ERANGE;
-+
-+      region->offset = 2;
-+      region->length = 62;
-+
-+      return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops fm25s01a_ooblayout = {
-+      .ecc = fm25s01a_ooblayout_ecc,
-+      .free = fm25s01a_ooblayout_free,
-+};
-+
-+static const struct spinand_info fmsh_spinand_table[] = {
-+      SPINAND_INFO("FM25S01A",
-+                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
-+                   NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+                   NAND_ECCREQ(1, 512),
-+                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+                                            &write_cache_variants,
-+                                            &update_cache_variants),
-+                   SPINAND_HAS_QE_BIT,
-+                   SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)),
-+};
-+
-+static const struct spinand_manufacturer_ops fmsh_spinand_manuf_ops = {
-+};
-+
-+const struct spinand_manufacturer fmsh_spinand_manufacturer = {
-+      .id = SPINAND_MFR_FMSH,
-+      .name = "Fudan Micro",
-+      .chips = fmsh_spinand_table,
-+      .nchips = ARRAY_SIZE(fmsh_spinand_table),
-+      .ops = &fmsh_spinand_manuf_ops,
-+};
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -263,6 +263,7 @@ struct spinand_manufacturer {
- extern const struct spinand_manufacturer alliancememory_spinand_manufacturer;
- extern const struct spinand_manufacturer ato_spinand_manufacturer;
- extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
-+extern const struct spinand_manufacturer fmsh_spinand_manufacturer;
- extern const struct spinand_manufacturer foresee_spinand_manufacturer;
- extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
- extern const struct spinand_manufacturer macronix_spinand_manufacturer;
diff --git a/target/linux/generic/backport-6.18/402-v6.18-mtd-nand-move-chunk-to-core.patch b/target/linux/generic/backport-6.18/402-v6.18-mtd-nand-move-chunk-to-core.patch
deleted file mode 100644 (file)
index 7933874..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-From 6b88293aae7fb78872e5cc1ec36e2f750ae12e38 Mon Sep 17 00:00:00 2001
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-Date: Wed, 10 Sep 2025 14:32:58 -0400
-Subject: mtd: nand: move nand_check_erased_ecc_chunk() to nand/core
-
-The check function for bitflips in erased blocks will be needed
-by the Realtek ECC engine driver (which is currently under
-development). Right now it is located in raw/nand_base.c.
-While this is sufficient for the current usecases, there is
-no real dependency for an ECC engine on the raw nand library.
-
-Move the function over to a more generic place in core library.
-
-Suggested-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/core.c          | 131 +++++++++++++++++++++++++++++++++++++++
- drivers/mtd/nand/raw/nand_base.c | 131 ---------------------------------------
- include/linux/mtd/nand.h         |   5 ++
- include/linux/mtd/rawnand.h      |   5 --
- 4 files changed, 136 insertions(+), 136 deletions(-)
-
---- a/drivers/mtd/nand/core.c
-+++ b/drivers/mtd/nand/core.c
-@@ -13,6 +13,137 @@
- #include <linux/mtd/nand.h>
- /**
-+ * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data
-+ * @buf: buffer to test
-+ * @len: buffer length
-+ * @bitflips_threshold: maximum number of bitflips
-+ *
-+ * Check if a buffer contains only 0xff, which means the underlying region
-+ * has been erased and is ready to be programmed.
-+ * The bitflips_threshold specify the maximum number of bitflips before
-+ * considering the region is not erased.
-+ * Note: The logic of this function has been extracted from the memweight
-+ * implementation, except that nand_check_erased_buf function exit before
-+ * testing the whole buffer if the number of bitflips exceed the
-+ * bitflips_threshold value.
-+ *
-+ * Returns a positive number of bitflips less than or equal to
-+ * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the
-+ * threshold.
-+ */
-+static int nand_check_erased_buf(void *buf, int len, int bitflips_threshold)
-+{
-+      const unsigned char *bitmap = buf;
-+      int bitflips = 0;
-+      int weight;
-+
-+      for (; len && ((uintptr_t)bitmap) % sizeof(long);
-+           len--, bitmap++) {
-+              weight = hweight8(*bitmap);
-+              bitflips += BITS_PER_BYTE - weight;
-+              if (unlikely(bitflips > bitflips_threshold))
-+                      return -EBADMSG;
-+      }
-+
-+      for (; len >= sizeof(long);
-+           len -= sizeof(long), bitmap += sizeof(long)) {
-+              unsigned long d = *((unsigned long *)bitmap);
-+              if (d == ~0UL)
-+                      continue;
-+              weight = hweight_long(d);
-+              bitflips += BITS_PER_LONG - weight;
-+              if (unlikely(bitflips > bitflips_threshold))
-+                      return -EBADMSG;
-+      }
-+
-+      for (; len > 0; len--, bitmap++) {
-+              weight = hweight8(*bitmap);
-+              bitflips += BITS_PER_BYTE - weight;
-+              if (unlikely(bitflips > bitflips_threshold))
-+                      return -EBADMSG;
-+      }
-+
-+      return bitflips;
-+}
-+
-+/**
-+ * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only
-+ *                             0xff data
-+ * @data: data buffer to test
-+ * @datalen: data length
-+ * @ecc: ECC buffer
-+ * @ecclen: ECC length
-+ * @extraoob: extra OOB buffer
-+ * @extraooblen: extra OOB length
-+ * @bitflips_threshold: maximum number of bitflips
-+ *
-+ * Check if a data buffer and its associated ECC and OOB data contains only
-+ * 0xff pattern, which means the underlying region has been erased and is
-+ * ready to be programmed.
-+ * The bitflips_threshold specify the maximum number of bitflips before
-+ * considering the region as not erased.
-+ *
-+ * Note:
-+ * 1/ ECC algorithms are working on pre-defined block sizes which are usually
-+ *    different from the NAND page size. When fixing bitflips, ECC engines will
-+ *    report the number of errors per chunk, and the NAND core infrastructure
-+ *    expect you to return the maximum number of bitflips for the whole page.
-+ *    This is why you should always use this function on a single chunk and
-+ *    not on the whole page. After checking each chunk you should update your
-+ *    max_bitflips value accordingly.
-+ * 2/ When checking for bitflips in erased pages you should not only check
-+ *    the payload data but also their associated ECC data, because a user might
-+ *    have programmed almost all bits to 1 but a few. In this case, we
-+ *    shouldn't consider the chunk as erased, and checking ECC bytes prevent
-+ *    this case.
-+ * 3/ The extraoob argument is optional, and should be used if some of your OOB
-+ *    data are protected by the ECC engine.
-+ *    It could also be used if you support subpages and want to attach some
-+ *    extra OOB data to an ECC chunk.
-+ *
-+ * Returns a positive number of bitflips less than or equal to
-+ * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the
-+ * threshold. In case of success, the passed buffers are filled with 0xff.
-+ */
-+int nand_check_erased_ecc_chunk(void *data, int datalen,
-+                              void *ecc, int ecclen,
-+                              void *extraoob, int extraooblen,
-+                              int bitflips_threshold)
-+{
-+      int data_bitflips = 0, ecc_bitflips = 0, extraoob_bitflips = 0;
-+
-+      data_bitflips = nand_check_erased_buf(data, datalen,
-+                                            bitflips_threshold);
-+      if (data_bitflips < 0)
-+              return data_bitflips;
-+
-+      bitflips_threshold -= data_bitflips;
-+
-+      ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold);
-+      if (ecc_bitflips < 0)
-+              return ecc_bitflips;
-+
-+      bitflips_threshold -= ecc_bitflips;
-+
-+      extraoob_bitflips = nand_check_erased_buf(extraoob, extraooblen,
-+                                                bitflips_threshold);
-+      if (extraoob_bitflips < 0)
-+              return extraoob_bitflips;
-+
-+      if (data_bitflips)
-+              memset(data, 0xff, datalen);
-+
-+      if (ecc_bitflips)
-+              memset(ecc, 0xff, ecclen);
-+
-+      if (extraoob_bitflips)
-+              memset(extraoob, 0xff, extraooblen);
-+
-+      return data_bitflips + ecc_bitflips + extraoob_bitflips;
-+}
-+EXPORT_SYMBOL(nand_check_erased_ecc_chunk);
-+
-+/**
-  * nanddev_isbad() - Check if a block is bad
-  * @nand: NAND device
-  * @pos: position pointing to the block we want to check
---- a/drivers/mtd/nand/raw/nand_base.c
-+++ b/drivers/mtd/nand/raw/nand_base.c
-@@ -2784,137 +2784,6 @@ int nand_set_features(struct nand_chip *
- }
- /**
-- * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data
-- * @buf: buffer to test
-- * @len: buffer length
-- * @bitflips_threshold: maximum number of bitflips
-- *
-- * Check if a buffer contains only 0xff, which means the underlying region
-- * has been erased and is ready to be programmed.
-- * The bitflips_threshold specify the maximum number of bitflips before
-- * considering the region is not erased.
-- * Note: The logic of this function has been extracted from the memweight
-- * implementation, except that nand_check_erased_buf function exit before
-- * testing the whole buffer if the number of bitflips exceed the
-- * bitflips_threshold value.
-- *
-- * Returns a positive number of bitflips less than or equal to
-- * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the
-- * threshold.
-- */
--static int nand_check_erased_buf(void *buf, int len, int bitflips_threshold)
--{
--      const unsigned char *bitmap = buf;
--      int bitflips = 0;
--      int weight;
--
--      for (; len && ((uintptr_t)bitmap) % sizeof(long);
--           len--, bitmap++) {
--              weight = hweight8(*bitmap);
--              bitflips += BITS_PER_BYTE - weight;
--              if (unlikely(bitflips > bitflips_threshold))
--                      return -EBADMSG;
--      }
--
--      for (; len >= sizeof(long);
--           len -= sizeof(long), bitmap += sizeof(long)) {
--              unsigned long d = *((unsigned long *)bitmap);
--              if (d == ~0UL)
--                      continue;
--              weight = hweight_long(d);
--              bitflips += BITS_PER_LONG - weight;
--              if (unlikely(bitflips > bitflips_threshold))
--                      return -EBADMSG;
--      }
--
--      for (; len > 0; len--, bitmap++) {
--              weight = hweight8(*bitmap);
--              bitflips += BITS_PER_BYTE - weight;
--              if (unlikely(bitflips > bitflips_threshold))
--                      return -EBADMSG;
--      }
--
--      return bitflips;
--}
--
--/**
-- * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only
-- *                             0xff data
-- * @data: data buffer to test
-- * @datalen: data length
-- * @ecc: ECC buffer
-- * @ecclen: ECC length
-- * @extraoob: extra OOB buffer
-- * @extraooblen: extra OOB length
-- * @bitflips_threshold: maximum number of bitflips
-- *
-- * Check if a data buffer and its associated ECC and OOB data contains only
-- * 0xff pattern, which means the underlying region has been erased and is
-- * ready to be programmed.
-- * The bitflips_threshold specify the maximum number of bitflips before
-- * considering the region as not erased.
-- *
-- * Note:
-- * 1/ ECC algorithms are working on pre-defined block sizes which are usually
-- *    different from the NAND page size. When fixing bitflips, ECC engines will
-- *    report the number of errors per chunk, and the NAND core infrastructure
-- *    expect you to return the maximum number of bitflips for the whole page.
-- *    This is why you should always use this function on a single chunk and
-- *    not on the whole page. After checking each chunk you should update your
-- *    max_bitflips value accordingly.
-- * 2/ When checking for bitflips in erased pages you should not only check
-- *    the payload data but also their associated ECC data, because a user might
-- *    have programmed almost all bits to 1 but a few. In this case, we
-- *    shouldn't consider the chunk as erased, and checking ECC bytes prevent
-- *    this case.
-- * 3/ The extraoob argument is optional, and should be used if some of your OOB
-- *    data are protected by the ECC engine.
-- *    It could also be used if you support subpages and want to attach some
-- *    extra OOB data to an ECC chunk.
-- *
-- * Returns a positive number of bitflips less than or equal to
-- * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the
-- * threshold. In case of success, the passed buffers are filled with 0xff.
-- */
--int nand_check_erased_ecc_chunk(void *data, int datalen,
--                              void *ecc, int ecclen,
--                              void *extraoob, int extraooblen,
--                              int bitflips_threshold)
--{
--      int data_bitflips = 0, ecc_bitflips = 0, extraoob_bitflips = 0;
--
--      data_bitflips = nand_check_erased_buf(data, datalen,
--                                            bitflips_threshold);
--      if (data_bitflips < 0)
--              return data_bitflips;
--
--      bitflips_threshold -= data_bitflips;
--
--      ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold);
--      if (ecc_bitflips < 0)
--              return ecc_bitflips;
--
--      bitflips_threshold -= ecc_bitflips;
--
--      extraoob_bitflips = nand_check_erased_buf(extraoob, extraooblen,
--                                                bitflips_threshold);
--      if (extraoob_bitflips < 0)
--              return extraoob_bitflips;
--
--      if (data_bitflips)
--              memset(data, 0xff, datalen);
--
--      if (ecc_bitflips)
--              memset(ecc, 0xff, ecclen);
--
--      if (extraoob_bitflips)
--              memset(extraoob, 0xff, extraooblen);
--
--      return data_bitflips + ecc_bitflips + extraoob_bitflips;
--}
--EXPORT_SYMBOL(nand_check_erased_ecc_chunk);
--
--/**
-  * nand_read_page_raw_notsupp - dummy read raw page function
-  * @chip: nand chip info structure
-  * @buf: buffer to store read data
---- a/include/linux/mtd/nand.h
-+++ b/include/linux/mtd/nand.h
-@@ -1136,4 +1136,9 @@ static inline bool nanddev_bbt_is_initia
- int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo);
- int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len);
-+int nand_check_erased_ecc_chunk(void *data, int datalen,
-+                              void *ecc, int ecclen,
-+                              void *extraoob, int extraooblen,
-+                              int threshold);
-+
- #endif /* __LINUX_MTD_NAND_H */
---- a/include/linux/mtd/rawnand.h
-+++ b/include/linux/mtd/rawnand.h
-@@ -1519,11 +1519,6 @@ int rawnand_sw_bch_correct(struct nand_c
-                          unsigned char *read_ecc, unsigned char *calc_ecc);
- void rawnand_sw_bch_cleanup(struct nand_chip *chip);
--int nand_check_erased_ecc_chunk(void *data, int datalen,
--                              void *ecc, int ecclen,
--                              void *extraoob, int extraooblen,
--                              int threshold);
--
- int nand_ecc_choose_conf(struct nand_chip *chip,
-                        const struct nand_ecc_caps *caps, int oobavail);
diff --git a/target/linux/generic/backport-6.18/404-v6.19-mtd-spinand-fmsh-remove-QE-bit-for-FM25S01A-flash.patch b/target/linux/generic/backport-6.18/404-v6.19-mtd-spinand-fmsh-remove-QE-bit-for-FM25S01A-flash.patch
deleted file mode 100644 (file)
index 7f9ec6a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From a1d3bc606bf5c3b3ea811cc2019df6285d75b00f Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Mon, 3 Nov 2025 04:01:48 +0300
-Subject: [PATCH] mtd: spinand: fmsh: remove QE bit for FM25S01A flash
-
-According to datasheet (http://eng.fmsh.com/nvm/FM25S01A_ds_eng.pdf)
-there is no QE (Quad Enable) bit for FM25S01A flash, so remove it.
-
-Fixes: 5f284dc15ca86 ("mtd: spinand: add support for FudanMicro FM25S01A")
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Tested-by: Tianling Shen <cnsztl@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: Link: https://lore.kernel.org/linux-mtd/176216634975.908445.2776312239779833518.b4-ty@bootlin.com
----
- drivers/mtd/nand/spi/fmsh.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/spi/fmsh.c
-+++ b/drivers/mtd/nand/spi/fmsh.c
-@@ -58,7 +58,7 @@ static const struct spinand_info fmsh_sp
-                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-                                             &write_cache_variants,
-                                             &update_cache_variants),
--                   SPINAND_HAS_QE_BIT,
-+                   0,
-                    SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)),
- };
diff --git a/target/linux/generic/backport-6.18/410-01-v6.14-mtd-rawnand-qcom-cleanup-qcom_nandc-driver.patch b/target/linux/generic/backport-6.18/410-01-v6.14-mtd-rawnand-qcom-cleanup-qcom_nandc-driver.patch
deleted file mode 100644 (file)
index 1d1288e..0000000
+++ /dev/null
@@ -1,1026 +0,0 @@
-From 8c52932da5e6756fa66f52f0720da283fba13aa6 Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Wed, 20 Nov 2024 14:45:00 +0530
-Subject: [PATCH 1/4] mtd: rawnand: qcom: cleanup qcom_nandc driver
-
-Perform a global cleanup of the Qualcomm NAND
-controller driver with the following improvements:
-
-- Remove register value indirection API
-
-- Remove set_reg() API
-
-- Convert read_loc_first & read_loc_last macro to functions
-
-- Rename multiple variables
-
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/raw/qcom_nandc.c | 516 ++++++++++++++----------------
- 1 file changed, 234 insertions(+), 282 deletions(-)
-
---- a/drivers/mtd/nand/raw/qcom_nandc.c
-+++ b/drivers/mtd/nand/raw/qcom_nandc.c
-@@ -189,17 +189,6 @@
- #define       ECC_BCH_4BIT    BIT(2)
- #define       ECC_BCH_8BIT    BIT(3)
--#define nandc_set_read_loc_first(chip, reg, cw_offset, read_size, is_last_read_loc)   \
--nandc_set_reg(chip, reg,                      \
--            ((cw_offset) << READ_LOCATION_OFFSET) |           \
--            ((read_size) << READ_LOCATION_SIZE) |                     \
--            ((is_last_read_loc) << READ_LOCATION_LAST))
--
--#define nandc_set_read_loc_last(chip, reg, cw_offset, read_size, is_last_read_loc)    \
--nandc_set_reg(chip, reg,                      \
--            ((cw_offset) << READ_LOCATION_OFFSET) |           \
--            ((read_size) << READ_LOCATION_SIZE) |                     \
--            ((is_last_read_loc) << READ_LOCATION_LAST))
- /*
-  * Returns the actual register address for all NAND_DEV_ registers
-  * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD)
-@@ -257,8 +246,6 @@ nandc_set_reg(chip, reg,                   \
-  * @tx_sgl_start - start index in data sgl for tx.
-  * @rx_sgl_pos - current index in data sgl for rx.
-  * @rx_sgl_start - start index in data sgl for rx.
-- * @wait_second_completion - wait for second DMA desc completion before making
-- *                         the NAND transfer completion.
-  */
- struct bam_transaction {
-       struct bam_cmd_element *bam_ce;
-@@ -275,7 +262,6 @@ struct bam_transaction {
-       u32 tx_sgl_start;
-       u32 rx_sgl_pos;
-       u32 rx_sgl_start;
--      bool wait_second_completion;
- };
- /*
-@@ -471,9 +457,9 @@ struct qcom_op {
-       unsigned int data_instr_idx;
-       unsigned int rdy_timeout_ms;
-       unsigned int rdy_delay_ns;
--      u32 addr1_reg;
--      u32 addr2_reg;
--      u32 cmd_reg;
-+      __le32 addr1_reg;
-+      __le32 addr2_reg;
-+      __le32 cmd_reg;
-       u8 flag;
- };
-@@ -549,17 +535,17 @@ struct qcom_nand_host {
-  * among different NAND controllers.
-  * @ecc_modes - ecc mode for NAND
-  * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset
-- * @is_bam - whether NAND controller is using BAM
-- * @is_qpic - whether NAND CTRL is part of qpic IP
-- * @qpic_v2 - flag to indicate QPIC IP version 2
-+ * @supports_bam - whether NAND controller is using Bus Access Manager (BAM)
-+ * @nandc_part_of_qpic - whether NAND controller is part of qpic IP
-+ * @qpic_version2 - flag to indicate QPIC IP version 2
-  * @use_codeword_fixup - whether NAND has different layout for boot partitions
-  */
- struct qcom_nandc_props {
-       u32 ecc_modes;
-       u32 dev_cmd_reg_start;
--      bool is_bam;
--      bool is_qpic;
--      bool qpic_v2;
-+      bool supports_bam;
-+      bool nandc_part_of_qpic;
-+      bool qpic_version2;
-       bool use_codeword_fixup;
- };
-@@ -613,19 +599,11 @@ static void clear_bam_transaction(struct
- {
-       struct bam_transaction *bam_txn = nandc->bam_txn;
--      if (!nandc->props->is_bam)
-+      if (!nandc->props->supports_bam)
-               return;
--      bam_txn->bam_ce_pos = 0;
--      bam_txn->bam_ce_start = 0;
--      bam_txn->cmd_sgl_pos = 0;
--      bam_txn->cmd_sgl_start = 0;
--      bam_txn->tx_sgl_pos = 0;
--      bam_txn->tx_sgl_start = 0;
--      bam_txn->rx_sgl_pos = 0;
--      bam_txn->rx_sgl_start = 0;
-+      memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8);
-       bam_txn->last_data_desc = NULL;
--      bam_txn->wait_second_completion = false;
-       sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
-                     QPIC_PER_CW_CMD_SGL);
-@@ -640,46 +618,35 @@ static void qpic_bam_dma_done(void *data
- {
-       struct bam_transaction *bam_txn = data;
--      /*
--       * In case of data transfer with NAND, 2 callbacks will be generated.
--       * One for command channel and another one for data channel.
--       * If current transaction has data descriptors
--       * (i.e. wait_second_completion is true), then set this to false
--       * and wait for second DMA descriptor completion.
--       */
--      if (bam_txn->wait_second_completion)
--              bam_txn->wait_second_completion = false;
--      else
--              complete(&bam_txn->txn_done);
-+      complete(&bam_txn->txn_done);
- }
--static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
-+static struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
- {
-       return container_of(chip, struct qcom_nand_host, chip);
- }
--static inline struct qcom_nand_controller *
-+static struct qcom_nand_controller *
- get_qcom_nand_controller(struct nand_chip *chip)
- {
-       return container_of(chip->controller, struct qcom_nand_controller,
-                           controller);
- }
--static inline u32 nandc_read(struct qcom_nand_controller *nandc, int offset)
-+static u32 nandc_read(struct qcom_nand_controller *nandc, int offset)
- {
-       return ioread32(nandc->base + offset);
- }
--static inline void nandc_write(struct qcom_nand_controller *nandc, int offset,
--                             u32 val)
-+static void nandc_write(struct qcom_nand_controller *nandc, int offset,
-+                      u32 val)
- {
-       iowrite32(val, nandc->base + offset);
- }
--static inline void nandc_read_buffer_sync(struct qcom_nand_controller *nandc,
--                                        bool is_cpu)
-+static void nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu)
- {
--      if (!nandc->props->is_bam)
-+      if (!nandc->props->supports_bam)
-               return;
-       if (is_cpu)
-@@ -694,93 +661,90 @@ static inline void nandc_read_buffer_syn
-                                          DMA_FROM_DEVICE);
- }
--static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
--{
--      switch (offset) {
--      case NAND_FLASH_CMD:
--              return &regs->cmd;
--      case NAND_ADDR0:
--              return &regs->addr0;
--      case NAND_ADDR1:
--              return &regs->addr1;
--      case NAND_FLASH_CHIP_SELECT:
--              return &regs->chip_sel;
--      case NAND_EXEC_CMD:
--              return &regs->exec;
--      case NAND_FLASH_STATUS:
--              return &regs->clrflashstatus;
--      case NAND_DEV0_CFG0:
--              return &regs->cfg0;
--      case NAND_DEV0_CFG1:
--              return &regs->cfg1;
--      case NAND_DEV0_ECC_CFG:
--              return &regs->ecc_bch_cfg;
--      case NAND_READ_STATUS:
--              return &regs->clrreadstatus;
--      case NAND_DEV_CMD1:
--              return &regs->cmd1;
--      case NAND_DEV_CMD1_RESTORE:
--              return &regs->orig_cmd1;
--      case NAND_DEV_CMD_VLD:
--              return &regs->vld;
--      case NAND_DEV_CMD_VLD_RESTORE:
--              return &regs->orig_vld;
--      case NAND_EBI2_ECC_BUF_CFG:
--              return &regs->ecc_buf_cfg;
--      case NAND_READ_LOCATION_0:
--              return &regs->read_location0;
--      case NAND_READ_LOCATION_1:
--              return &regs->read_location1;
--      case NAND_READ_LOCATION_2:
--              return &regs->read_location2;
--      case NAND_READ_LOCATION_3:
--              return &regs->read_location3;
--      case NAND_READ_LOCATION_LAST_CW_0:
--              return &regs->read_location_last0;
--      case NAND_READ_LOCATION_LAST_CW_1:
--              return &regs->read_location_last1;
--      case NAND_READ_LOCATION_LAST_CW_2:
--              return &regs->read_location_last2;
--      case NAND_READ_LOCATION_LAST_CW_3:
--              return &regs->read_location_last3;
--      default:
--              return NULL;
--      }
--}
--
--static void nandc_set_reg(struct nand_chip *chip, int offset,
--                        u32 val)
--{
--      struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
--      struct nandc_regs *regs = nandc->regs;
--      __le32 *reg;
--
--      reg = offset_to_nandc_reg(regs, offset);
--
--      if (reg)
--              *reg = cpu_to_le32(val);
--}
--
--/* Helper to check the code word, whether it is last cw or not */
-+/* Helper to check whether this is the last CW or not */
- static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw)
- {
-       return cw == (ecc->steps - 1);
- }
-+/**
-+ * nandc_set_read_loc_first() - to set read location first register
-+ * @chip:             NAND Private Flash Chip Data
-+ * @reg_base:         location register base
-+ * @cw_offset:                code word offset
-+ * @read_size:                code word read length
-+ * @is_last_read_loc: is this the last read location
-+ *
-+ * This function will set location register value
-+ */
-+static void nandc_set_read_loc_first(struct nand_chip *chip,
-+                                   int reg_base, u32 cw_offset,
-+                                   u32 read_size, u32 is_last_read_loc)
-+{
-+      struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-+      __le32 locreg_val;
-+      u32 val = (((cw_offset) << READ_LOCATION_OFFSET) |
-+                ((read_size) << READ_LOCATION_SIZE) |
-+                ((is_last_read_loc) << READ_LOCATION_LAST));
-+
-+      locreg_val = cpu_to_le32(val);
-+
-+      if (reg_base == NAND_READ_LOCATION_0)
-+              nandc->regs->read_location0 = locreg_val;
-+      else if (reg_base == NAND_READ_LOCATION_1)
-+              nandc->regs->read_location1 = locreg_val;
-+      else if (reg_base == NAND_READ_LOCATION_2)
-+              nandc->regs->read_location2 = locreg_val;
-+      else if (reg_base == NAND_READ_LOCATION_3)
-+              nandc->regs->read_location3 = locreg_val;
-+}
-+
-+/**
-+ * nandc_set_read_loc_last - to set read location last register
-+ * @chip:             NAND Private Flash Chip Data
-+ * @reg_base:         location register base
-+ * @cw_offset:                code word offset
-+ * @read_size:                code word read length
-+ * @is_last_read_loc: is this the last read location
-+ *
-+ * This function will set location last register value
-+ */
-+static void nandc_set_read_loc_last(struct nand_chip *chip,
-+                                  int reg_base, u32 cw_offset,
-+                                  u32 read_size, u32 is_last_read_loc)
-+{
-+      struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-+      __le32 locreg_val;
-+      u32 val = (((cw_offset) << READ_LOCATION_OFFSET) |
-+                ((read_size) << READ_LOCATION_SIZE) |
-+                ((is_last_read_loc) << READ_LOCATION_LAST));
-+
-+      locreg_val = cpu_to_le32(val);
-+
-+      if (reg_base == NAND_READ_LOCATION_LAST_CW_0)
-+              nandc->regs->read_location_last0 = locreg_val;
-+      else if (reg_base == NAND_READ_LOCATION_LAST_CW_1)
-+              nandc->regs->read_location_last1 = locreg_val;
-+      else if (reg_base == NAND_READ_LOCATION_LAST_CW_2)
-+              nandc->regs->read_location_last2 = locreg_val;
-+      else if (reg_base == NAND_READ_LOCATION_LAST_CW_3)
-+              nandc->regs->read_location_last3 = locreg_val;
-+}
-+
- /* helper to configure location register values */
- static void nandc_set_read_loc(struct nand_chip *chip, int cw, int reg,
--                             int cw_offset, int read_size, int is_last_read_loc)
-+                             u32 cw_offset, u32 read_size, u32 is_last_read_loc)
- {
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-       struct nand_ecc_ctrl *ecc = &chip->ecc;
-       int reg_base = NAND_READ_LOCATION_0;
--      if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw))
-+      if (nandc->props->qpic_version2 && qcom_nandc_is_last_cw(ecc, cw))
-               reg_base = NAND_READ_LOCATION_LAST_CW_0;
-       reg_base += reg * 4;
--      if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw))
-+      if (nandc->props->qpic_version2 && qcom_nandc_is_last_cw(ecc, cw))
-               return nandc_set_read_loc_last(chip, reg_base, cw_offset,
-                               read_size, is_last_read_loc);
-       else
-@@ -792,12 +756,13 @@ static void nandc_set_read_loc(struct na
- static void set_address(struct qcom_nand_host *host, u16 column, int page)
- {
-       struct nand_chip *chip = &host->chip;
-+      struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-       if (chip->options & NAND_BUSWIDTH_16)
-               column >>= 1;
--      nandc_set_reg(chip, NAND_ADDR0, page << 16 | column);
--      nandc_set_reg(chip, NAND_ADDR1, page >> 16 & 0xff);
-+      nandc->regs->addr0 = cpu_to_le32(page << 16 | column);
-+      nandc->regs->addr1 = cpu_to_le32(page >> 16 & 0xff);
- }
- /*
-@@ -811,41 +776,43 @@ static void set_address(struct qcom_nand
- static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, int cw)
- {
-       struct nand_chip *chip = &host->chip;
--      u32 cmd, cfg0, cfg1, ecc_bch_cfg;
-+      __le32 cmd, cfg0, cfg1, ecc_bch_cfg;
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-       if (read) {
-               if (host->use_ecc)
--                      cmd = OP_PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE;
-+                      cmd = cpu_to_le32(OP_PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE);
-               else
--                      cmd = OP_PAGE_READ | PAGE_ACC | LAST_PAGE;
-+                      cmd = cpu_to_le32(OP_PAGE_READ | PAGE_ACC | LAST_PAGE);
-       } else {
--              cmd = OP_PROGRAM_PAGE | PAGE_ACC | LAST_PAGE;
-+              cmd = cpu_to_le32(OP_PROGRAM_PAGE | PAGE_ACC | LAST_PAGE);
-       }
-       if (host->use_ecc) {
--              cfg0 = (host->cfg0 & ~(7U << CW_PER_PAGE)) |
--                              (num_cw - 1) << CW_PER_PAGE;
-+              cfg0 = cpu_to_le32((host->cfg0 & ~(7U << CW_PER_PAGE)) |
-+                              (num_cw - 1) << CW_PER_PAGE);
--              cfg1 = host->cfg1;
--              ecc_bch_cfg = host->ecc_bch_cfg;
-+              cfg1 = cpu_to_le32(host->cfg1);
-+              ecc_bch_cfg = cpu_to_le32(host->ecc_bch_cfg);
-       } else {
--              cfg0 = (host->cfg0_raw & ~(7U << CW_PER_PAGE)) |
--                              (num_cw - 1) << CW_PER_PAGE;
-+              cfg0 = cpu_to_le32((host->cfg0_raw & ~(7U << CW_PER_PAGE)) |
-+                              (num_cw - 1) << CW_PER_PAGE);
--              cfg1 = host->cfg1_raw;
--              ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE;
-+              cfg1 = cpu_to_le32(host->cfg1_raw);
-+              ecc_bch_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE);
-       }
--      nandc_set_reg(chip, NAND_FLASH_CMD, cmd);
--      nandc_set_reg(chip, NAND_DEV0_CFG0, cfg0);
--      nandc_set_reg(chip, NAND_DEV0_CFG1, cfg1);
--      nandc_set_reg(chip, NAND_DEV0_ECC_CFG, ecc_bch_cfg);
--      if (!nandc->props->qpic_v2)
--              nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, host->ecc_buf_cfg);
--      nandc_set_reg(chip, NAND_FLASH_STATUS, host->clrflashstatus);
--      nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus);
--      nandc_set_reg(chip, NAND_EXEC_CMD, 1);
-+      nandc->regs->cmd = cmd;
-+      nandc->regs->cfg0 = cfg0;
-+      nandc->regs->cfg1 = cfg1;
-+      nandc->regs->ecc_bch_cfg = ecc_bch_cfg;
-+
-+      if (!nandc->props->qpic_version2)
-+              nandc->regs->ecc_buf_cfg = cpu_to_le32(host->ecc_buf_cfg);
-+
-+      nandc->regs->clrflashstatus = cpu_to_le32(host->clrflashstatus);
-+      nandc->regs->clrreadstatus = cpu_to_le32(host->clrreadstatus);
-+      nandc->regs->exec = cpu_to_le32(1);
-       if (read)
-               nandc_set_read_loc(chip, cw, 0, 0, host->use_ecc ?
-@@ -1121,7 +1088,7 @@ static int read_reg_dma(struct qcom_nand
-       if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1)
-               first = dev_cmd_reg_addr(nandc, first);
--      if (nandc->props->is_bam)
-+      if (nandc->props->supports_bam)
-               return prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
-                                            num_regs, flags);
-@@ -1136,25 +1103,16 @@ static int read_reg_dma(struct qcom_nand
-  * write_reg_dma:     prepares a descriptor to write a given number of
-  *                    contiguous registers
-  *
-+ * @vaddr:            contiguous memory from where register value will
-+ *                    be written
-  * @first:            offset of the first register in the contiguous block
-  * @num_regs:         number of registers to write
-  * @flags:            flags to control DMA descriptor preparation
-  */
--static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
--                       int num_regs, unsigned int flags)
-+static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
-+                       int first, int num_regs, unsigned int flags)
- {
-       bool flow_control = false;
--      struct nandc_regs *regs = nandc->regs;
--      void *vaddr;
--
--      vaddr = offset_to_nandc_reg(regs, first);
--
--      if (first == NAND_ERASED_CW_DETECT_CFG) {
--              if (flags & NAND_ERASED_CW_SET)
--                      vaddr = &regs->erased_cw_detect_cfg_set;
--              else
--                      vaddr = &regs->erased_cw_detect_cfg_clr;
--      }
-       if (first == NAND_EXEC_CMD)
-               flags |= NAND_BAM_NWD;
-@@ -1165,7 +1123,7 @@ static int write_reg_dma(struct qcom_nan
-       if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD)
-               first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD);
--      if (nandc->props->is_bam)
-+      if (nandc->props->supports_bam)
-               return prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
-                                            num_regs, flags);
-@@ -1188,7 +1146,7 @@ static int write_reg_dma(struct qcom_nan
- static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-                        const u8 *vaddr, int size, unsigned int flags)
- {
--      if (nandc->props->is_bam)
-+      if (nandc->props->supports_bam)
-               return prep_bam_dma_desc_data(nandc, true, vaddr, size, flags);
-       return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
-@@ -1206,7 +1164,7 @@ static int read_data_dma(struct qcom_nan
- static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-                         const u8 *vaddr, int size, unsigned int flags)
- {
--      if (nandc->props->is_bam)
-+      if (nandc->props->supports_bam)
-               return prep_bam_dma_desc_data(nandc, false, vaddr, size, flags);
-       return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
-@@ -1220,13 +1178,14 @@ static void config_nand_page_read(struct
- {
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
--      write_reg_dma(nandc, NAND_ADDR0, 2, 0);
--      write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
--      if (!nandc->props->qpic_v2)
--              write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
--      write_reg_dma(nandc, NAND_ERASED_CW_DETECT_CFG, 1, 0);
--      write_reg_dma(nandc, NAND_ERASED_CW_DETECT_CFG, 1,
--                    NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      if (!nandc->props->qpic_version2)
-+              write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0);
-+      write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_clr,
-+                    NAND_ERASED_CW_DETECT_CFG, 1, 0);
-+      write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_set,
-+                    NAND_ERASED_CW_DETECT_CFG, 1, NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
- }
- /*
-@@ -1239,16 +1198,16 @@ config_nand_cw_read(struct nand_chip *ch
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-       struct nand_ecc_ctrl *ecc = &chip->ecc;
--      int reg = NAND_READ_LOCATION_0;
-+      __le32 *reg = &nandc->regs->read_location0;
--      if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw))
--              reg = NAND_READ_LOCATION_LAST_CW_0;
-+      if (nandc->props->qpic_version2 && qcom_nandc_is_last_cw(ecc, cw))
-+              reg = &nandc->regs->read_location_last0;
--      if (nandc->props->is_bam)
--              write_reg_dma(nandc, reg, 4, NAND_BAM_NEXT_SGL);
-+      if (nandc->props->supports_bam)
-+              write_reg_dma(nandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-       if (use_ecc) {
-               read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
-@@ -1279,10 +1238,10 @@ static void config_nand_page_write(struc
- {
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
--      write_reg_dma(nandc, NAND_ADDR0, 2, 0);
--      write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
--      if (!nandc->props->qpic_v2)
--              write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1,
-+      write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      if (!nandc->props->qpic_version2)
-+              write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1,
-                             NAND_BAM_NEXT_SGL);
- }
-@@ -1294,13 +1253,13 @@ static void config_nand_cw_write(struct
- {
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
--      write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-       read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0);
--      write_reg_dma(nandc, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0);
-+      write_reg_dma(nandc, &nandc->regs->clrreadstatus, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
- }
- /* helpers to submit/free our list of dma descriptors */
-@@ -1311,7 +1270,7 @@ static int submit_descs(struct qcom_nand
-       struct bam_transaction *bam_txn = nandc->bam_txn;
-       int ret = 0;
--      if (nandc->props->is_bam) {
-+      if (nandc->props->supports_bam) {
-               if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) {
-                       ret = prepare_bam_async_desc(nandc, nandc->rx_chan, 0);
-                       if (ret)
-@@ -1336,14 +1295,9 @@ static int submit_descs(struct qcom_nand
-       list_for_each_entry(desc, &nandc->desc_list, node)
-               cookie = dmaengine_submit(desc->dma_desc);
--      if (nandc->props->is_bam) {
-+      if (nandc->props->supports_bam) {
-               bam_txn->last_cmd_desc->callback = qpic_bam_dma_done;
-               bam_txn->last_cmd_desc->callback_param = bam_txn;
--              if (bam_txn->last_data_desc) {
--                      bam_txn->last_data_desc->callback = qpic_bam_dma_done;
--                      bam_txn->last_data_desc->callback_param = bam_txn;
--                      bam_txn->wait_second_completion = true;
--              }
-               dma_async_issue_pending(nandc->tx_chan);
-               dma_async_issue_pending(nandc->rx_chan);
-@@ -1365,7 +1319,7 @@ err_unmap_free_desc:
-       list_for_each_entry_safe(desc, n, &nandc->desc_list, node) {
-               list_del(&desc->node);
--              if (nandc->props->is_bam)
-+              if (nandc->props->supports_bam)
-                       dma_unmap_sg(nandc->dev, desc->bam_sgl,
-                                    desc->sgl_cnt, desc->dir);
-               else
-@@ -1382,7 +1336,7 @@ err_unmap_free_desc:
- static void clear_read_regs(struct qcom_nand_controller *nandc)
- {
-       nandc->reg_read_pos = 0;
--      nandc_read_buffer_sync(nandc, false);
-+      nandc_dev_to_mem(nandc, false);
- }
- /*
-@@ -1446,7 +1400,7 @@ static int check_flash_errors(struct qco
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-       int i;
--      nandc_read_buffer_sync(nandc, true);
-+      nandc_dev_to_mem(nandc, true);
-       for (i = 0; i < cw_cnt; i++) {
-               u32 flash = le32_to_cpu(nandc->reg_read_buf[i]);
-@@ -1476,7 +1430,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *
-       clear_read_regs(nandc);
-       host->use_ecc = false;
--      if (nandc->props->qpic_v2)
-+      if (nandc->props->qpic_version2)
-               raw_cw = ecc->steps - 1;
-       clear_bam_transaction(nandc);
-@@ -1497,7 +1451,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *
-               oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
-       }
--      if (nandc->props->is_bam) {
-+      if (nandc->props->supports_bam) {
-               nandc_set_read_loc(chip, cw, 0, read_loc, data_size1, 0);
-               read_loc += data_size1;
-@@ -1621,7 +1575,7 @@ static int parse_read_errors(struct qcom
-       u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf;
-       buf = (struct read_stats *)nandc->reg_read_buf;
--      nandc_read_buffer_sync(nandc, true);
-+      nandc_dev_to_mem(nandc, true);
-       for (i = 0; i < ecc->steps; i++, buf++) {
-               u32 flash, buffer, erased_cw;
-@@ -1734,7 +1688,7 @@ static int read_page_ecc(struct qcom_nan
-                       oob_size = host->ecc_bytes_hw + host->spare_bytes;
-               }
--              if (nandc->props->is_bam) {
-+              if (nandc->props->supports_bam) {
-                       if (data_buf && oob_buf) {
-                               nandc_set_read_loc(chip, i, 0, 0, data_size, 0);
-                               nandc_set_read_loc(chip, i, 1, data_size,
-@@ -2455,14 +2409,14 @@ static int qcom_nand_attach_chip(struct
-       mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
-       /* Free the initially allocated BAM transaction for reading the ONFI params */
--      if (nandc->props->is_bam)
-+      if (nandc->props->supports_bam)
-               free_bam_transaction(nandc);
-       nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage,
-                                    cwperpage);
-       /* Now allocate the BAM transaction based on updated max_cwperpage */
--      if (nandc->props->is_bam) {
-+      if (nandc->props->supports_bam) {
-               nandc->bam_txn = alloc_bam_transaction(nandc);
-               if (!nandc->bam_txn) {
-                       dev_err(nandc->dev,
-@@ -2522,7 +2476,7 @@ static int qcom_nand_attach_chip(struct
-                               | ecc_mode << ECC_MODE
-                               | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_BCH;
--      if (!nandc->props->qpic_v2)
-+      if (!nandc->props->qpic_version2)
-               host->ecc_buf_cfg = 0x203 << NUM_STEPS;
-       host->clrflashstatus = FS_READY_BSY_N;
-@@ -2556,7 +2510,7 @@ static int qcom_op_cmd_mapping(struct na
-               cmd = OP_FETCH_ID;
-               break;
-       case NAND_CMD_PARAM:
--              if (nandc->props->qpic_v2)
-+              if (nandc->props->qpic_version2)
-                       cmd = OP_PAGE_READ_ONFI_READ;
-               else
-                       cmd = OP_PAGE_READ;
-@@ -2609,7 +2563,7 @@ static int qcom_parse_instructions(struc
-                       if (ret < 0)
-                               return ret;
--                      q_op->cmd_reg = ret;
-+                      q_op->cmd_reg = cpu_to_le32(ret);
-                       q_op->rdy_delay_ns = instr->delay_ns;
-                       break;
-@@ -2619,10 +2573,10 @@ static int qcom_parse_instructions(struc
-                       addrs = &instr->ctx.addr.addrs[offset];
-                       for (i = 0; i < min_t(unsigned int, 4, naddrs); i++)
--                              q_op->addr1_reg |= addrs[i] << (i * 8);
-+                              q_op->addr1_reg |= cpu_to_le32(addrs[i] << (i * 8));
-                       if (naddrs > 4)
--                              q_op->addr2_reg |= addrs[4];
-+                              q_op->addr2_reg |= cpu_to_le32(addrs[4]);
-                       q_op->rdy_delay_ns = instr->delay_ns;
-                       break;
-@@ -2663,7 +2617,7 @@ static int qcom_wait_rdy_poll(struct nan
-       unsigned long start = jiffies + msecs_to_jiffies(time_ms);
-       u32 flash;
--      nandc_read_buffer_sync(nandc, true);
-+      nandc_dev_to_mem(nandc, true);
-       do {
-               flash = le32_to_cpu(nandc->reg_read_buf[0]);
-@@ -2706,11 +2660,11 @@ static int qcom_read_status_exec(struct
-       clear_read_regs(nandc);
-       clear_bam_transaction(nandc);
--      nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg);
--      nandc_set_reg(chip, NAND_EXEC_CMD, 1);
-+      nandc->regs->cmd = q_op.cmd_reg;
-+      nandc->regs->exec = cpu_to_le32(1);
--      write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-       read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-       ret = submit_descs(nandc);
-@@ -2719,7 +2673,7 @@ static int qcom_read_status_exec(struct
-               goto err_out;
-       }
--      nandc_read_buffer_sync(nandc, true);
-+      nandc_dev_to_mem(nandc, true);
-       for (i = 0; i < num_cw; i++) {
-               flash_status = le32_to_cpu(nandc->reg_read_buf[i]);
-@@ -2763,16 +2717,14 @@ static int qcom_read_id_type_exec(struct
-       clear_read_regs(nandc);
-       clear_bam_transaction(nandc);
--      nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg);
--      nandc_set_reg(chip, NAND_ADDR0, q_op.addr1_reg);
--      nandc_set_reg(chip, NAND_ADDR1, q_op.addr2_reg);
--      nandc_set_reg(chip, NAND_FLASH_CHIP_SELECT,
--                    nandc->props->is_bam ? 0 : DM_EN);
-+      nandc->regs->cmd = q_op.cmd_reg;
-+      nandc->regs->addr0 = q_op.addr1_reg;
-+      nandc->regs->addr1 = q_op.addr2_reg;
-+      nandc->regs->chip_sel = cpu_to_le32(nandc->props->supports_bam ? 0 : DM_EN);
-+      nandc->regs->exec = cpu_to_le32(1);
--      nandc_set_reg(chip, NAND_EXEC_CMD, 1);
--
--      write_reg_dma(nandc, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-       read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
-@@ -2786,7 +2738,7 @@ static int qcom_read_id_type_exec(struct
-       op_id = q_op.data_instr_idx;
-       len = nand_subop_get_data_len(subop, op_id);
--      nandc_read_buffer_sync(nandc, true);
-+      nandc_dev_to_mem(nandc, true);
-       memcpy(instr->ctx.data.buf.in, nandc->reg_read_buf, len);
- err_out:
-@@ -2807,15 +2759,14 @@ static int qcom_misc_cmd_type_exec(struc
-       if (q_op.flag == OP_PROGRAM_PAGE) {
-               goto wait_rdy;
--      } else if (q_op.cmd_reg == OP_BLOCK_ERASE) {
--              q_op.cmd_reg |= PAGE_ACC | LAST_PAGE;
--              nandc_set_reg(chip, NAND_ADDR0, q_op.addr1_reg);
--              nandc_set_reg(chip, NAND_ADDR1, q_op.addr2_reg);
--              nandc_set_reg(chip, NAND_DEV0_CFG0,
--                            host->cfg0_raw & ~(7 << CW_PER_PAGE));
--              nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw);
-+      } else if (q_op.cmd_reg == cpu_to_le32(OP_BLOCK_ERASE)) {
-+              q_op.cmd_reg |= cpu_to_le32(PAGE_ACC | LAST_PAGE);
-+              nandc->regs->addr0 = q_op.addr1_reg;
-+              nandc->regs->addr1 = q_op.addr2_reg;
-+              nandc->regs->cfg0 = cpu_to_le32(host->cfg0_raw & ~(7 << CW_PER_PAGE));
-+              nandc->regs->cfg1 = cpu_to_le32(host->cfg1_raw);
-               instrs = 3;
--      } else if (q_op.cmd_reg != OP_RESET_DEVICE) {
-+      } else if (q_op.cmd_reg != cpu_to_le32(OP_RESET_DEVICE)) {
-               return 0;
-       }
-@@ -2826,14 +2777,14 @@ static int qcom_misc_cmd_type_exec(struc
-       clear_read_regs(nandc);
-       clear_bam_transaction(nandc);
--      nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg);
--      nandc_set_reg(chip, NAND_EXEC_CMD, 1);
-+      nandc->regs->cmd = q_op.cmd_reg;
-+      nandc->regs->exec = cpu_to_le32(1);
--      write_reg_dma(nandc, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
--      if (q_op.cmd_reg == OP_BLOCK_ERASE)
--              write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
-+      if (q_op.cmd_reg == cpu_to_le32(OP_BLOCK_ERASE))
-+              write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-       read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-       ret = submit_descs(nandc);
-@@ -2862,14 +2813,14 @@ static int qcom_param_page_type_exec(str
-       reg_base = NAND_READ_LOCATION_0;
--      if (nandc->props->qpic_v2)
-+      if (nandc->props->qpic_version2)
-               reg_base = NAND_READ_LOCATION_LAST_CW_0;
-       ret = qcom_parse_instructions(chip, subop, &q_op);
-       if (ret)
-               return ret;
--      q_op.cmd_reg |= PAGE_ACC | LAST_PAGE;
-+      q_op.cmd_reg |= cpu_to_le32(PAGE_ACC | LAST_PAGE);
-       nandc->buf_count = 0;
-       nandc->buf_start = 0;
-@@ -2877,52 +2828,52 @@ static int qcom_param_page_type_exec(str
-       clear_read_regs(nandc);
-       clear_bam_transaction(nandc);
--      nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg);
-+      nandc->regs->cmd = q_op.cmd_reg;
-+      nandc->regs->addr0 = 0;
-+      nandc->regs->addr1 = 0;
-+
-+      nandc->regs->cfg0 = cpu_to_le32(0 << CW_PER_PAGE |
-+                                      512 << UD_SIZE_BYTES |
-+                                      5 << NUM_ADDR_CYCLES |
-+                                      0 << SPARE_SIZE_BYTES);
-+
-+      nandc->regs->cfg1 = cpu_to_le32(7 << NAND_RECOVERY_CYCLES |
-+                                      0 << CS_ACTIVE_BSY |
-+                                      17 << BAD_BLOCK_BYTE_NUM |
-+                                      1 << BAD_BLOCK_IN_SPARE_AREA |
-+                                      2 << WR_RD_BSY_GAP |
-+                                      0 << WIDE_FLASH |
-+                                      1 << DEV0_CFG1_ECC_DISABLE);
--      nandc_set_reg(chip, NAND_ADDR0, 0);
--      nandc_set_reg(chip, NAND_ADDR1, 0);
--      nandc_set_reg(chip, NAND_DEV0_CFG0, 0 << CW_PER_PAGE
--                                      | 512 << UD_SIZE_BYTES
--                                      | 5 << NUM_ADDR_CYCLES
--                                      | 0 << SPARE_SIZE_BYTES);
--      nandc_set_reg(chip, NAND_DEV0_CFG1, 7 << NAND_RECOVERY_CYCLES
--                                      | 0 << CS_ACTIVE_BSY
--                                      | 17 << BAD_BLOCK_BYTE_NUM
--                                      | 1 << BAD_BLOCK_IN_SPARE_AREA
--                                      | 2 << WR_RD_BSY_GAP
--                                      | 0 << WIDE_FLASH
--                                      | 1 << DEV0_CFG1_ECC_DISABLE);
--      if (!nandc->props->qpic_v2)
--              nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, 1 << ECC_CFG_ECC_DISABLE);
-+      if (!nandc->props->qpic_version2)
-+              nandc->regs->ecc_buf_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE);
-       /* configure CMD1 and VLD for ONFI param probing in QPIC v1 */
--      if (!nandc->props->qpic_v2) {
--              nandc_set_reg(chip, NAND_DEV_CMD_VLD,
--                            (nandc->vld & ~READ_START_VLD));
--              nandc_set_reg(chip, NAND_DEV_CMD1,
--                            (nandc->cmd1 & ~(0xFF << READ_ADDR))
--                            | NAND_CMD_PARAM << READ_ADDR);
-+      if (!nandc->props->qpic_version2) {
-+              nandc->regs->vld = cpu_to_le32((nandc->vld & ~READ_START_VLD));
-+              nandc->regs->cmd1 = cpu_to_le32((nandc->cmd1 & ~(0xFF << READ_ADDR))
-+                                  | NAND_CMD_PARAM << READ_ADDR);
-       }
--      nandc_set_reg(chip, NAND_EXEC_CMD, 1);
--
--      if (!nandc->props->qpic_v2) {
--              nandc_set_reg(chip, NAND_DEV_CMD1_RESTORE, nandc->cmd1);
--              nandc_set_reg(chip, NAND_DEV_CMD_VLD_RESTORE, nandc->vld);
-+      nandc->regs->exec = cpu_to_le32(1);
-+
-+      if (!nandc->props->qpic_version2) {
-+              nandc->regs->orig_cmd1 = cpu_to_le32(nandc->cmd1);
-+              nandc->regs->orig_vld = cpu_to_le32(nandc->vld);
-       }
-       instr = q_op.data_instr;
-       op_id = q_op.data_instr_idx;
-       len = nand_subop_get_data_len(subop, op_id);
--      if (nandc->props->qpic_v2)
-+      if (nandc->props->qpic_version2)
-               nandc_set_read_loc_last(chip, reg_base, 0, len, 1);
-       else
-               nandc_set_read_loc_first(chip, reg_base, 0, len, 1);
--      if (!nandc->props->qpic_v2) {
--              write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
--              write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
-+      if (!nandc->props->qpic_version2) {
-+              write_reg_dma(nandc, &nandc->regs->vld, NAND_DEV_CMD_VLD, 1, 0);
-+              write_reg_dma(nandc, &nandc->regs->cmd1, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
-       }
-       nandc->buf_count = 512;
-@@ -2934,9 +2885,10 @@ static int qcom_param_page_type_exec(str
-                     nandc->buf_count, 0);
-       /* restore CMD1 and VLD regs */
--      if (!nandc->props->qpic_v2) {
--              write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1, 0);
--              write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1, NAND_BAM_NEXT_SGL);
-+      if (!nandc->props->qpic_version2) {
-+              write_reg_dma(nandc, &nandc->regs->orig_cmd1, NAND_DEV_CMD1_RESTORE, 1, 0);
-+              write_reg_dma(nandc, &nandc->regs->orig_vld, NAND_DEV_CMD_VLD_RESTORE, 1,
-+                            NAND_BAM_NEXT_SGL);
-       }
-       ret = submit_descs(nandc);
-@@ -3025,7 +2977,7 @@ static const struct nand_controller_ops
- static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
- {
--      if (nandc->props->is_bam) {
-+      if (nandc->props->supports_bam) {
-               if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma))
-                       dma_unmap_single(nandc->dev, nandc->reg_read_dma,
-                                        MAX_REG_RD *
-@@ -3078,7 +3030,7 @@ static int qcom_nandc_alloc(struct qcom_
-       if (!nandc->reg_read_buf)
-               return -ENOMEM;
--      if (nandc->props->is_bam) {
-+      if (nandc->props->supports_bam) {
-               nandc->reg_read_dma =
-                       dma_map_single(nandc->dev, nandc->reg_read_buf,
-                                      MAX_REG_RD *
-@@ -3159,15 +3111,15 @@ static int qcom_nandc_setup(struct qcom_
-       u32 nand_ctrl;
-       /* kill onenand */
--      if (!nandc->props->is_qpic)
-+      if (!nandc->props->nandc_part_of_qpic)
-               nandc_write(nandc, SFLASHC_BURST_CFG, 0);
--      if (!nandc->props->qpic_v2)
-+      if (!nandc->props->qpic_version2)
-               nandc_write(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD),
-                           NAND_DEV_CMD_VLD_VAL);
-       /* enable ADM or BAM DMA */
--      if (nandc->props->is_bam) {
-+      if (nandc->props->supports_bam) {
-               nand_ctrl = nandc_read(nandc, NAND_CTRL);
-               /*
-@@ -3184,7 +3136,7 @@ static int qcom_nandc_setup(struct qcom_
-       }
-       /* save the original values of these registers */
--      if (!nandc->props->qpic_v2) {
-+      if (!nandc->props->qpic_version2) {
-               nandc->cmd1 = nandc_read(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD1));
-               nandc->vld = NAND_DEV_CMD_VLD_VAL;
-       }
-@@ -3357,7 +3309,7 @@ static int qcom_nandc_parse_dt(struct pl
-       struct device_node *np = nandc->dev->of_node;
-       int ret;
--      if (!nandc->props->is_bam) {
-+      if (!nandc->props->supports_bam) {
-               ret = of_property_read_u32(np, "qcom,cmd-crci",
-                                          &nandc->cmd_crci);
-               if (ret) {
-@@ -3482,30 +3434,30 @@ static void qcom_nandc_remove(struct pla
- static const struct qcom_nandc_props ipq806x_nandc_props = {
-       .ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT),
--      .is_bam = false,
-+      .supports_bam = false,
-       .use_codeword_fixup = true,
-       .dev_cmd_reg_start = 0x0,
- };
- static const struct qcom_nandc_props ipq4019_nandc_props = {
-       .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
--      .is_bam = true,
--      .is_qpic = true,
-+      .supports_bam = true,
-+      .nandc_part_of_qpic = true,
-       .dev_cmd_reg_start = 0x0,
- };
- static const struct qcom_nandc_props ipq8074_nandc_props = {
-       .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
--      .is_bam = true,
--      .is_qpic = true,
-+      .supports_bam = true,
-+      .nandc_part_of_qpic = true,
-       .dev_cmd_reg_start = 0x7000,
- };
- static const struct qcom_nandc_props sdx55_nandc_props = {
-       .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
--      .is_bam = true,
--      .is_qpic = true,
--      .qpic_v2 = true,
-+      .supports_bam = true,
-+      .nandc_part_of_qpic = true,
-+      .qpic_version2 = true,
-       .dev_cmd_reg_start = 0x7000,
- };
diff --git a/target/linux/generic/backport-6.18/410-02-v6.14-mtd-rawnand-qcom-Add-qcom-prefix-to-common-api.patch b/target/linux/generic/backport-6.18/410-02-v6.14-mtd-rawnand-qcom-Add-qcom-prefix-to-common-api.patch
deleted file mode 100644 (file)
index 23ef86f..0000000
+++ /dev/null
@@ -1,880 +0,0 @@
-From 1d479f5b345e0c3650fec4dddeef9fc6fab30c8b Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Wed, 20 Nov 2024 14:45:01 +0530
-Subject: [PATCH 2/4] mtd: rawnand: qcom: Add qcom prefix to common api
-
-Add qcom prefix to all the api which will be commonly
-used by spi nand driver and raw nand driver.
-
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/raw/qcom_nandc.c | 320 +++++++++++++++---------------
- 1 file changed, 160 insertions(+), 160 deletions(-)
-
---- a/drivers/mtd/nand/raw/qcom_nandc.c
-+++ b/drivers/mtd/nand/raw/qcom_nandc.c
-@@ -53,7 +53,7 @@
- #define       NAND_READ_LOCATION_LAST_CW_2    0xf48
- #define       NAND_READ_LOCATION_LAST_CW_3    0xf4c
--/* dummy register offsets, used by write_reg_dma */
-+/* dummy register offsets, used by qcom_write_reg_dma */
- #define       NAND_DEV_CMD1_RESTORE           0xdead
- #define       NAND_DEV_CMD_VLD_RESTORE        0xbeef
-@@ -211,7 +211,7 @@
- /*
-  * Flags used in DMA descriptor preparation helper functions
-- * (i.e. read_reg_dma/write_reg_dma/read_data_dma/write_data_dma)
-+ * (i.e. qcom_read_reg_dma/qcom_write_reg_dma/qcom_read_data_dma/qcom_write_data_dma)
-  */
- /* Don't set the EOT in current tx BAM sgl */
- #define NAND_BAM_NO_EOT                       BIT(0)
-@@ -550,7 +550,7 @@ struct qcom_nandc_props {
- };
- /* Frees the BAM transaction memory */
--static void free_bam_transaction(struct qcom_nand_controller *nandc)
-+static void qcom_free_bam_transaction(struct qcom_nand_controller *nandc)
- {
-       struct bam_transaction *bam_txn = nandc->bam_txn;
-@@ -559,7 +559,7 @@ static void free_bam_transaction(struct
- /* Allocates and Initializes the BAM transaction */
- static struct bam_transaction *
--alloc_bam_transaction(struct qcom_nand_controller *nandc)
-+qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc)
- {
-       struct bam_transaction *bam_txn;
-       size_t bam_txn_size;
-@@ -595,7 +595,7 @@ alloc_bam_transaction(struct qcom_nand_c
- }
- /* Clears the BAM transaction indexes */
--static void clear_bam_transaction(struct qcom_nand_controller *nandc)
-+static void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc)
- {
-       struct bam_transaction *bam_txn = nandc->bam_txn;
-@@ -614,7 +614,7 @@ static void clear_bam_transaction(struct
- }
- /* Callback for DMA descriptor completion */
--static void qpic_bam_dma_done(void *data)
-+static void qcom_qpic_bam_dma_done(void *data)
- {
-       struct bam_transaction *bam_txn = data;
-@@ -644,7 +644,7 @@ static void nandc_write(struct qcom_nand
-       iowrite32(val, nandc->base + offset);
- }
--static void nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu)
-+static void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu)
- {
-       if (!nandc->props->supports_bam)
-               return;
-@@ -824,9 +824,9 @@ static void update_rw_regs(struct qcom_n
-  * for BAM. This descriptor will be added in the NAND DMA descriptor queue
-  * which will be submitted to DMA engine.
-  */
--static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
--                                struct dma_chan *chan,
--                                unsigned long flags)
-+static int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc,
-+                                     struct dma_chan *chan,
-+                                     unsigned long flags)
- {
-       struct desc_info *desc;
-       struct scatterlist *sgl;
-@@ -903,9 +903,9 @@ static int prepare_bam_async_desc(struct
-  * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
-  * after the current command element.
-  */
--static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
--                               int reg_off, const void *vaddr,
--                               int size, unsigned int flags)
-+static int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
-+                                    int reg_off, const void *vaddr,
-+                                    int size, unsigned int flags)
- {
-       int bam_ce_size;
-       int i, ret;
-@@ -943,9 +943,9 @@ static int prep_bam_dma_desc_cmd(struct
-               bam_txn->bam_ce_start = bam_txn->bam_ce_pos;
-               if (flags & NAND_BAM_NWD) {
--                      ret = prepare_bam_async_desc(nandc, nandc->cmd_chan,
--                                                   DMA_PREP_FENCE |
--                                                   DMA_PREP_CMD);
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan,
-+                                                        DMA_PREP_FENCE |
-+                                                        DMA_PREP_CMD);
-                       if (ret)
-                               return ret;
-               }
-@@ -958,9 +958,8 @@ static int prep_bam_dma_desc_cmd(struct
-  * Prepares the data descriptor for BAM DMA which will be used for NAND
-  * data reads and writes.
-  */
--static int prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
--                                const void *vaddr,
--                                int size, unsigned int flags)
-+static int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
-+                                     const void *vaddr, int size, unsigned int flags)
- {
-       int ret;
-       struct bam_transaction *bam_txn = nandc->bam_txn;
-@@ -979,8 +978,8 @@ static int prep_bam_dma_desc_data(struct
-                * is not set, form the DMA descriptor
-                */
-               if (!(flags & NAND_BAM_NO_EOT)) {
--                      ret = prepare_bam_async_desc(nandc, nandc->tx_chan,
--                                                   DMA_PREP_INTERRUPT);
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan,
-+                                                        DMA_PREP_INTERRUPT);
-                       if (ret)
-                               return ret;
-               }
-@@ -989,9 +988,9 @@ static int prep_bam_dma_desc_data(struct
-       return 0;
- }
--static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
--                           int reg_off, const void *vaddr, int size,
--                           bool flow_control)
-+static int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
-+                                int reg_off, const void *vaddr, int size,
-+                                bool flow_control)
- {
-       struct desc_info *desc;
-       struct dma_async_tx_descriptor *dma_desc;
-@@ -1069,15 +1068,15 @@ err:
- }
- /*
-- * read_reg_dma:      prepares a descriptor to read a given number of
-+ * qcom_read_reg_dma: prepares a descriptor to read a given number of
-  *                    contiguous registers to the reg_read_buf pointer
-  *
-  * @first:            offset of the first register in the contiguous block
-  * @num_regs:         number of registers to read
-  * @flags:            flags to control DMA descriptor preparation
-  */
--static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
--                      int num_regs, unsigned int flags)
-+static int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first,
-+                           int num_regs, unsigned int flags)
- {
-       bool flow_control = false;
-       void *vaddr;
-@@ -1089,18 +1088,18 @@ static int read_reg_dma(struct qcom_nand
-               first = dev_cmd_reg_addr(nandc, first);
-       if (nandc->props->supports_bam)
--              return prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
-+              return qcom_prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
-                                            num_regs, flags);
-       if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
-               flow_control = true;
--      return prep_adm_dma_desc(nandc, true, first, vaddr,
-+      return qcom_prep_adm_dma_desc(nandc, true, first, vaddr,
-                                num_regs * sizeof(u32), flow_control);
- }
- /*
-- * write_reg_dma:     prepares a descriptor to write a given number of
-+ * qcom_write_reg_dma:        prepares a descriptor to write a given number of
-  *                    contiguous registers
-  *
-  * @vaddr:            contiguous memory from where register value will
-@@ -1109,8 +1108,8 @@ static int read_reg_dma(struct qcom_nand
-  * @num_regs:         number of registers to write
-  * @flags:            flags to control DMA descriptor preparation
-  */
--static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
--                       int first, int num_regs, unsigned int flags)
-+static int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
-+                            int first, int num_regs, unsigned int flags)
- {
-       bool flow_control = false;
-@@ -1124,18 +1123,18 @@ static int write_reg_dma(struct qcom_nan
-               first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD);
-       if (nandc->props->supports_bam)
--              return prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
-+              return qcom_prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
-                                            num_regs, flags);
-       if (first == NAND_FLASH_CMD)
-               flow_control = true;
--      return prep_adm_dma_desc(nandc, false, first, vaddr,
-+      return qcom_prep_adm_dma_desc(nandc, false, first, vaddr,
-                                num_regs * sizeof(u32), flow_control);
- }
- /*
-- * read_data_dma:     prepares a DMA descriptor to transfer data from the
-+ * qcom_read_data_dma:        prepares a DMA descriptor to transfer data from the
-  *                    controller's internal buffer to the buffer 'vaddr'
-  *
-  * @reg_off:          offset within the controller's data buffer
-@@ -1143,17 +1142,17 @@ static int write_reg_dma(struct qcom_nan
-  * @size:             DMA transaction size in bytes
-  * @flags:            flags to control DMA descriptor preparation
-  */
--static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
--                       const u8 *vaddr, int size, unsigned int flags)
-+static int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-+                            const u8 *vaddr, int size, unsigned int flags)
- {
-       if (nandc->props->supports_bam)
--              return prep_bam_dma_desc_data(nandc, true, vaddr, size, flags);
-+              return qcom_prep_bam_dma_desc_data(nandc, true, vaddr, size, flags);
--      return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
-+      return qcom_prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
- }
- /*
-- * write_data_dma:    prepares a DMA descriptor to transfer data from
-+ * qcom_write_data_dma:       prepares a DMA descriptor to transfer data from
-  *                    'vaddr' to the controller's internal buffer
-  *
-  * @reg_off:          offset within the controller's data buffer
-@@ -1161,13 +1160,13 @@ static int read_data_dma(struct qcom_nan
-  * @size:             DMA transaction size in bytes
-  * @flags:            flags to control DMA descriptor preparation
-  */
--static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
--                        const u8 *vaddr, int size, unsigned int flags)
-+static int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-+                             const u8 *vaddr, int size, unsigned int flags)
- {
-       if (nandc->props->supports_bam)
--              return prep_bam_dma_desc_data(nandc, false, vaddr, size, flags);
-+              return qcom_prep_bam_dma_desc_data(nandc, false, vaddr, size, flags);
--      return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
-+      return qcom_prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
- }
- /*
-@@ -1178,14 +1177,14 @@ static void config_nand_page_read(struct
- {
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
--      write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
--      write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      qcom_write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-       if (!nandc->props->qpic_version2)
--              write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0);
--      write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_clr,
--                    NAND_ERASED_CW_DETECT_CFG, 1, 0);
--      write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_set,
--                    NAND_ERASED_CW_DETECT_CFG, 1, NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
-+              qcom_write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0);
-+      qcom_write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_clr,
-+                         NAND_ERASED_CW_DETECT_CFG, 1, 0);
-+      qcom_write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_set,
-+                         NAND_ERASED_CW_DETECT_CFG, 1, NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
- }
- /*
-@@ -1204,17 +1203,17 @@ config_nand_cw_read(struct nand_chip *ch
-               reg = &nandc->regs->read_location_last0;
-       if (nandc->props->supports_bam)
--              write_reg_dma(nandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL);
-+              qcom_write_reg_dma(nandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-       if (use_ecc) {
--              read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
--              read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
--                           NAND_BAM_NEXT_SGL);
-+              qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
-+              qcom_read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
-+                                NAND_BAM_NEXT_SGL);
-       } else {
--              read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-+              qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-       }
- }
-@@ -1238,11 +1237,11 @@ static void config_nand_page_write(struc
- {
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
--      write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
--      write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      qcom_write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-       if (!nandc->props->qpic_version2)
--              write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1,
--                            NAND_BAM_NEXT_SGL);
-+              qcom_write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1,
-+                                 NAND_BAM_NEXT_SGL);
- }
- /*
-@@ -1253,17 +1252,18 @@ static void config_nand_cw_write(struct
- {
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
--      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
--      read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-+      qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, &nandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0);
--      write_reg_dma(nandc, &nandc->regs->clrreadstatus, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0);
-+      qcom_write_reg_dma(nandc, &nandc->regs->clrreadstatus, NAND_READ_STATUS, 1,
-+                         NAND_BAM_NEXT_SGL);
- }
- /* helpers to submit/free our list of dma descriptors */
--static int submit_descs(struct qcom_nand_controller *nandc)
-+static int qcom_submit_descs(struct qcom_nand_controller *nandc)
- {
-       struct desc_info *desc, *n;
-       dma_cookie_t cookie = 0;
-@@ -1272,21 +1272,21 @@ static int submit_descs(struct qcom_nand
-       if (nandc->props->supports_bam) {
-               if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) {
--                      ret = prepare_bam_async_desc(nandc, nandc->rx_chan, 0);
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->rx_chan, 0);
-                       if (ret)
-                               goto err_unmap_free_desc;
-               }
-               if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) {
--                      ret = prepare_bam_async_desc(nandc, nandc->tx_chan,
--                                                 DMA_PREP_INTERRUPT);
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan,
-+                                                        DMA_PREP_INTERRUPT);
-                       if (ret)
-                               goto err_unmap_free_desc;
-               }
-               if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) {
--                      ret = prepare_bam_async_desc(nandc, nandc->cmd_chan,
--                                                 DMA_PREP_CMD);
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan,
-+                                                        DMA_PREP_CMD);
-                       if (ret)
-                               goto err_unmap_free_desc;
-               }
-@@ -1296,7 +1296,7 @@ static int submit_descs(struct qcom_nand
-               cookie = dmaengine_submit(desc->dma_desc);
-       if (nandc->props->supports_bam) {
--              bam_txn->last_cmd_desc->callback = qpic_bam_dma_done;
-+              bam_txn->last_cmd_desc->callback = qcom_qpic_bam_dma_done;
-               bam_txn->last_cmd_desc->callback_param = bam_txn;
-               dma_async_issue_pending(nandc->tx_chan);
-@@ -1314,7 +1314,7 @@ static int submit_descs(struct qcom_nand
- err_unmap_free_desc:
-       /*
-        * Unmap the dma sg_list and free the desc allocated by both
--       * prepare_bam_async_desc() and prep_adm_dma_desc() functions.
-+       * qcom_prepare_bam_async_desc() and qcom_prep_adm_dma_desc() functions.
-        */
-       list_for_each_entry_safe(desc, n, &nandc->desc_list, node) {
-               list_del(&desc->node);
-@@ -1333,10 +1333,10 @@ err_unmap_free_desc:
- }
- /* reset the register read buffer for next NAND operation */
--static void clear_read_regs(struct qcom_nand_controller *nandc)
-+static void qcom_clear_read_regs(struct qcom_nand_controller *nandc)
- {
-       nandc->reg_read_pos = 0;
--      nandc_dev_to_mem(nandc, false);
-+      qcom_nandc_dev_to_mem(nandc, false);
- }
- /*
-@@ -1400,7 +1400,7 @@ static int check_flash_errors(struct qco
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-       int i;
--      nandc_dev_to_mem(nandc, true);
-+      qcom_nandc_dev_to_mem(nandc, true);
-       for (i = 0; i < cw_cnt; i++) {
-               u32 flash = le32_to_cpu(nandc->reg_read_buf[i]);
-@@ -1427,13 +1427,13 @@ qcom_nandc_read_cw_raw(struct mtd_info *
-       nand_read_page_op(chip, page, 0, NULL, 0);
-       nandc->buf_count = 0;
-       nandc->buf_start = 0;
--      clear_read_regs(nandc);
-+      qcom_clear_read_regs(nandc);
-       host->use_ecc = false;
-       if (nandc->props->qpic_version2)
-               raw_cw = ecc->steps - 1;
--      clear_bam_transaction(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       set_address(host, host->cw_size * cw, page);
-       update_rw_regs(host, 1, true, raw_cw);
-       config_nand_page_read(chip);
-@@ -1466,18 +1466,18 @@ qcom_nandc_read_cw_raw(struct mtd_info *
-       config_nand_cw_read(chip, false, raw_cw);
--      read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
-+      qcom_read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
-       reg_off += data_size1;
--      read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
-+      qcom_read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
-       reg_off += oob_size1;
--      read_data_dma(nandc, reg_off, data_buf + data_size1, data_size2, 0);
-+      qcom_read_data_dma(nandc, reg_off, data_buf + data_size1, data_size2, 0);
-       reg_off += data_size2;
--      read_data_dma(nandc, reg_off, oob_buf + oob_size1, oob_size2, 0);
-+      qcom_read_data_dma(nandc, reg_off, oob_buf + oob_size1, oob_size2, 0);
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure to read raw cw %d\n", cw);
-               return ret;
-@@ -1575,7 +1575,7 @@ static int parse_read_errors(struct qcom
-       u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf;
-       buf = (struct read_stats *)nandc->reg_read_buf;
--      nandc_dev_to_mem(nandc, true);
-+      qcom_nandc_dev_to_mem(nandc, true);
-       for (i = 0; i < ecc->steps; i++, buf++) {
-               u32 flash, buffer, erased_cw;
-@@ -1704,8 +1704,8 @@ static int read_page_ecc(struct qcom_nan
-               config_nand_cw_read(chip, true, i);
-               if (data_buf)
--                      read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
--                                    data_size, 0);
-+                      qcom_read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
-+                                         data_size, 0);
-               /*
-                * when ecc is enabled, the controller doesn't read the real
-@@ -1720,8 +1720,8 @@ static int read_page_ecc(struct qcom_nan
-                       for (j = 0; j < host->bbm_size; j++)
-                               *oob_buf++ = 0xff;
--                      read_data_dma(nandc, FLASH_BUF_ACC + data_size,
--                                    oob_buf, oob_size, 0);
-+                      qcom_read_data_dma(nandc, FLASH_BUF_ACC + data_size,
-+                                         oob_buf, oob_size, 0);
-               }
-               if (data_buf)
-@@ -1730,7 +1730,7 @@ static int read_page_ecc(struct qcom_nan
-                       oob_buf += oob_size;
-       }
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure to read page/oob\n");
-               return ret;
-@@ -1751,7 +1751,7 @@ static int copy_last_cw(struct qcom_nand
-       int size;
-       int ret;
--      clear_read_regs(nandc);
-+      qcom_clear_read_regs(nandc);
-       size = host->use_ecc ? host->cw_data : host->cw_size;
-@@ -1763,9 +1763,9 @@ static int copy_last_cw(struct qcom_nand
-       config_nand_single_cw_page_read(chip, host->use_ecc, ecc->steps - 1);
--      read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0);
-+      qcom_read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0);
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret)
-               dev_err(nandc->dev, "failed to copy last codeword\n");
-@@ -1851,14 +1851,14 @@ static int qcom_nandc_read_page(struct n
-       nandc->buf_count = 0;
-       nandc->buf_start = 0;
-       host->use_ecc = true;
--      clear_read_regs(nandc);
-+      qcom_clear_read_regs(nandc);
-       set_address(host, 0, page);
-       update_rw_regs(host, ecc->steps, true, 0);
-       data_buf = buf;
-       oob_buf = oob_required ? chip->oob_poi : NULL;
--      clear_bam_transaction(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       return read_page_ecc(host, data_buf, oob_buf, page);
- }
-@@ -1899,8 +1899,8 @@ static int qcom_nandc_read_oob(struct na
-       if (host->nr_boot_partitions)
-               qcom_nandc_codeword_fixup(host, page);
--      clear_read_regs(nandc);
--      clear_bam_transaction(nandc);
-+      qcom_clear_read_regs(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       host->use_ecc = true;
-       set_address(host, 0, page);
-@@ -1927,8 +1927,8 @@ static int qcom_nandc_write_page(struct
-       set_address(host, 0, page);
-       nandc->buf_count = 0;
-       nandc->buf_start = 0;
--      clear_read_regs(nandc);
--      clear_bam_transaction(nandc);
-+      qcom_clear_read_regs(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       data_buf = (u8 *)buf;
-       oob_buf = chip->oob_poi;
-@@ -1949,8 +1949,8 @@ static int qcom_nandc_write_page(struct
-                       oob_size = ecc->bytes;
-               }
--              write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size,
--                             i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0);
-+              qcom_write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size,
-+                                  i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0);
-               /*
-                * when ECC is enabled, we don't really need to write anything
-@@ -1962,8 +1962,8 @@ static int qcom_nandc_write_page(struct
-               if (qcom_nandc_is_last_cw(ecc, i)) {
-                       oob_buf += host->bbm_size;
--                      write_data_dma(nandc, FLASH_BUF_ACC + data_size,
--                                     oob_buf, oob_size, 0);
-+                      qcom_write_data_dma(nandc, FLASH_BUF_ACC + data_size,
-+                                          oob_buf, oob_size, 0);
-               }
-               config_nand_cw_write(chip);
-@@ -1972,7 +1972,7 @@ static int qcom_nandc_write_page(struct
-               oob_buf += oob_size;
-       }
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure to write page\n");
-               return ret;
-@@ -1997,8 +1997,8 @@ static int qcom_nandc_write_page_raw(str
-               qcom_nandc_codeword_fixup(host, page);
-       nand_prog_page_begin_op(chip, page, 0, NULL, 0);
--      clear_read_regs(nandc);
--      clear_bam_transaction(nandc);
-+      qcom_clear_read_regs(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       data_buf = (u8 *)buf;
-       oob_buf = chip->oob_poi;
-@@ -2024,28 +2024,28 @@ static int qcom_nandc_write_page_raw(str
-                       oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
-               }
--              write_data_dma(nandc, reg_off, data_buf, data_size1,
--                             NAND_BAM_NO_EOT);
-+              qcom_write_data_dma(nandc, reg_off, data_buf, data_size1,
-+                                  NAND_BAM_NO_EOT);
-               reg_off += data_size1;
-               data_buf += data_size1;
--              write_data_dma(nandc, reg_off, oob_buf, oob_size1,
--                             NAND_BAM_NO_EOT);
-+              qcom_write_data_dma(nandc, reg_off, oob_buf, oob_size1,
-+                                  NAND_BAM_NO_EOT);
-               reg_off += oob_size1;
-               oob_buf += oob_size1;
--              write_data_dma(nandc, reg_off, data_buf, data_size2,
--                             NAND_BAM_NO_EOT);
-+              qcom_write_data_dma(nandc, reg_off, data_buf, data_size2,
-+                                  NAND_BAM_NO_EOT);
-               reg_off += data_size2;
-               data_buf += data_size2;
--              write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
-+              qcom_write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
-               oob_buf += oob_size2;
-               config_nand_cw_write(chip);
-       }
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure to write raw page\n");
-               return ret;
-@@ -2075,7 +2075,7 @@ static int qcom_nandc_write_oob(struct n
-               qcom_nandc_codeword_fixup(host, page);
-       host->use_ecc = true;
--      clear_bam_transaction(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       /* calculate the data and oob size for the last codeword/step */
-       data_size = ecc->size - ((ecc->steps - 1) << 2);
-@@ -2090,11 +2090,11 @@ static int qcom_nandc_write_oob(struct n
-       update_rw_regs(host, 1, false, 0);
-       config_nand_page_write(chip);
--      write_data_dma(nandc, FLASH_BUF_ACC,
--                     nandc->data_buffer, data_size + oob_size, 0);
-+      qcom_write_data_dma(nandc, FLASH_BUF_ACC,
-+                          nandc->data_buffer, data_size + oob_size, 0);
-       config_nand_cw_write(chip);
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure to write oob\n");
-               return ret;
-@@ -2121,7 +2121,7 @@ static int qcom_nandc_block_bad(struct n
-        */
-       host->use_ecc = false;
--      clear_bam_transaction(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       ret = copy_last_cw(host, page);
-       if (ret)
-               goto err;
-@@ -2148,8 +2148,8 @@ static int qcom_nandc_block_markbad(stru
-       struct nand_ecc_ctrl *ecc = &chip->ecc;
-       int page, ret;
--      clear_read_regs(nandc);
--      clear_bam_transaction(nandc);
-+      qcom_clear_read_regs(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       /*
-        * to mark the BBM as bad, we flash the entire last codeword with 0s.
-@@ -2166,11 +2166,11 @@ static int qcom_nandc_block_markbad(stru
-       update_rw_regs(host, 1, false, ecc->steps - 1);
-       config_nand_page_write(chip);
--      write_data_dma(nandc, FLASH_BUF_ACC,
--                     nandc->data_buffer, host->cw_size, 0);
-+      qcom_write_data_dma(nandc, FLASH_BUF_ACC,
-+                          nandc->data_buffer, host->cw_size, 0);
-       config_nand_cw_write(chip);
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure to update BBM\n");
-               return ret;
-@@ -2410,14 +2410,14 @@ static int qcom_nand_attach_chip(struct
-       mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
-       /* Free the initially allocated BAM transaction for reading the ONFI params */
-       if (nandc->props->supports_bam)
--              free_bam_transaction(nandc);
-+              qcom_free_bam_transaction(nandc);
-       nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage,
-                                    cwperpage);
-       /* Now allocate the BAM transaction based on updated max_cwperpage */
-       if (nandc->props->supports_bam) {
--              nandc->bam_txn = alloc_bam_transaction(nandc);
-+              nandc->bam_txn = qcom_alloc_bam_transaction(nandc);
-               if (!nandc->bam_txn) {
-                       dev_err(nandc->dev,
-                               "failed to allocate bam transaction\n");
-@@ -2617,7 +2617,7 @@ static int qcom_wait_rdy_poll(struct nan
-       unsigned long start = jiffies + msecs_to_jiffies(time_ms);
-       u32 flash;
--      nandc_dev_to_mem(nandc, true);
-+      qcom_nandc_dev_to_mem(nandc, true);
-       do {
-               flash = le32_to_cpu(nandc->reg_read_buf[0]);
-@@ -2657,23 +2657,23 @@ static int qcom_read_status_exec(struct
-       nandc->buf_start = 0;
-       host->use_ecc = false;
--      clear_read_regs(nandc);
--      clear_bam_transaction(nandc);
-+      qcom_clear_read_regs(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       nandc->regs->cmd = q_op.cmd_reg;
-       nandc->regs->exec = cpu_to_le32(1);
--      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
--      read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure in submitting status descriptor\n");
-               goto err_out;
-       }
--      nandc_dev_to_mem(nandc, true);
-+      qcom_nandc_dev_to_mem(nandc, true);
-       for (i = 0; i < num_cw; i++) {
-               flash_status = le32_to_cpu(nandc->reg_read_buf[i]);
-@@ -2714,8 +2714,8 @@ static int qcom_read_id_type_exec(struct
-       nandc->buf_start = 0;
-       host->use_ecc = false;
--      clear_read_regs(nandc);
--      clear_bam_transaction(nandc);
-+      qcom_clear_read_regs(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       nandc->regs->cmd = q_op.cmd_reg;
-       nandc->regs->addr0 = q_op.addr1_reg;
-@@ -2723,12 +2723,12 @@ static int qcom_read_id_type_exec(struct
-       nandc->regs->chip_sel = cpu_to_le32(nandc->props->supports_bam ? 0 : DM_EN);
-       nandc->regs->exec = cpu_to_le32(1);
--      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
--      read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
-+      qcom_read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure in submitting read id descriptor\n");
-               goto err_out;
-@@ -2738,7 +2738,7 @@ static int qcom_read_id_type_exec(struct
-       op_id = q_op.data_instr_idx;
-       len = nand_subop_get_data_len(subop, op_id);
--      nandc_dev_to_mem(nandc, true);
-+      qcom_nandc_dev_to_mem(nandc, true);
-       memcpy(instr->ctx.data.buf.in, nandc->reg_read_buf, len);
- err_out:
-@@ -2774,20 +2774,20 @@ static int qcom_misc_cmd_type_exec(struc
-       nandc->buf_start = 0;
-       host->use_ecc = false;
--      clear_read_regs(nandc);
--      clear_bam_transaction(nandc);
-+      qcom_clear_read_regs(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       nandc->regs->cmd = q_op.cmd_reg;
-       nandc->regs->exec = cpu_to_le32(1);
--      write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
-       if (q_op.cmd_reg == cpu_to_le32(OP_BLOCK_ERASE))
--              write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
-+              qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
--      write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
--      read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure in submitting misc descriptor\n");
-               goto err_out;
-@@ -2825,8 +2825,8 @@ static int qcom_param_page_type_exec(str
-       nandc->buf_count = 0;
-       nandc->buf_start = 0;
-       host->use_ecc = false;
--      clear_read_regs(nandc);
--      clear_bam_transaction(nandc);
-+      qcom_clear_read_regs(nandc);
-+      qcom_clear_bam_transaction(nandc);
-       nandc->regs->cmd = q_op.cmd_reg;
-       nandc->regs->addr0 = 0;
-@@ -2872,8 +2872,8 @@ static int qcom_param_page_type_exec(str
-               nandc_set_read_loc_first(chip, reg_base, 0, len, 1);
-       if (!nandc->props->qpic_version2) {
--              write_reg_dma(nandc, &nandc->regs->vld, NAND_DEV_CMD_VLD, 1, 0);
--              write_reg_dma(nandc, &nandc->regs->cmd1, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
-+              qcom_write_reg_dma(nandc, &nandc->regs->vld, NAND_DEV_CMD_VLD, 1, 0);
-+              qcom_write_reg_dma(nandc, &nandc->regs->cmd1, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
-       }
-       nandc->buf_count = 512;
-@@ -2881,17 +2881,17 @@ static int qcom_param_page_type_exec(str
-       config_nand_single_cw_page_read(chip, false, 0);
--      read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
--                    nandc->buf_count, 0);
-+      qcom_read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
-+                         nandc->buf_count, 0);
-       /* restore CMD1 and VLD regs */
-       if (!nandc->props->qpic_version2) {
--              write_reg_dma(nandc, &nandc->regs->orig_cmd1, NAND_DEV_CMD1_RESTORE, 1, 0);
--              write_reg_dma(nandc, &nandc->regs->orig_vld, NAND_DEV_CMD_VLD_RESTORE, 1,
--                            NAND_BAM_NEXT_SGL);
-+              qcom_write_reg_dma(nandc, &nandc->regs->orig_cmd1, NAND_DEV_CMD1_RESTORE, 1, 0);
-+              qcom_write_reg_dma(nandc, &nandc->regs->orig_vld, NAND_DEV_CMD_VLD_RESTORE, 1,
-+                                 NAND_BAM_NEXT_SGL);
-       }
--      ret = submit_descs(nandc);
-+      ret = qcom_submit_descs(nandc);
-       if (ret) {
-               dev_err(nandc->dev, "failure in submitting param page descriptor\n");
-               goto err_out;
-@@ -3075,7 +3075,7 @@ static int qcom_nandc_alloc(struct qcom_
-                * maximum codeword size
-                */
-               nandc->max_cwperpage = 1;
--              nandc->bam_txn = alloc_bam_transaction(nandc);
-+              nandc->bam_txn = qcom_alloc_bam_transaction(nandc);
-               if (!nandc->bam_txn) {
-                       dev_err(nandc->dev,
-                               "failed to allocate bam transaction\n");
diff --git a/target/linux/generic/backport-6.18/410-03-v6.14-mtd-nand-Add-qpic_common-API-file.patch b/target/linux/generic/backport-6.18/410-03-v6.14-mtd-nand-Add-qpic_common-API-file.patch
deleted file mode 100644 (file)
index 9272f98..0000000
+++ /dev/null
@@ -1,2436 +0,0 @@
-From fdf3ee5c6e5278dab4f60b998b47ed2d510bf80f Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Wed, 20 Nov 2024 14:45:02 +0530
-Subject: [PATCH 3/4] mtd: nand: Add qpic_common API file
-
-Add qpic_common.c file which hold all the common
-qpic APIs which will be used by both qpic raw nand
-driver and qpic spi nand driver.
-
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/Makefile            |    2 +-
- drivers/mtd/nand/qpic_common.c       |  759 ++++++++++++++++++
- drivers/mtd/nand/raw/qcom_nandc.c    | 1092 +-------------------------
- include/linux/mtd/nand-qpic-common.h |  468 +++++++++++
- 4 files changed, 1240 insertions(+), 1081 deletions(-)
- create mode 100644 drivers/mtd/nand/qpic_common.c
- create mode 100644 include/linux/mtd/nand-qpic-common.h
-
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -3,7 +3,7 @@
- nandcore-objs := core.o bbt.o
- obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
- obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
--
-+obj-$(CONFIG_MTD_NAND_QCOM) += qpic_common.o
- obj-y += onenand/
- obj-y += raw/
- obj-y += spi/
---- /dev/null
-+++ b/drivers/mtd/nand/qpic_common.c
-@@ -0,0 +1,759 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved
-+ */
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/dmaengine.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dma/qcom_adm.h>
-+#include <linux/dma/qcom_bam_dma.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/mtd/nand-qpic-common.h>
-+
-+/**
-+ * qcom_free_bam_transaction() - Frees the BAM transaction memory
-+ * @nandc: qpic nand controller
-+ *
-+ * This function frees the bam transaction memory
-+ */
-+void qcom_free_bam_transaction(struct qcom_nand_controller *nandc)
-+{
-+      struct bam_transaction *bam_txn = nandc->bam_txn;
-+
-+      kfree(bam_txn);
-+}
-+EXPORT_SYMBOL(qcom_free_bam_transaction);
-+
-+/**
-+ * qcom_alloc_bam_transaction() - allocate BAM transaction
-+ * @nandc: qpic nand controller
-+ *
-+ * This function will allocate and initialize the BAM transaction structure
-+ */
-+struct bam_transaction *
-+qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc)
-+{
-+      struct bam_transaction *bam_txn;
-+      size_t bam_txn_size;
-+      unsigned int num_cw = nandc->max_cwperpage;
-+      void *bam_txn_buf;
-+
-+      bam_txn_size =
-+              sizeof(*bam_txn) + num_cw *
-+              ((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) +
-+              (sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
-+              (sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL));
-+
-+      bam_txn_buf = kzalloc(bam_txn_size, GFP_KERNEL);
-+      if (!bam_txn_buf)
-+              return NULL;
-+
-+      bam_txn = bam_txn_buf;
-+      bam_txn_buf += sizeof(*bam_txn);
-+
-+      bam_txn->bam_ce = bam_txn_buf;
-+      bam_txn_buf +=
-+              sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw;
-+
-+      bam_txn->cmd_sgl = bam_txn_buf;
-+      bam_txn_buf +=
-+              sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw;
-+
-+      bam_txn->data_sgl = bam_txn_buf;
-+
-+      init_completion(&bam_txn->txn_done);
-+
-+      return bam_txn;
-+}
-+EXPORT_SYMBOL(qcom_alloc_bam_transaction);
-+
-+/**
-+ * qcom_clear_bam_transaction() - Clears the BAM transaction
-+ * @nandc: qpic nand controller
-+ *
-+ * This function will clear the BAM transaction indexes.
-+ */
-+void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc)
-+{
-+      struct bam_transaction *bam_txn = nandc->bam_txn;
-+
-+      if (!nandc->props->supports_bam)
-+              return;
-+
-+      memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8);
-+      bam_txn->last_data_desc = NULL;
-+
-+      sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
-+                    QPIC_PER_CW_CMD_SGL);
-+      sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage *
-+                    QPIC_PER_CW_DATA_SGL);
-+
-+      reinit_completion(&bam_txn->txn_done);
-+}
-+EXPORT_SYMBOL(qcom_clear_bam_transaction);
-+
-+/**
-+ * qcom_qpic_bam_dma_done() - Callback for DMA descriptor completion
-+ * @data: data pointer
-+ *
-+ * This function is a callback for DMA descriptor completion
-+ */
-+void qcom_qpic_bam_dma_done(void *data)
-+{
-+      struct bam_transaction *bam_txn = data;
-+
-+      complete(&bam_txn->txn_done);
-+}
-+EXPORT_SYMBOL(qcom_qpic_bam_dma_done);
-+
-+/**
-+ * qcom_nandc_dev_to_mem() - Check for dma sync for cpu or device
-+ * @nandc: qpic nand controller
-+ * @is_cpu: cpu or Device
-+ *
-+ * This function will check for dma sync for cpu or device
-+ */
-+inline void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu)
-+{
-+      if (!nandc->props->supports_bam)
-+              return;
-+
-+      if (is_cpu)
-+              dma_sync_single_for_cpu(nandc->dev, nandc->reg_read_dma,
-+                                      MAX_REG_RD *
-+                                      sizeof(*nandc->reg_read_buf),
-+                                      DMA_FROM_DEVICE);
-+      else
-+              dma_sync_single_for_device(nandc->dev, nandc->reg_read_dma,
-+                                         MAX_REG_RD *
-+                                         sizeof(*nandc->reg_read_buf),
-+                                         DMA_FROM_DEVICE);
-+}
-+EXPORT_SYMBOL(qcom_nandc_dev_to_mem);
-+
-+/**
-+ * qcom_prepare_bam_async_desc() - Prepare DMA descriptor
-+ * @nandc: qpic nand controller
-+ * @chan: dma channel
-+ * @flags: flags to control DMA descriptor preparation
-+ *
-+ * This function maps the scatter gather list for DMA transfer and forms the
-+ * DMA descriptor for BAM.This descriptor will be added in the NAND DMA
-+ * descriptor queue which will be submitted to DMA engine.
-+ */
-+int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc,
-+                              struct dma_chan *chan, unsigned long flags)
-+{
-+      struct desc_info *desc;
-+      struct scatterlist *sgl;
-+      unsigned int sgl_cnt;
-+      int ret;
-+      struct bam_transaction *bam_txn = nandc->bam_txn;
-+      enum dma_transfer_direction dir_eng;
-+      struct dma_async_tx_descriptor *dma_desc;
-+
-+      desc = kzalloc(sizeof(*desc), GFP_KERNEL);
-+      if (!desc)
-+              return -ENOMEM;
-+
-+      if (chan == nandc->cmd_chan) {
-+              sgl = &bam_txn->cmd_sgl[bam_txn->cmd_sgl_start];
-+              sgl_cnt = bam_txn->cmd_sgl_pos - bam_txn->cmd_sgl_start;
-+              bam_txn->cmd_sgl_start = bam_txn->cmd_sgl_pos;
-+              dir_eng = DMA_MEM_TO_DEV;
-+              desc->dir = DMA_TO_DEVICE;
-+      } else if (chan == nandc->tx_chan) {
-+              sgl = &bam_txn->data_sgl[bam_txn->tx_sgl_start];
-+              sgl_cnt = bam_txn->tx_sgl_pos - bam_txn->tx_sgl_start;
-+              bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos;
-+              dir_eng = DMA_MEM_TO_DEV;
-+              desc->dir = DMA_TO_DEVICE;
-+      } else {
-+              sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start];
-+              sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start;
-+              bam_txn->rx_sgl_start = bam_txn->rx_sgl_pos;
-+              dir_eng = DMA_DEV_TO_MEM;
-+              desc->dir = DMA_FROM_DEVICE;
-+      }
-+
-+      sg_mark_end(sgl + sgl_cnt - 1);
-+      ret = dma_map_sg(nandc->dev, sgl, sgl_cnt, desc->dir);
-+      if (ret == 0) {
-+              dev_err(nandc->dev, "failure in mapping desc\n");
-+              kfree(desc);
-+              return -ENOMEM;
-+      }
-+
-+      desc->sgl_cnt = sgl_cnt;
-+      desc->bam_sgl = sgl;
-+
-+      dma_desc = dmaengine_prep_slave_sg(chan, sgl, sgl_cnt, dir_eng,
-+                                         flags);
-+
-+      if (!dma_desc) {
-+              dev_err(nandc->dev, "failure in prep desc\n");
-+              dma_unmap_sg(nandc->dev, sgl, sgl_cnt, desc->dir);
-+              kfree(desc);
-+              return -EINVAL;
-+      }
-+
-+      desc->dma_desc = dma_desc;
-+
-+      /* update last data/command descriptor */
-+      if (chan == nandc->cmd_chan)
-+              bam_txn->last_cmd_desc = dma_desc;
-+      else
-+              bam_txn->last_data_desc = dma_desc;
-+
-+      list_add_tail(&desc->node, &nandc->desc_list);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(qcom_prepare_bam_async_desc);
-+
-+/**
-+ * qcom_prep_bam_dma_desc_cmd() - Prepares the command descriptor for BAM DMA
-+ * @nandc: qpic nand controller
-+ * @read: read or write type
-+ * @reg_off: offset within the controller's data buffer
-+ * @vaddr: virtual address of the buffer we want to write to
-+ * @size: DMA transaction size in bytes
-+ * @flags: flags to control DMA descriptor preparation
-+ *
-+ * This function will prepares the command descriptor for BAM DMA
-+ * which will be used for NAND register reads and writes.
-+ */
-+int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
-+                             int reg_off, const void *vaddr,
-+                             int size, unsigned int flags)
-+{
-+      int bam_ce_size;
-+      int i, ret;
-+      struct bam_cmd_element *bam_ce_buffer;
-+      struct bam_transaction *bam_txn = nandc->bam_txn;
-+
-+      bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos];
-+
-+      /* fill the command desc */
-+      for (i = 0; i < size; i++) {
-+              if (read)
-+                      bam_prep_ce(&bam_ce_buffer[i],
-+                                  nandc_reg_phys(nandc, reg_off + 4 * i),
-+                                  BAM_READ_COMMAND,
-+                                  reg_buf_dma_addr(nandc,
-+                                                   (__le32 *)vaddr + i));
-+              else
-+                      bam_prep_ce_le32(&bam_ce_buffer[i],
-+                                       nandc_reg_phys(nandc, reg_off + 4 * i),
-+                                       BAM_WRITE_COMMAND,
-+                                       *((__le32 *)vaddr + i));
-+      }
-+
-+      bam_txn->bam_ce_pos += size;
-+
-+      /* use the separate sgl after this command */
-+      if (flags & NAND_BAM_NEXT_SGL) {
-+              bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start];
-+              bam_ce_size = (bam_txn->bam_ce_pos -
-+                              bam_txn->bam_ce_start) *
-+                              sizeof(struct bam_cmd_element);
-+              sg_set_buf(&bam_txn->cmd_sgl[bam_txn->cmd_sgl_pos],
-+                         bam_ce_buffer, bam_ce_size);
-+              bam_txn->cmd_sgl_pos++;
-+              bam_txn->bam_ce_start = bam_txn->bam_ce_pos;
-+
-+              if (flags & NAND_BAM_NWD) {
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan,
-+                                                        DMA_PREP_FENCE | DMA_PREP_CMD);
-+                      if (ret)
-+                              return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(qcom_prep_bam_dma_desc_cmd);
-+
-+/**
-+ * qcom_prep_bam_dma_desc_data() - Prepares the data descriptor for BAM DMA
-+ * @nandc: qpic nand controller
-+ * @read: read or write type
-+ * @vaddr: virtual address of the buffer we want to write to
-+ * @size: DMA transaction size in bytes
-+ * @flags: flags to control DMA descriptor preparation
-+ *
-+ * This function will prepares the data descriptor for BAM DMA which
-+ * will be used for NAND data reads and writes.
-+ */
-+int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
-+                              const void *vaddr, int size, unsigned int flags)
-+{
-+      int ret;
-+      struct bam_transaction *bam_txn = nandc->bam_txn;
-+
-+      if (read) {
-+              sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos],
-+                         vaddr, size);
-+              bam_txn->rx_sgl_pos++;
-+      } else {
-+              sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos],
-+                         vaddr, size);
-+              bam_txn->tx_sgl_pos++;
-+
-+              /*
-+               * BAM will only set EOT for DMA_PREP_INTERRUPT so if this flag
-+               * is not set, form the DMA descriptor
-+               */
-+              if (!(flags & NAND_BAM_NO_EOT)) {
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan,
-+                                                        DMA_PREP_INTERRUPT);
-+                      if (ret)
-+                              return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(qcom_prep_bam_dma_desc_data);
-+
-+/**
-+ * qcom_prep_adm_dma_desc() - Prepare descriptor for adma
-+ * @nandc: qpic nand controller
-+ * @read: read or write type
-+ * @reg_off: offset within the controller's data buffer
-+ * @vaddr: virtual address of the buffer we want to write to
-+ * @size: adm dma transaction size in bytes
-+ * @flow_control: flow controller
-+ *
-+ * This function will prepare descriptor for adma
-+ */
-+int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
-+                         int reg_off, const void *vaddr, int size,
-+                         bool flow_control)
-+{
-+      struct qcom_adm_peripheral_config periph_conf = {};
-+      struct dma_async_tx_descriptor *dma_desc;
-+      struct dma_slave_config slave_conf = {0};
-+      enum dma_transfer_direction dir_eng;
-+      struct desc_info *desc;
-+      struct scatterlist *sgl;
-+      int ret;
-+
-+      desc = kzalloc(sizeof(*desc), GFP_KERNEL);
-+      if (!desc)
-+              return -ENOMEM;
-+
-+      sgl = &desc->adm_sgl;
-+
-+      sg_init_one(sgl, vaddr, size);
-+
-+      if (read) {
-+              dir_eng = DMA_DEV_TO_MEM;
-+              desc->dir = DMA_FROM_DEVICE;
-+      } else {
-+              dir_eng = DMA_MEM_TO_DEV;
-+              desc->dir = DMA_TO_DEVICE;
-+      }
-+
-+      ret = dma_map_sg(nandc->dev, sgl, 1, desc->dir);
-+      if (!ret) {
-+              ret = -ENOMEM;
-+              goto err;
-+      }
-+
-+      slave_conf.device_fc = flow_control;
-+      if (read) {
-+              slave_conf.src_maxburst = 16;
-+              slave_conf.src_addr = nandc->base_dma + reg_off;
-+              if (nandc->data_crci) {
-+                      periph_conf.crci = nandc->data_crci;
-+                      slave_conf.peripheral_config = &periph_conf;
-+                      slave_conf.peripheral_size = sizeof(periph_conf);
-+              }
-+      } else {
-+              slave_conf.dst_maxburst = 16;
-+              slave_conf.dst_addr = nandc->base_dma + reg_off;
-+              if (nandc->cmd_crci) {
-+                      periph_conf.crci = nandc->cmd_crci;
-+                      slave_conf.peripheral_config = &periph_conf;
-+                      slave_conf.peripheral_size = sizeof(periph_conf);
-+              }
-+      }
-+
-+      ret = dmaengine_slave_config(nandc->chan, &slave_conf);
-+      if (ret) {
-+              dev_err(nandc->dev, "failed to configure dma channel\n");
-+              goto err;
-+      }
-+
-+      dma_desc = dmaengine_prep_slave_sg(nandc->chan, sgl, 1, dir_eng, 0);
-+      if (!dma_desc) {
-+              dev_err(nandc->dev, "failed to prepare desc\n");
-+              ret = -EINVAL;
-+              goto err;
-+      }
-+
-+      desc->dma_desc = dma_desc;
-+
-+      list_add_tail(&desc->node, &nandc->desc_list);
-+
-+      return 0;
-+err:
-+      kfree(desc);
-+
-+      return ret;
-+}
-+EXPORT_SYMBOL(qcom_prep_adm_dma_desc);
-+
-+/**
-+ * qcom_read_reg_dma() - read a given number of registers to the reg_read_buf pointer
-+ * @nandc: qpic nand controller
-+ * @first: offset of the first register in the contiguous block
-+ * @num_regs: number of registers to read
-+ * @flags: flags to control DMA descriptor preparation
-+ *
-+ * This function will prepares a descriptor to read a given number of
-+ * contiguous registers to the reg_read_buf pointer.
-+ */
-+int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first,
-+                    int num_regs, unsigned int flags)
-+{
-+      bool flow_control = false;
-+      void *vaddr;
-+
-+      vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
-+      nandc->reg_read_pos += num_regs;
-+
-+      if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1)
-+              first = dev_cmd_reg_addr(nandc, first);
-+
-+      if (nandc->props->supports_bam)
-+              return qcom_prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
-+                                           num_regs, flags);
-+
-+      if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
-+              flow_control = true;
-+
-+      return qcom_prep_adm_dma_desc(nandc, true, first, vaddr,
-+                                    num_regs * sizeof(u32), flow_control);
-+}
-+EXPORT_SYMBOL(qcom_read_reg_dma);
-+
-+/**
-+ * qcom_write_reg_dma() - write a given number of registers
-+ * @nandc: qpic nand controller
-+ * @vaddr: contiguous memory from where register value will
-+ *       be written
-+ * @first: offset of the first register in the contiguous block
-+ * @num_regs: number of registers to write
-+ * @flags: flags to control DMA descriptor preparation
-+ *
-+ * This function will prepares a descriptor to write a given number of
-+ * contiguous registers
-+ */
-+int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
-+                     int first, int num_regs, unsigned int flags)
-+{
-+      bool flow_control = false;
-+
-+      if (first == NAND_EXEC_CMD)
-+              flags |= NAND_BAM_NWD;
-+
-+      if (first == NAND_DEV_CMD1_RESTORE || first == NAND_DEV_CMD1)
-+              first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD1);
-+
-+      if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD)
-+              first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD);
-+
-+      if (nandc->props->supports_bam)
-+              return qcom_prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
-+                                                num_regs, flags);
-+
-+      if (first == NAND_FLASH_CMD)
-+              flow_control = true;
-+
-+      return qcom_prep_adm_dma_desc(nandc, false, first, vaddr,
-+                                    num_regs * sizeof(u32), flow_control);
-+}
-+EXPORT_SYMBOL(qcom_write_reg_dma);
-+
-+/**
-+ * qcom_read_data_dma() - transfer data
-+ * @nandc: qpic nand controller
-+ * @reg_off: offset within the controller's data buffer
-+ * @vaddr: virtual address of the buffer we want to write to
-+ * @size: DMA transaction size in bytes
-+ * @flags: flags to control DMA descriptor preparation
-+ *
-+ * This function will prepares a DMA descriptor to transfer data from the
-+ * controller's internal buffer to the buffer 'vaddr'
-+ */
-+int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-+                     const u8 *vaddr, int size, unsigned int flags)
-+{
-+      if (nandc->props->supports_bam)
-+              return qcom_prep_bam_dma_desc_data(nandc, true, vaddr, size, flags);
-+
-+      return qcom_prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
-+}
-+EXPORT_SYMBOL(qcom_read_data_dma);
-+
-+/**
-+ * qcom_write_data_dma() - transfer data
-+ * @nandc: qpic nand controller
-+ * @reg_off: offset within the controller's data buffer
-+ * @vaddr: virtual address of the buffer we want to read from
-+ * @size: DMA transaction size in bytes
-+ * @flags: flags to control DMA descriptor preparation
-+ *
-+ * This function will prepares a DMA descriptor to transfer data from
-+ * 'vaddr' to the controller's internal buffer
-+ */
-+int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-+                      const u8 *vaddr, int size, unsigned int flags)
-+{
-+      if (nandc->props->supports_bam)
-+              return qcom_prep_bam_dma_desc_data(nandc, false, vaddr, size, flags);
-+
-+      return qcom_prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
-+}
-+EXPORT_SYMBOL(qcom_write_data_dma);
-+
-+/**
-+ * qcom_submit_descs() - submit dma descriptor
-+ * @nandc: qpic nand controller
-+ *
-+ * This function will submit all the prepared dma descriptor
-+ * cmd or data descriptor
-+ */
-+int qcom_submit_descs(struct qcom_nand_controller *nandc)
-+{
-+      struct desc_info *desc, *n;
-+      dma_cookie_t cookie = 0;
-+      struct bam_transaction *bam_txn = nandc->bam_txn;
-+      int ret = 0;
-+
-+      if (nandc->props->supports_bam) {
-+              if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) {
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->rx_chan, 0);
-+                      if (ret)
-+                              goto err_unmap_free_desc;
-+              }
-+
-+              if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) {
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan,
-+                                                        DMA_PREP_INTERRUPT);
-+                      if (ret)
-+                              goto err_unmap_free_desc;
-+              }
-+
-+              if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) {
-+                      ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan,
-+                                                        DMA_PREP_CMD);
-+                      if (ret)
-+                              goto err_unmap_free_desc;
-+              }
-+      }
-+
-+      list_for_each_entry(desc, &nandc->desc_list, node)
-+              cookie = dmaengine_submit(desc->dma_desc);
-+
-+      if (nandc->props->supports_bam) {
-+              bam_txn->last_cmd_desc->callback = qcom_qpic_bam_dma_done;
-+              bam_txn->last_cmd_desc->callback_param = bam_txn;
-+
-+              dma_async_issue_pending(nandc->tx_chan);
-+              dma_async_issue_pending(nandc->rx_chan);
-+              dma_async_issue_pending(nandc->cmd_chan);
-+
-+              if (!wait_for_completion_timeout(&bam_txn->txn_done,
-+                                               QPIC_NAND_COMPLETION_TIMEOUT))
-+                      ret = -ETIMEDOUT;
-+      } else {
-+              if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE)
-+                      ret = -ETIMEDOUT;
-+      }
-+
-+err_unmap_free_desc:
-+      /*
-+       * Unmap the dma sg_list and free the desc allocated by both
-+       * qcom_prepare_bam_async_desc() and qcom_prep_adm_dma_desc() functions.
-+       */
-+      list_for_each_entry_safe(desc, n, &nandc->desc_list, node) {
-+              list_del(&desc->node);
-+
-+              if (nandc->props->supports_bam)
-+                      dma_unmap_sg(nandc->dev, desc->bam_sgl,
-+                                   desc->sgl_cnt, desc->dir);
-+              else
-+                      dma_unmap_sg(nandc->dev, &desc->adm_sgl, 1,
-+                                   desc->dir);
-+
-+              kfree(desc);
-+      }
-+
-+      return ret;
-+}
-+EXPORT_SYMBOL(qcom_submit_descs);
-+
-+/**
-+ * qcom_clear_read_regs() - reset the read register buffer
-+ * @nandc: qpic nand controller
-+ *
-+ * This function reset the register read buffer for next NAND operation
-+ */
-+void qcom_clear_read_regs(struct qcom_nand_controller *nandc)
-+{
-+      nandc->reg_read_pos = 0;
-+      qcom_nandc_dev_to_mem(nandc, false);
-+}
-+EXPORT_SYMBOL(qcom_clear_read_regs);
-+
-+/**
-+ * qcom_nandc_unalloc() - unallocate qpic nand controller
-+ * @nandc: qpic nand controller
-+ *
-+ * This function will unallocate memory alloacted for qpic nand controller
-+ */
-+void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
-+{
-+      if (nandc->props->supports_bam) {
-+              if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma))
-+                      dma_unmap_single(nandc->dev, nandc->reg_read_dma,
-+                                       MAX_REG_RD *
-+                                       sizeof(*nandc->reg_read_buf),
-+                                       DMA_FROM_DEVICE);
-+
-+              if (nandc->tx_chan)
-+                      dma_release_channel(nandc->tx_chan);
-+
-+              if (nandc->rx_chan)
-+                      dma_release_channel(nandc->rx_chan);
-+
-+              if (nandc->cmd_chan)
-+                      dma_release_channel(nandc->cmd_chan);
-+      } else {
-+              if (nandc->chan)
-+                      dma_release_channel(nandc->chan);
-+      }
-+}
-+EXPORT_SYMBOL(qcom_nandc_unalloc);
-+
-+/**
-+ * qcom_nandc_alloc() - Allocate qpic nand controller
-+ * @nandc: qpic nand controller
-+ *
-+ * This function will allocate memory for qpic nand controller
-+ */
-+int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
-+{
-+      int ret;
-+
-+      ret = dma_set_coherent_mask(nandc->dev, DMA_BIT_MASK(32));
-+      if (ret) {
-+              dev_err(nandc->dev, "failed to set DMA mask\n");
-+              return ret;
-+      }
-+
-+      /*
-+       * we use the internal buffer for reading ONFI params, reading small
-+       * data like ID and status, and preforming read-copy-write operations
-+       * when writing to a codeword partially. 532 is the maximum possible
-+       * size of a codeword for our nand controller
-+       */
-+      nandc->buf_size = 532;
-+
-+      nandc->data_buffer = devm_kzalloc(nandc->dev, nandc->buf_size, GFP_KERNEL);
-+      if (!nandc->data_buffer)
-+              return -ENOMEM;
-+
-+      nandc->regs = devm_kzalloc(nandc->dev, sizeof(*nandc->regs), GFP_KERNEL);
-+      if (!nandc->regs)
-+              return -ENOMEM;
-+
-+      nandc->reg_read_buf = devm_kcalloc(nandc->dev, MAX_REG_RD,
-+                                         sizeof(*nandc->reg_read_buf),
-+                                         GFP_KERNEL);
-+      if (!nandc->reg_read_buf)
-+              return -ENOMEM;
-+
-+      if (nandc->props->supports_bam) {
-+              nandc->reg_read_dma =
-+                      dma_map_single(nandc->dev, nandc->reg_read_buf,
-+                                     MAX_REG_RD *
-+                                     sizeof(*nandc->reg_read_buf),
-+                                     DMA_FROM_DEVICE);
-+              if (dma_mapping_error(nandc->dev, nandc->reg_read_dma)) {
-+                      dev_err(nandc->dev, "failed to DMA MAP reg buffer\n");
-+                      return -EIO;
-+              }
-+
-+              nandc->tx_chan = dma_request_chan(nandc->dev, "tx");
-+              if (IS_ERR(nandc->tx_chan)) {
-+                      ret = PTR_ERR(nandc->tx_chan);
-+                      nandc->tx_chan = NULL;
-+                      dev_err_probe(nandc->dev, ret,
-+                                    "tx DMA channel request failed\n");
-+                      goto unalloc;
-+              }
-+
-+              nandc->rx_chan = dma_request_chan(nandc->dev, "rx");
-+              if (IS_ERR(nandc->rx_chan)) {
-+                      ret = PTR_ERR(nandc->rx_chan);
-+                      nandc->rx_chan = NULL;
-+                      dev_err_probe(nandc->dev, ret,
-+                                    "rx DMA channel request failed\n");
-+                      goto unalloc;
-+              }
-+
-+              nandc->cmd_chan = dma_request_chan(nandc->dev, "cmd");
-+              if (IS_ERR(nandc->cmd_chan)) {
-+                      ret = PTR_ERR(nandc->cmd_chan);
-+                      nandc->cmd_chan = NULL;
-+                      dev_err_probe(nandc->dev, ret,
-+                                    "cmd DMA channel request failed\n");
-+                      goto unalloc;
-+              }
-+
-+              /*
-+               * Initially allocate BAM transaction to read ONFI param page.
-+               * After detecting all the devices, this BAM transaction will
-+               * be freed and the next BAM transaction will be allocated with
-+               * maximum codeword size
-+               */
-+              nandc->max_cwperpage = 1;
-+              nandc->bam_txn = qcom_alloc_bam_transaction(nandc);
-+              if (!nandc->bam_txn) {
-+                      dev_err(nandc->dev,
-+                              "failed to allocate bam transaction\n");
-+                      ret = -ENOMEM;
-+                      goto unalloc;
-+              }
-+      } else {
-+              nandc->chan = dma_request_chan(nandc->dev, "rxtx");
-+              if (IS_ERR(nandc->chan)) {
-+                      ret = PTR_ERR(nandc->chan);
-+                      nandc->chan = NULL;
-+                      dev_err_probe(nandc->dev, ret,
-+                                    "rxtx DMA channel request failed\n");
-+                      return ret;
-+              }
-+      }
-+
-+      INIT_LIST_HEAD(&nandc->desc_list);
-+      INIT_LIST_HEAD(&nandc->host_list);
-+
-+      return 0;
-+unalloc:
-+      qcom_nandc_unalloc(nandc);
-+      return ret;
-+}
-+EXPORT_SYMBOL(qcom_nandc_alloc);
-+
-+MODULE_DESCRIPTION("QPIC controller common api");
-+MODULE_LICENSE("GPL");
---- a/drivers/mtd/nand/raw/qcom_nandc.c
-+++ b/drivers/mtd/nand/raw/qcom_nandc.c
-@@ -15,417 +15,7 @@
- #include <linux/of.h>
- #include <linux/platform_device.h>
- #include <linux/slab.h>
--
--/* NANDc reg offsets */
--#define       NAND_FLASH_CMD                  0x00
--#define       NAND_ADDR0                      0x04
--#define       NAND_ADDR1                      0x08
--#define       NAND_FLASH_CHIP_SELECT          0x0c
--#define       NAND_EXEC_CMD                   0x10
--#define       NAND_FLASH_STATUS               0x14
--#define       NAND_BUFFER_STATUS              0x18
--#define       NAND_DEV0_CFG0                  0x20
--#define       NAND_DEV0_CFG1                  0x24
--#define       NAND_DEV0_ECC_CFG               0x28
--#define       NAND_AUTO_STATUS_EN             0x2c
--#define       NAND_DEV1_CFG0                  0x30
--#define       NAND_DEV1_CFG1                  0x34
--#define       NAND_READ_ID                    0x40
--#define       NAND_READ_STATUS                0x44
--#define       NAND_DEV_CMD0                   0xa0
--#define       NAND_DEV_CMD1                   0xa4
--#define       NAND_DEV_CMD2                   0xa8
--#define       NAND_DEV_CMD_VLD                0xac
--#define       SFLASHC_BURST_CFG               0xe0
--#define       NAND_ERASED_CW_DETECT_CFG       0xe8
--#define       NAND_ERASED_CW_DETECT_STATUS    0xec
--#define       NAND_EBI2_ECC_BUF_CFG           0xf0
--#define       FLASH_BUF_ACC                   0x100
--
--#define       NAND_CTRL                       0xf00
--#define       NAND_VERSION                    0xf08
--#define       NAND_READ_LOCATION_0            0xf20
--#define       NAND_READ_LOCATION_1            0xf24
--#define       NAND_READ_LOCATION_2            0xf28
--#define       NAND_READ_LOCATION_3            0xf2c
--#define       NAND_READ_LOCATION_LAST_CW_0    0xf40
--#define       NAND_READ_LOCATION_LAST_CW_1    0xf44
--#define       NAND_READ_LOCATION_LAST_CW_2    0xf48
--#define       NAND_READ_LOCATION_LAST_CW_3    0xf4c
--
--/* dummy register offsets, used by qcom_write_reg_dma */
--#define       NAND_DEV_CMD1_RESTORE           0xdead
--#define       NAND_DEV_CMD_VLD_RESTORE        0xbeef
--
--/* NAND_FLASH_CMD bits */
--#define       PAGE_ACC                        BIT(4)
--#define       LAST_PAGE                       BIT(5)
--
--/* NAND_FLASH_CHIP_SELECT bits */
--#define       NAND_DEV_SEL                    0
--#define       DM_EN                           BIT(2)
--
--/* NAND_FLASH_STATUS bits */
--#define       FS_OP_ERR                       BIT(4)
--#define       FS_READY_BSY_N                  BIT(5)
--#define       FS_MPU_ERR                      BIT(8)
--#define       FS_DEVICE_STS_ERR               BIT(16)
--#define       FS_DEVICE_WP                    BIT(23)
--
--/* NAND_BUFFER_STATUS bits */
--#define       BS_UNCORRECTABLE_BIT            BIT(8)
--#define       BS_CORRECTABLE_ERR_MSK          0x1f
--
--/* NAND_DEVn_CFG0 bits */
--#define       DISABLE_STATUS_AFTER_WRITE      4
--#define       CW_PER_PAGE                     6
--#define       UD_SIZE_BYTES                   9
--#define       UD_SIZE_BYTES_MASK              GENMASK(18, 9)
--#define       ECC_PARITY_SIZE_BYTES_RS        19
--#define       SPARE_SIZE_BYTES                23
--#define       SPARE_SIZE_BYTES_MASK           GENMASK(26, 23)
--#define       NUM_ADDR_CYCLES                 27
--#define       STATUS_BFR_READ                 30
--#define       SET_RD_MODE_AFTER_STATUS        31
--
--/* NAND_DEVn_CFG0 bits */
--#define       DEV0_CFG1_ECC_DISABLE           0
--#define       WIDE_FLASH                      1
--#define       NAND_RECOVERY_CYCLES            2
--#define       CS_ACTIVE_BSY                   5
--#define       BAD_BLOCK_BYTE_NUM              6
--#define       BAD_BLOCK_IN_SPARE_AREA         16
--#define       WR_RD_BSY_GAP                   17
--#define       ENABLE_BCH_ECC                  27
--
--/* NAND_DEV0_ECC_CFG bits */
--#define       ECC_CFG_ECC_DISABLE             0
--#define       ECC_SW_RESET                    1
--#define       ECC_MODE                        4
--#define       ECC_PARITY_SIZE_BYTES_BCH       8
--#define       ECC_NUM_DATA_BYTES              16
--#define       ECC_NUM_DATA_BYTES_MASK         GENMASK(25, 16)
--#define       ECC_FORCE_CLK_OPEN              30
--
--/* NAND_DEV_CMD1 bits */
--#define       READ_ADDR                       0
--
--/* NAND_DEV_CMD_VLD bits */
--#define       READ_START_VLD                  BIT(0)
--#define       READ_STOP_VLD                   BIT(1)
--#define       WRITE_START_VLD                 BIT(2)
--#define       ERASE_START_VLD                 BIT(3)
--#define       SEQ_READ_START_VLD              BIT(4)
--
--/* NAND_EBI2_ECC_BUF_CFG bits */
--#define       NUM_STEPS                       0
--
--/* NAND_ERASED_CW_DETECT_CFG bits */
--#define       ERASED_CW_ECC_MASK              1
--#define       AUTO_DETECT_RES                 0
--#define       MASK_ECC                        BIT(ERASED_CW_ECC_MASK)
--#define       RESET_ERASED_DET                BIT(AUTO_DETECT_RES)
--#define       ACTIVE_ERASED_DET               (0 << AUTO_DETECT_RES)
--#define       CLR_ERASED_PAGE_DET             (RESET_ERASED_DET | MASK_ECC)
--#define       SET_ERASED_PAGE_DET             (ACTIVE_ERASED_DET | MASK_ECC)
--
--/* NAND_ERASED_CW_DETECT_STATUS bits */
--#define       PAGE_ALL_ERASED                 BIT(7)
--#define       CODEWORD_ALL_ERASED             BIT(6)
--#define       PAGE_ERASED                     BIT(5)
--#define       CODEWORD_ERASED                 BIT(4)
--#define       ERASED_PAGE                     (PAGE_ALL_ERASED | PAGE_ERASED)
--#define       ERASED_CW                       (CODEWORD_ALL_ERASED | CODEWORD_ERASED)
--
--/* NAND_READ_LOCATION_n bits */
--#define READ_LOCATION_OFFSET          0
--#define READ_LOCATION_SIZE            16
--#define READ_LOCATION_LAST            31
--
--/* Version Mask */
--#define       NAND_VERSION_MAJOR_MASK         0xf0000000
--#define       NAND_VERSION_MAJOR_SHIFT        28
--#define       NAND_VERSION_MINOR_MASK         0x0fff0000
--#define       NAND_VERSION_MINOR_SHIFT        16
--
--/* NAND OP_CMDs */
--#define       OP_PAGE_READ                    0x2
--#define       OP_PAGE_READ_WITH_ECC           0x3
--#define       OP_PAGE_READ_WITH_ECC_SPARE     0x4
--#define       OP_PAGE_READ_ONFI_READ          0x5
--#define       OP_PROGRAM_PAGE                 0x6
--#define       OP_PAGE_PROGRAM_WITH_ECC        0x7
--#define       OP_PROGRAM_PAGE_SPARE           0x9
--#define       OP_BLOCK_ERASE                  0xa
--#define       OP_CHECK_STATUS                 0xc
--#define       OP_FETCH_ID                     0xb
--#define       OP_RESET_DEVICE                 0xd
--
--/* Default Value for NAND_DEV_CMD_VLD */
--#define NAND_DEV_CMD_VLD_VAL          (READ_START_VLD | WRITE_START_VLD | \
--                                       ERASE_START_VLD | SEQ_READ_START_VLD)
--
--/* NAND_CTRL bits */
--#define       BAM_MODE_EN                     BIT(0)
--
--/*
-- * the NAND controller performs reads/writes with ECC in 516 byte chunks.
-- * the driver calls the chunks 'step' or 'codeword' interchangeably
-- */
--#define       NANDC_STEP_SIZE                 512
--
--/*
-- * the largest page size we support is 8K, this will have 16 steps/codewords
-- * of 512 bytes each
-- */
--#define       MAX_NUM_STEPS                   (SZ_8K / NANDC_STEP_SIZE)
--
--/* we read at most 3 registers per codeword scan */
--#define       MAX_REG_RD                      (3 * MAX_NUM_STEPS)
--
--/* ECC modes supported by the controller */
--#define       ECC_NONE        BIT(0)
--#define       ECC_RS_4BIT     BIT(1)
--#define       ECC_BCH_4BIT    BIT(2)
--#define       ECC_BCH_8BIT    BIT(3)
--
--/*
-- * Returns the actual register address for all NAND_DEV_ registers
-- * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD)
-- */
--#define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg))
--
--/* Returns the NAND register physical address */
--#define nandc_reg_phys(chip, offset) ((chip)->base_phys + (offset))
--
--/* Returns the dma address for reg read buffer */
--#define reg_buf_dma_addr(chip, vaddr) \
--      ((chip)->reg_read_dma + \
--      ((u8 *)(vaddr) - (u8 *)(chip)->reg_read_buf))
--
--#define QPIC_PER_CW_CMD_ELEMENTS      32
--#define QPIC_PER_CW_CMD_SGL           32
--#define QPIC_PER_CW_DATA_SGL          8
--
--#define QPIC_NAND_COMPLETION_TIMEOUT  msecs_to_jiffies(2000)
--
--/*
-- * Flags used in DMA descriptor preparation helper functions
-- * (i.e. qcom_read_reg_dma/qcom_write_reg_dma/qcom_read_data_dma/qcom_write_data_dma)
-- */
--/* Don't set the EOT in current tx BAM sgl */
--#define NAND_BAM_NO_EOT                       BIT(0)
--/* Set the NWD flag in current BAM sgl */
--#define NAND_BAM_NWD                  BIT(1)
--/* Finish writing in the current BAM sgl and start writing in another BAM sgl */
--#define NAND_BAM_NEXT_SGL             BIT(2)
--/*
-- * Erased codeword status is being used two times in single transfer so this
-- * flag will determine the current value of erased codeword status register
-- */
--#define NAND_ERASED_CW_SET            BIT(4)
--
--#define MAX_ADDRESS_CYCLE             5
--
--/*
-- * This data type corresponds to the BAM transaction which will be used for all
-- * NAND transfers.
-- * @bam_ce - the array of BAM command elements
-- * @cmd_sgl - sgl for NAND BAM command pipe
-- * @data_sgl - sgl for NAND BAM consumer/producer pipe
-- * @last_data_desc - last DMA desc in data channel (tx/rx).
-- * @last_cmd_desc - last DMA desc in command channel.
-- * @txn_done - completion for NAND transfer.
-- * @bam_ce_pos - the index in bam_ce which is available for next sgl
-- * @bam_ce_start - the index in bam_ce which marks the start position ce
-- *               for current sgl. It will be used for size calculation
-- *               for current sgl
-- * @cmd_sgl_pos - current index in command sgl.
-- * @cmd_sgl_start - start index in command sgl.
-- * @tx_sgl_pos - current index in data sgl for tx.
-- * @tx_sgl_start - start index in data sgl for tx.
-- * @rx_sgl_pos - current index in data sgl for rx.
-- * @rx_sgl_start - start index in data sgl for rx.
-- */
--struct bam_transaction {
--      struct bam_cmd_element *bam_ce;
--      struct scatterlist *cmd_sgl;
--      struct scatterlist *data_sgl;
--      struct dma_async_tx_descriptor *last_data_desc;
--      struct dma_async_tx_descriptor *last_cmd_desc;
--      struct completion txn_done;
--      u32 bam_ce_pos;
--      u32 bam_ce_start;
--      u32 cmd_sgl_pos;
--      u32 cmd_sgl_start;
--      u32 tx_sgl_pos;
--      u32 tx_sgl_start;
--      u32 rx_sgl_pos;
--      u32 rx_sgl_start;
--};
--
--/*
-- * This data type corresponds to the nand dma descriptor
-- * @dma_desc - low level DMA engine descriptor
-- * @list - list for desc_info
-- *
-- * @adm_sgl - sgl which will be used for single sgl dma descriptor. Only used by
-- *          ADM
-- * @bam_sgl - sgl which will be used for dma descriptor. Only used by BAM
-- * @sgl_cnt - number of SGL in bam_sgl. Only used by BAM
-- * @dir - DMA transfer direction
-- */
--struct desc_info {
--      struct dma_async_tx_descriptor *dma_desc;
--      struct list_head node;
--
--      union {
--              struct scatterlist adm_sgl;
--              struct {
--                      struct scatterlist *bam_sgl;
--                      int sgl_cnt;
--              };
--      };
--      enum dma_data_direction dir;
--};
--
--/*
-- * holds the current register values that we want to write. acts as a contiguous
-- * chunk of memory which we use to write the controller registers through DMA.
-- */
--struct nandc_regs {
--      __le32 cmd;
--      __le32 addr0;
--      __le32 addr1;
--      __le32 chip_sel;
--      __le32 exec;
--
--      __le32 cfg0;
--      __le32 cfg1;
--      __le32 ecc_bch_cfg;
--
--      __le32 clrflashstatus;
--      __le32 clrreadstatus;
--
--      __le32 cmd1;
--      __le32 vld;
--
--      __le32 orig_cmd1;
--      __le32 orig_vld;
--
--      __le32 ecc_buf_cfg;
--      __le32 read_location0;
--      __le32 read_location1;
--      __le32 read_location2;
--      __le32 read_location3;
--      __le32 read_location_last0;
--      __le32 read_location_last1;
--      __le32 read_location_last2;
--      __le32 read_location_last3;
--
--      __le32 erased_cw_detect_cfg_clr;
--      __le32 erased_cw_detect_cfg_set;
--};
--
--/*
-- * NAND controller data struct
-- *
-- * @dev:                      parent device
-- *
-- * @base:                     MMIO base
-- *
-- * @core_clk:                 controller clock
-- * @aon_clk:                  another controller clock
-- *
-- * @regs:                     a contiguous chunk of memory for DMA register
-- *                            writes. contains the register values to be
-- *                            written to controller
-- *
-- * @props:                    properties of current NAND controller,
-- *                            initialized via DT match data
-- *
-- * @controller:                       base controller structure
-- * @host_list:                        list containing all the chips attached to the
-- *                            controller
-- *
-- * @chan:                     dma channel
-- * @cmd_crci:                 ADM DMA CRCI for command flow control
-- * @data_crci:                        ADM DMA CRCI for data flow control
-- *
-- * @desc_list:                        DMA descriptor list (list of desc_infos)
-- *
-- * @data_buffer:              our local DMA buffer for page read/writes,
-- *                            used when we can't use the buffer provided
-- *                            by upper layers directly
-- * @reg_read_buf:             local buffer for reading back registers via DMA
-- *
-- * @base_phys:                        physical base address of controller registers
-- * @base_dma:                 dma base address of controller registers
-- * @reg_read_dma:             contains dma address for register read buffer
-- *
-- * @buf_size/count/start:     markers for chip->legacy.read_buf/write_buf
-- *                            functions
-- * @max_cwperpage:            maximum QPIC codewords required. calculated
-- *                            from all connected NAND devices pagesize
-- *
-- * @reg_read_pos:             marker for data read in reg_read_buf
-- *
-- * @cmd1/vld:                 some fixed controller register values
-- *
-- * @exec_opwrite:             flag to select correct number of code word
-- *                            while reading status
-- */
--struct qcom_nand_controller {
--      struct device *dev;
--
--      void __iomem *base;
--
--      struct clk *core_clk;
--      struct clk *aon_clk;
--
--      struct nandc_regs *regs;
--      struct bam_transaction *bam_txn;
--
--      const struct qcom_nandc_props *props;
--
--      struct nand_controller controller;
--      struct list_head host_list;
--
--      union {
--              /* will be used only by QPIC for BAM DMA */
--              struct {
--                      struct dma_chan *tx_chan;
--                      struct dma_chan *rx_chan;
--                      struct dma_chan *cmd_chan;
--              };
--
--              /* will be used only by EBI2 for ADM DMA */
--              struct {
--                      struct dma_chan *chan;
--                      unsigned int cmd_crci;
--                      unsigned int data_crci;
--              };
--      };
--
--      struct list_head desc_list;
--
--      u8              *data_buffer;
--      __le32          *reg_read_buf;
--
--      phys_addr_t base_phys;
--      dma_addr_t base_dma;
--      dma_addr_t reg_read_dma;
--
--      int             buf_size;
--      int             buf_count;
--      int             buf_start;
--      unsigned int    max_cwperpage;
--
--      int reg_read_pos;
--
--      u32 cmd1, vld;
--      bool exec_opwrite;
--};
-+#include <linux/mtd/nand-qpic-common.h>
- /*
-  * NAND special boot partitions
-@@ -530,97 +120,6 @@ struct qcom_nand_host {
-       bool bch_enabled;
- };
--/*
-- * This data type corresponds to the NAND controller properties which varies
-- * among different NAND controllers.
-- * @ecc_modes - ecc mode for NAND
-- * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset
-- * @supports_bam - whether NAND controller is using Bus Access Manager (BAM)
-- * @nandc_part_of_qpic - whether NAND controller is part of qpic IP
-- * @qpic_version2 - flag to indicate QPIC IP version 2
-- * @use_codeword_fixup - whether NAND has different layout for boot partitions
-- */
--struct qcom_nandc_props {
--      u32 ecc_modes;
--      u32 dev_cmd_reg_start;
--      bool supports_bam;
--      bool nandc_part_of_qpic;
--      bool qpic_version2;
--      bool use_codeword_fixup;
--};
--
--/* Frees the BAM transaction memory */
--static void qcom_free_bam_transaction(struct qcom_nand_controller *nandc)
--{
--      struct bam_transaction *bam_txn = nandc->bam_txn;
--
--      devm_kfree(nandc->dev, bam_txn);
--}
--
--/* Allocates and Initializes the BAM transaction */
--static struct bam_transaction *
--qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc)
--{
--      struct bam_transaction *bam_txn;
--      size_t bam_txn_size;
--      unsigned int num_cw = nandc->max_cwperpage;
--      void *bam_txn_buf;
--
--      bam_txn_size =
--              sizeof(*bam_txn) + num_cw *
--              ((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) +
--              (sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
--              (sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL));
--
--      bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL);
--      if (!bam_txn_buf)
--              return NULL;
--
--      bam_txn = bam_txn_buf;
--      bam_txn_buf += sizeof(*bam_txn);
--
--      bam_txn->bam_ce = bam_txn_buf;
--      bam_txn_buf +=
--              sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw;
--
--      bam_txn->cmd_sgl = bam_txn_buf;
--      bam_txn_buf +=
--              sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw;
--
--      bam_txn->data_sgl = bam_txn_buf;
--
--      init_completion(&bam_txn->txn_done);
--
--      return bam_txn;
--}
--
--/* Clears the BAM transaction indexes */
--static void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc)
--{
--      struct bam_transaction *bam_txn = nandc->bam_txn;
--
--      if (!nandc->props->supports_bam)
--              return;
--
--      memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8);
--      bam_txn->last_data_desc = NULL;
--
--      sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
--                    QPIC_PER_CW_CMD_SGL);
--      sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage *
--                    QPIC_PER_CW_DATA_SGL);
--
--      reinit_completion(&bam_txn->txn_done);
--}
--
--/* Callback for DMA descriptor completion */
--static void qcom_qpic_bam_dma_done(void *data)
--{
--      struct bam_transaction *bam_txn = data;
--
--      complete(&bam_txn->txn_done);
--}
--
- static struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
- {
-       return container_of(chip, struct qcom_nand_host, chip);
-@@ -629,8 +128,8 @@ static struct qcom_nand_host *to_qcom_na
- static struct qcom_nand_controller *
- get_qcom_nand_controller(struct nand_chip *chip)
- {
--      return container_of(chip->controller, struct qcom_nand_controller,
--                          controller);
-+      return (struct qcom_nand_controller *)
-+              ((u8 *)chip->controller - sizeof(struct qcom_nand_controller));
- }
- static u32 nandc_read(struct qcom_nand_controller *nandc, int offset)
-@@ -644,23 +143,6 @@ static void nandc_write(struct qcom_nand
-       iowrite32(val, nandc->base + offset);
- }
--static void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu)
--{
--      if (!nandc->props->supports_bam)
--              return;
--
--      if (is_cpu)
--              dma_sync_single_for_cpu(nandc->dev, nandc->reg_read_dma,
--                                      MAX_REG_RD *
--                                      sizeof(*nandc->reg_read_buf),
--                                      DMA_FROM_DEVICE);
--      else
--              dma_sync_single_for_device(nandc->dev, nandc->reg_read_dma,
--                                         MAX_REG_RD *
--                                         sizeof(*nandc->reg_read_buf),
--                                         DMA_FROM_DEVICE);
--}
--
- /* Helper to check whether this is the last CW or not */
- static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw)
- {
-@@ -820,356 +302,6 @@ static void update_rw_regs(struct qcom_n
- }
- /*
-- * Maps the scatter gather list for DMA transfer and forms the DMA descriptor
-- * for BAM. This descriptor will be added in the NAND DMA descriptor queue
-- * which will be submitted to DMA engine.
-- */
--static int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc,
--                                     struct dma_chan *chan,
--                                     unsigned long flags)
--{
--      struct desc_info *desc;
--      struct scatterlist *sgl;
--      unsigned int sgl_cnt;
--      int ret;
--      struct bam_transaction *bam_txn = nandc->bam_txn;
--      enum dma_transfer_direction dir_eng;
--      struct dma_async_tx_descriptor *dma_desc;
--
--      desc = kzalloc(sizeof(*desc), GFP_KERNEL);
--      if (!desc)
--              return -ENOMEM;
--
--      if (chan == nandc->cmd_chan) {
--              sgl = &bam_txn->cmd_sgl[bam_txn->cmd_sgl_start];
--              sgl_cnt = bam_txn->cmd_sgl_pos - bam_txn->cmd_sgl_start;
--              bam_txn->cmd_sgl_start = bam_txn->cmd_sgl_pos;
--              dir_eng = DMA_MEM_TO_DEV;
--              desc->dir = DMA_TO_DEVICE;
--      } else if (chan == nandc->tx_chan) {
--              sgl = &bam_txn->data_sgl[bam_txn->tx_sgl_start];
--              sgl_cnt = bam_txn->tx_sgl_pos - bam_txn->tx_sgl_start;
--              bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos;
--              dir_eng = DMA_MEM_TO_DEV;
--              desc->dir = DMA_TO_DEVICE;
--      } else {
--              sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start];
--              sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start;
--              bam_txn->rx_sgl_start = bam_txn->rx_sgl_pos;
--              dir_eng = DMA_DEV_TO_MEM;
--              desc->dir = DMA_FROM_DEVICE;
--      }
--
--      sg_mark_end(sgl + sgl_cnt - 1);
--      ret = dma_map_sg(nandc->dev, sgl, sgl_cnt, desc->dir);
--      if (ret == 0) {
--              dev_err(nandc->dev, "failure in mapping desc\n");
--              kfree(desc);
--              return -ENOMEM;
--      }
--
--      desc->sgl_cnt = sgl_cnt;
--      desc->bam_sgl = sgl;
--
--      dma_desc = dmaengine_prep_slave_sg(chan, sgl, sgl_cnt, dir_eng,
--                                         flags);
--
--      if (!dma_desc) {
--              dev_err(nandc->dev, "failure in prep desc\n");
--              dma_unmap_sg(nandc->dev, sgl, sgl_cnt, desc->dir);
--              kfree(desc);
--              return -EINVAL;
--      }
--
--      desc->dma_desc = dma_desc;
--
--      /* update last data/command descriptor */
--      if (chan == nandc->cmd_chan)
--              bam_txn->last_cmd_desc = dma_desc;
--      else
--              bam_txn->last_data_desc = dma_desc;
--
--      list_add_tail(&desc->node, &nandc->desc_list);
--
--      return 0;
--}
--
--/*
-- * Prepares the command descriptor for BAM DMA which will be used for NAND
-- * register reads and writes. The command descriptor requires the command
-- * to be formed in command element type so this function uses the command
-- * element from bam transaction ce array and fills the same with required
-- * data. A single SGL can contain multiple command elements so
-- * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
-- * after the current command element.
-- */
--static int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
--                                    int reg_off, const void *vaddr,
--                                    int size, unsigned int flags)
--{
--      int bam_ce_size;
--      int i, ret;
--      struct bam_cmd_element *bam_ce_buffer;
--      struct bam_transaction *bam_txn = nandc->bam_txn;
--
--      bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos];
--
--      /* fill the command desc */
--      for (i = 0; i < size; i++) {
--              if (read)
--                      bam_prep_ce(&bam_ce_buffer[i],
--                                  nandc_reg_phys(nandc, reg_off + 4 * i),
--                                  BAM_READ_COMMAND,
--                                  reg_buf_dma_addr(nandc,
--                                                   (__le32 *)vaddr + i));
--              else
--                      bam_prep_ce_le32(&bam_ce_buffer[i],
--                                       nandc_reg_phys(nandc, reg_off + 4 * i),
--                                       BAM_WRITE_COMMAND,
--                                       *((__le32 *)vaddr + i));
--      }
--
--      bam_txn->bam_ce_pos += size;
--
--      /* use the separate sgl after this command */
--      if (flags & NAND_BAM_NEXT_SGL) {
--              bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start];
--              bam_ce_size = (bam_txn->bam_ce_pos -
--                              bam_txn->bam_ce_start) *
--                              sizeof(struct bam_cmd_element);
--              sg_set_buf(&bam_txn->cmd_sgl[bam_txn->cmd_sgl_pos],
--                         bam_ce_buffer, bam_ce_size);
--              bam_txn->cmd_sgl_pos++;
--              bam_txn->bam_ce_start = bam_txn->bam_ce_pos;
--
--              if (flags & NAND_BAM_NWD) {
--                      ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan,
--                                                        DMA_PREP_FENCE |
--                                                        DMA_PREP_CMD);
--                      if (ret)
--                              return ret;
--              }
--      }
--
--      return 0;
--}
--
--/*
-- * Prepares the data descriptor for BAM DMA which will be used for NAND
-- * data reads and writes.
-- */
--static int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
--                                     const void *vaddr, int size, unsigned int flags)
--{
--      int ret;
--      struct bam_transaction *bam_txn = nandc->bam_txn;
--
--      if (read) {
--              sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos],
--                         vaddr, size);
--              bam_txn->rx_sgl_pos++;
--      } else {
--              sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos],
--                         vaddr, size);
--              bam_txn->tx_sgl_pos++;
--
--              /*
--               * BAM will only set EOT for DMA_PREP_INTERRUPT so if this flag
--               * is not set, form the DMA descriptor
--               */
--              if (!(flags & NAND_BAM_NO_EOT)) {
--                      ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan,
--                                                        DMA_PREP_INTERRUPT);
--                      if (ret)
--                              return ret;
--              }
--      }
--
--      return 0;
--}
--
--static int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
--                                int reg_off, const void *vaddr, int size,
--                                bool flow_control)
--{
--      struct desc_info *desc;
--      struct dma_async_tx_descriptor *dma_desc;
--      struct scatterlist *sgl;
--      struct dma_slave_config slave_conf;
--      struct qcom_adm_peripheral_config periph_conf = {};
--      enum dma_transfer_direction dir_eng;
--      int ret;
--
--      desc = kzalloc(sizeof(*desc), GFP_KERNEL);
--      if (!desc)
--              return -ENOMEM;
--
--      sgl = &desc->adm_sgl;
--
--      sg_init_one(sgl, vaddr, size);
--
--      if (read) {
--              dir_eng = DMA_DEV_TO_MEM;
--              desc->dir = DMA_FROM_DEVICE;
--      } else {
--              dir_eng = DMA_MEM_TO_DEV;
--              desc->dir = DMA_TO_DEVICE;
--      }
--
--      ret = dma_map_sg(nandc->dev, sgl, 1, desc->dir);
--      if (ret == 0) {
--              ret = -ENOMEM;
--              goto err;
--      }
--
--      memset(&slave_conf, 0x00, sizeof(slave_conf));
--
--      slave_conf.device_fc = flow_control;
--      if (read) {
--              slave_conf.src_maxburst = 16;
--              slave_conf.src_addr = nandc->base_dma + reg_off;
--              if (nandc->data_crci) {
--                      periph_conf.crci = nandc->data_crci;
--                      slave_conf.peripheral_config = &periph_conf;
--                      slave_conf.peripheral_size = sizeof(periph_conf);
--              }
--      } else {
--              slave_conf.dst_maxburst = 16;
--              slave_conf.dst_addr = nandc->base_dma + reg_off;
--              if (nandc->cmd_crci) {
--                      periph_conf.crci = nandc->cmd_crci;
--                      slave_conf.peripheral_config = &periph_conf;
--                      slave_conf.peripheral_size = sizeof(periph_conf);
--              }
--      }
--
--      ret = dmaengine_slave_config(nandc->chan, &slave_conf);
--      if (ret) {
--              dev_err(nandc->dev, "failed to configure dma channel\n");
--              goto err;
--      }
--
--      dma_desc = dmaengine_prep_slave_sg(nandc->chan, sgl, 1, dir_eng, 0);
--      if (!dma_desc) {
--              dev_err(nandc->dev, "failed to prepare desc\n");
--              ret = -EINVAL;
--              goto err;
--      }
--
--      desc->dma_desc = dma_desc;
--
--      list_add_tail(&desc->node, &nandc->desc_list);
--
--      return 0;
--err:
--      kfree(desc);
--
--      return ret;
--}
--
--/*
-- * qcom_read_reg_dma: prepares a descriptor to read a given number of
-- *                    contiguous registers to the reg_read_buf pointer
-- *
-- * @first:            offset of the first register in the contiguous block
-- * @num_regs:         number of registers to read
-- * @flags:            flags to control DMA descriptor preparation
-- */
--static int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first,
--                           int num_regs, unsigned int flags)
--{
--      bool flow_control = false;
--      void *vaddr;
--
--      vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
--      nandc->reg_read_pos += num_regs;
--
--      if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1)
--              first = dev_cmd_reg_addr(nandc, first);
--
--      if (nandc->props->supports_bam)
--              return qcom_prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
--                                           num_regs, flags);
--
--      if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
--              flow_control = true;
--
--      return qcom_prep_adm_dma_desc(nandc, true, first, vaddr,
--                               num_regs * sizeof(u32), flow_control);
--}
--
--/*
-- * qcom_write_reg_dma:        prepares a descriptor to write a given number of
-- *                    contiguous registers
-- *
-- * @vaddr:            contiguous memory from where register value will
-- *                    be written
-- * @first:            offset of the first register in the contiguous block
-- * @num_regs:         number of registers to write
-- * @flags:            flags to control DMA descriptor preparation
-- */
--static int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
--                            int first, int num_regs, unsigned int flags)
--{
--      bool flow_control = false;
--
--      if (first == NAND_EXEC_CMD)
--              flags |= NAND_BAM_NWD;
--
--      if (first == NAND_DEV_CMD1_RESTORE || first == NAND_DEV_CMD1)
--              first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD1);
--
--      if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD)
--              first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD);
--
--      if (nandc->props->supports_bam)
--              return qcom_prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
--                                           num_regs, flags);
--
--      if (first == NAND_FLASH_CMD)
--              flow_control = true;
--
--      return qcom_prep_adm_dma_desc(nandc, false, first, vaddr,
--                               num_regs * sizeof(u32), flow_control);
--}
--
--/*
-- * qcom_read_data_dma:        prepares a DMA descriptor to transfer data from the
-- *                    controller's internal buffer to the buffer 'vaddr'
-- *
-- * @reg_off:          offset within the controller's data buffer
-- * @vaddr:            virtual address of the buffer we want to write to
-- * @size:             DMA transaction size in bytes
-- * @flags:            flags to control DMA descriptor preparation
-- */
--static int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
--                            const u8 *vaddr, int size, unsigned int flags)
--{
--      if (nandc->props->supports_bam)
--              return qcom_prep_bam_dma_desc_data(nandc, true, vaddr, size, flags);
--
--      return qcom_prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
--}
--
--/*
-- * qcom_write_data_dma:       prepares a DMA descriptor to transfer data from
-- *                    'vaddr' to the controller's internal buffer
-- *
-- * @reg_off:          offset within the controller's data buffer
-- * @vaddr:            virtual address of the buffer we want to read from
-- * @size:             DMA transaction size in bytes
-- * @flags:            flags to control DMA descriptor preparation
-- */
--static int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
--                             const u8 *vaddr, int size, unsigned int flags)
--{
--      if (nandc->props->supports_bam)
--              return qcom_prep_bam_dma_desc_data(nandc, false, vaddr, size, flags);
--
--      return qcom_prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
--}
--
--/*
-  * Helper to prepare DMA descriptors for configuring registers
-  * before reading a NAND page.
-  */
-@@ -1262,83 +394,6 @@ static void config_nand_cw_write(struct
-                          NAND_BAM_NEXT_SGL);
- }
--/* helpers to submit/free our list of dma descriptors */
--static int qcom_submit_descs(struct qcom_nand_controller *nandc)
--{
--      struct desc_info *desc, *n;
--      dma_cookie_t cookie = 0;
--      struct bam_transaction *bam_txn = nandc->bam_txn;
--      int ret = 0;
--
--      if (nandc->props->supports_bam) {
--              if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) {
--                      ret = qcom_prepare_bam_async_desc(nandc, nandc->rx_chan, 0);
--                      if (ret)
--                              goto err_unmap_free_desc;
--              }
--
--              if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) {
--                      ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan,
--                                                        DMA_PREP_INTERRUPT);
--                      if (ret)
--                              goto err_unmap_free_desc;
--              }
--
--              if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) {
--                      ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan,
--                                                        DMA_PREP_CMD);
--                      if (ret)
--                              goto err_unmap_free_desc;
--              }
--      }
--
--      list_for_each_entry(desc, &nandc->desc_list, node)
--              cookie = dmaengine_submit(desc->dma_desc);
--
--      if (nandc->props->supports_bam) {
--              bam_txn->last_cmd_desc->callback = qcom_qpic_bam_dma_done;
--              bam_txn->last_cmd_desc->callback_param = bam_txn;
--
--              dma_async_issue_pending(nandc->tx_chan);
--              dma_async_issue_pending(nandc->rx_chan);
--              dma_async_issue_pending(nandc->cmd_chan);
--
--              if (!wait_for_completion_timeout(&bam_txn->txn_done,
--                                               QPIC_NAND_COMPLETION_TIMEOUT))
--                      ret = -ETIMEDOUT;
--      } else {
--              if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE)
--                      ret = -ETIMEDOUT;
--      }
--
--err_unmap_free_desc:
--      /*
--       * Unmap the dma sg_list and free the desc allocated by both
--       * qcom_prepare_bam_async_desc() and qcom_prep_adm_dma_desc() functions.
--       */
--      list_for_each_entry_safe(desc, n, &nandc->desc_list, node) {
--              list_del(&desc->node);
--
--              if (nandc->props->supports_bam)
--                      dma_unmap_sg(nandc->dev, desc->bam_sgl,
--                                   desc->sgl_cnt, desc->dir);
--              else
--                      dma_unmap_sg(nandc->dev, &desc->adm_sgl, 1,
--                                   desc->dir);
--
--              kfree(desc);
--      }
--
--      return ret;
--}
--
--/* reset the register read buffer for next NAND operation */
--static void qcom_clear_read_regs(struct qcom_nand_controller *nandc)
--{
--      nandc->reg_read_pos = 0;
--      qcom_nandc_dev_to_mem(nandc, false);
--}
--
- /*
-  * when using BCH ECC, the HW flags an error in NAND_FLASH_STATUS if it read
-  * an erased CW, and reports an erased CW in NAND_ERASED_CW_DETECT_STATUS.
-@@ -2975,141 +2030,14 @@ static const struct nand_controller_ops
-       .exec_op = qcom_nand_exec_op,
- };
--static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
--{
--      if (nandc->props->supports_bam) {
--              if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma))
--                      dma_unmap_single(nandc->dev, nandc->reg_read_dma,
--                                       MAX_REG_RD *
--                                       sizeof(*nandc->reg_read_buf),
--                                       DMA_FROM_DEVICE);
--
--              if (nandc->tx_chan)
--                      dma_release_channel(nandc->tx_chan);
--
--              if (nandc->rx_chan)
--                      dma_release_channel(nandc->rx_chan);
--
--              if (nandc->cmd_chan)
--                      dma_release_channel(nandc->cmd_chan);
--      } else {
--              if (nandc->chan)
--                      dma_release_channel(nandc->chan);
--      }
--}
--
--static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
--{
--      int ret;
--
--      ret = dma_set_coherent_mask(nandc->dev, DMA_BIT_MASK(32));
--      if (ret) {
--              dev_err(nandc->dev, "failed to set DMA mask\n");
--              return ret;
--      }
--
--      /*
--       * we use the internal buffer for reading ONFI params, reading small
--       * data like ID and status, and preforming read-copy-write operations
--       * when writing to a codeword partially. 532 is the maximum possible
--       * size of a codeword for our nand controller
--       */
--      nandc->buf_size = 532;
--
--      nandc->data_buffer = devm_kzalloc(nandc->dev, nandc->buf_size, GFP_KERNEL);
--      if (!nandc->data_buffer)
--              return -ENOMEM;
--
--      nandc->regs = devm_kzalloc(nandc->dev, sizeof(*nandc->regs), GFP_KERNEL);
--      if (!nandc->regs)
--              return -ENOMEM;
--
--      nandc->reg_read_buf = devm_kcalloc(nandc->dev, MAX_REG_RD,
--                                         sizeof(*nandc->reg_read_buf),
--                                         GFP_KERNEL);
--      if (!nandc->reg_read_buf)
--              return -ENOMEM;
--
--      if (nandc->props->supports_bam) {
--              nandc->reg_read_dma =
--                      dma_map_single(nandc->dev, nandc->reg_read_buf,
--                                     MAX_REG_RD *
--                                     sizeof(*nandc->reg_read_buf),
--                                     DMA_FROM_DEVICE);
--              if (dma_mapping_error(nandc->dev, nandc->reg_read_dma)) {
--                      dev_err(nandc->dev, "failed to DMA MAP reg buffer\n");
--                      return -EIO;
--              }
--
--              nandc->tx_chan = dma_request_chan(nandc->dev, "tx");
--              if (IS_ERR(nandc->tx_chan)) {
--                      ret = PTR_ERR(nandc->tx_chan);
--                      nandc->tx_chan = NULL;
--                      dev_err_probe(nandc->dev, ret,
--                                    "tx DMA channel request failed\n");
--                      goto unalloc;
--              }
--
--              nandc->rx_chan = dma_request_chan(nandc->dev, "rx");
--              if (IS_ERR(nandc->rx_chan)) {
--                      ret = PTR_ERR(nandc->rx_chan);
--                      nandc->rx_chan = NULL;
--                      dev_err_probe(nandc->dev, ret,
--                                    "rx DMA channel request failed\n");
--                      goto unalloc;
--              }
--
--              nandc->cmd_chan = dma_request_chan(nandc->dev, "cmd");
--              if (IS_ERR(nandc->cmd_chan)) {
--                      ret = PTR_ERR(nandc->cmd_chan);
--                      nandc->cmd_chan = NULL;
--                      dev_err_probe(nandc->dev, ret,
--                                    "cmd DMA channel request failed\n");
--                      goto unalloc;
--              }
--
--              /*
--               * Initially allocate BAM transaction to read ONFI param page.
--               * After detecting all the devices, this BAM transaction will
--               * be freed and the next BAM transaction will be allocated with
--               * maximum codeword size
--               */
--              nandc->max_cwperpage = 1;
--              nandc->bam_txn = qcom_alloc_bam_transaction(nandc);
--              if (!nandc->bam_txn) {
--                      dev_err(nandc->dev,
--                              "failed to allocate bam transaction\n");
--                      ret = -ENOMEM;
--                      goto unalloc;
--              }
--      } else {
--              nandc->chan = dma_request_chan(nandc->dev, "rxtx");
--              if (IS_ERR(nandc->chan)) {
--                      ret = PTR_ERR(nandc->chan);
--                      nandc->chan = NULL;
--                      dev_err_probe(nandc->dev, ret,
--                                    "rxtx DMA channel request failed\n");
--                      return ret;
--              }
--      }
--
--      INIT_LIST_HEAD(&nandc->desc_list);
--      INIT_LIST_HEAD(&nandc->host_list);
--
--      nand_controller_init(&nandc->controller);
--      nandc->controller.ops = &qcom_nandc_ops;
--
--      return 0;
--unalloc:
--      qcom_nandc_unalloc(nandc);
--      return ret;
--}
--
- /* one time setup of a few nand controller registers */
- static int qcom_nandc_setup(struct qcom_nand_controller *nandc)
- {
-       u32 nand_ctrl;
-+      nand_controller_init(nandc->controller);
-+      nandc->controller->ops = &qcom_nandc_ops;
-+
-       /* kill onenand */
-       if (!nandc->props->nandc_part_of_qpic)
-               nandc_write(nandc, SFLASHC_BURST_CFG, 0);
-@@ -3248,7 +2176,7 @@ static int qcom_nand_host_init_and_regis
-       chip->legacy.block_bad          = qcom_nandc_block_bad;
-       chip->legacy.block_markbad      = qcom_nandc_block_markbad;
--      chip->controller = &nandc->controller;
-+      chip->controller = nandc->controller;
-       chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA |
-                        NAND_SKIP_BBTSCAN;
-@@ -3331,17 +2259,21 @@ static int qcom_nandc_parse_dt(struct pl
- static int qcom_nandc_probe(struct platform_device *pdev)
- {
-       struct qcom_nand_controller *nandc;
-+      struct nand_controller *controller;
-       const void *dev_data;
-       struct device *dev = &pdev->dev;
-       struct resource *res;
-       int ret;
--      nandc = devm_kzalloc(&pdev->dev, sizeof(*nandc), GFP_KERNEL);
-+      nandc = devm_kzalloc(&pdev->dev, sizeof(*nandc) + sizeof(*controller),
-+                           GFP_KERNEL);
-       if (!nandc)
-               return -ENOMEM;
-+      controller = (struct nand_controller *)&nandc[1];
-       platform_set_drvdata(pdev, nandc);
-       nandc->dev = dev;
-+      nandc->controller = controller;
-       dev_data = of_device_get_match_data(dev);
-       if (!dev_data) {
---- /dev/null
-+++ b/include/linux/mtd/nand-qpic-common.h
-@@ -0,0 +1,468 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * QCOM QPIC common APIs header file
-+ *
-+ * Copyright (c) 2023 Qualcomm Inc.
-+ * Authors:   Md sadre Alam   <quic_mdalam@quicinc.com>
-+ *
-+ */
-+#ifndef __MTD_NAND_QPIC_COMMON_H__
-+#define __MTD_NAND_QPIC_COMMON_H__
-+
-+/* NANDc reg offsets */
-+#define       NAND_FLASH_CMD                  0x00
-+#define       NAND_ADDR0                      0x04
-+#define       NAND_ADDR1                      0x08
-+#define       NAND_FLASH_CHIP_SELECT          0x0c
-+#define       NAND_EXEC_CMD                   0x10
-+#define       NAND_FLASH_STATUS               0x14
-+#define       NAND_BUFFER_STATUS              0x18
-+#define       NAND_DEV0_CFG0                  0x20
-+#define       NAND_DEV0_CFG1                  0x24
-+#define       NAND_DEV0_ECC_CFG               0x28
-+#define       NAND_AUTO_STATUS_EN             0x2c
-+#define       NAND_DEV1_CFG0                  0x30
-+#define       NAND_DEV1_CFG1                  0x34
-+#define       NAND_READ_ID                    0x40
-+#define       NAND_READ_STATUS                0x44
-+#define       NAND_DEV_CMD0                   0xa0
-+#define       NAND_DEV_CMD1                   0xa4
-+#define       NAND_DEV_CMD2                   0xa8
-+#define       NAND_DEV_CMD_VLD                0xac
-+#define       SFLASHC_BURST_CFG               0xe0
-+#define       NAND_ERASED_CW_DETECT_CFG       0xe8
-+#define       NAND_ERASED_CW_DETECT_STATUS    0xec
-+#define       NAND_EBI2_ECC_BUF_CFG           0xf0
-+#define       FLASH_BUF_ACC                   0x100
-+
-+#define       NAND_CTRL                       0xf00
-+#define       NAND_VERSION                    0xf08
-+#define       NAND_READ_LOCATION_0            0xf20
-+#define       NAND_READ_LOCATION_1            0xf24
-+#define       NAND_READ_LOCATION_2            0xf28
-+#define       NAND_READ_LOCATION_3            0xf2c
-+#define       NAND_READ_LOCATION_LAST_CW_0    0xf40
-+#define       NAND_READ_LOCATION_LAST_CW_1    0xf44
-+#define       NAND_READ_LOCATION_LAST_CW_2    0xf48
-+#define       NAND_READ_LOCATION_LAST_CW_3    0xf4c
-+
-+/* dummy register offsets, used by qcom_write_reg_dma */
-+#define       NAND_DEV_CMD1_RESTORE           0xdead
-+#define       NAND_DEV_CMD_VLD_RESTORE        0xbeef
-+
-+/* NAND_FLASH_CMD bits */
-+#define       PAGE_ACC                        BIT(4)
-+#define       LAST_PAGE                       BIT(5)
-+
-+/* NAND_FLASH_CHIP_SELECT bits */
-+#define       NAND_DEV_SEL                    0
-+#define       DM_EN                           BIT(2)
-+
-+/* NAND_FLASH_STATUS bits */
-+#define       FS_OP_ERR                       BIT(4)
-+#define       FS_READY_BSY_N                  BIT(5)
-+#define       FS_MPU_ERR                      BIT(8)
-+#define       FS_DEVICE_STS_ERR               BIT(16)
-+#define       FS_DEVICE_WP                    BIT(23)
-+
-+/* NAND_BUFFER_STATUS bits */
-+#define       BS_UNCORRECTABLE_BIT            BIT(8)
-+#define       BS_CORRECTABLE_ERR_MSK          0x1f
-+
-+/* NAND_DEVn_CFG0 bits */
-+#define       DISABLE_STATUS_AFTER_WRITE      4
-+#define       CW_PER_PAGE                     6
-+#define       UD_SIZE_BYTES                   9
-+#define       UD_SIZE_BYTES_MASK              GENMASK(18, 9)
-+#define       ECC_PARITY_SIZE_BYTES_RS        19
-+#define       SPARE_SIZE_BYTES                23
-+#define       SPARE_SIZE_BYTES_MASK           GENMASK(26, 23)
-+#define       NUM_ADDR_CYCLES                 27
-+#define       STATUS_BFR_READ                 30
-+#define       SET_RD_MODE_AFTER_STATUS        31
-+
-+/* NAND_DEVn_CFG0 bits */
-+#define       DEV0_CFG1_ECC_DISABLE           0
-+#define       WIDE_FLASH                      1
-+#define       NAND_RECOVERY_CYCLES            2
-+#define       CS_ACTIVE_BSY                   5
-+#define       BAD_BLOCK_BYTE_NUM              6
-+#define       BAD_BLOCK_IN_SPARE_AREA         16
-+#define       WR_RD_BSY_GAP                   17
-+#define       ENABLE_BCH_ECC                  27
-+
-+/* NAND_DEV0_ECC_CFG bits */
-+#define       ECC_CFG_ECC_DISABLE             0
-+#define       ECC_SW_RESET                    1
-+#define       ECC_MODE                        4
-+#define       ECC_PARITY_SIZE_BYTES_BCH       8
-+#define       ECC_NUM_DATA_BYTES              16
-+#define       ECC_NUM_DATA_BYTES_MASK         GENMASK(25, 16)
-+#define       ECC_FORCE_CLK_OPEN              30
-+
-+/* NAND_DEV_CMD1 bits */
-+#define       READ_ADDR                       0
-+
-+/* NAND_DEV_CMD_VLD bits */
-+#define       READ_START_VLD                  BIT(0)
-+#define       READ_STOP_VLD                   BIT(1)
-+#define       WRITE_START_VLD                 BIT(2)
-+#define       ERASE_START_VLD                 BIT(3)
-+#define       SEQ_READ_START_VLD              BIT(4)
-+
-+/* NAND_EBI2_ECC_BUF_CFG bits */
-+#define       NUM_STEPS                       0
-+
-+/* NAND_ERASED_CW_DETECT_CFG bits */
-+#define       ERASED_CW_ECC_MASK              1
-+#define       AUTO_DETECT_RES                 0
-+#define       MASK_ECC                        BIT(ERASED_CW_ECC_MASK)
-+#define       RESET_ERASED_DET                BIT(AUTO_DETECT_RES)
-+#define       ACTIVE_ERASED_DET               (0 << AUTO_DETECT_RES)
-+#define       CLR_ERASED_PAGE_DET             (RESET_ERASED_DET | MASK_ECC)
-+#define       SET_ERASED_PAGE_DET             (ACTIVE_ERASED_DET | MASK_ECC)
-+
-+/* NAND_ERASED_CW_DETECT_STATUS bits */
-+#define       PAGE_ALL_ERASED                 BIT(7)
-+#define       CODEWORD_ALL_ERASED             BIT(6)
-+#define       PAGE_ERASED                     BIT(5)
-+#define       CODEWORD_ERASED                 BIT(4)
-+#define       ERASED_PAGE                     (PAGE_ALL_ERASED | PAGE_ERASED)
-+#define       ERASED_CW                       (CODEWORD_ALL_ERASED | CODEWORD_ERASED)
-+
-+/* NAND_READ_LOCATION_n bits */
-+#define READ_LOCATION_OFFSET          0
-+#define READ_LOCATION_SIZE            16
-+#define READ_LOCATION_LAST            31
-+
-+/* Version Mask */
-+#define       NAND_VERSION_MAJOR_MASK         0xf0000000
-+#define       NAND_VERSION_MAJOR_SHIFT        28
-+#define       NAND_VERSION_MINOR_MASK         0x0fff0000
-+#define       NAND_VERSION_MINOR_SHIFT        16
-+
-+/* NAND OP_CMDs */
-+#define       OP_PAGE_READ                    0x2
-+#define       OP_PAGE_READ_WITH_ECC           0x3
-+#define       OP_PAGE_READ_WITH_ECC_SPARE     0x4
-+#define       OP_PAGE_READ_ONFI_READ          0x5
-+#define       OP_PROGRAM_PAGE                 0x6
-+#define       OP_PAGE_PROGRAM_WITH_ECC        0x7
-+#define       OP_PROGRAM_PAGE_SPARE           0x9
-+#define       OP_BLOCK_ERASE                  0xa
-+#define       OP_CHECK_STATUS                 0xc
-+#define       OP_FETCH_ID                     0xb
-+#define       OP_RESET_DEVICE                 0xd
-+
-+/* Default Value for NAND_DEV_CMD_VLD */
-+#define NAND_DEV_CMD_VLD_VAL          (READ_START_VLD | WRITE_START_VLD | \
-+                                       ERASE_START_VLD | SEQ_READ_START_VLD)
-+
-+/* NAND_CTRL bits */
-+#define       BAM_MODE_EN                     BIT(0)
-+
-+/*
-+ * the NAND controller performs reads/writes with ECC in 516 byte chunks.
-+ * the driver calls the chunks 'step' or 'codeword' interchangeably
-+ */
-+#define       NANDC_STEP_SIZE                 512
-+
-+/*
-+ * the largest page size we support is 8K, this will have 16 steps/codewords
-+ * of 512 bytes each
-+ */
-+#define       MAX_NUM_STEPS                   (SZ_8K / NANDC_STEP_SIZE)
-+
-+/* we read at most 3 registers per codeword scan */
-+#define       MAX_REG_RD                      (3 * MAX_NUM_STEPS)
-+
-+/* ECC modes supported by the controller */
-+#define       ECC_NONE        BIT(0)
-+#define       ECC_RS_4BIT     BIT(1)
-+#define       ECC_BCH_4BIT    BIT(2)
-+#define       ECC_BCH_8BIT    BIT(3)
-+
-+/*
-+ * Returns the actual register address for all NAND_DEV_ registers
-+ * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD)
-+ */
-+#define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg))
-+
-+/* Returns the NAND register physical address */
-+#define nandc_reg_phys(chip, offset) ((chip)->base_phys + (offset))
-+
-+/* Returns the dma address for reg read buffer */
-+#define reg_buf_dma_addr(chip, vaddr) \
-+      ((chip)->reg_read_dma + \
-+      ((u8 *)(vaddr) - (u8 *)(chip)->reg_read_buf))
-+
-+#define QPIC_PER_CW_CMD_ELEMENTS      32
-+#define QPIC_PER_CW_CMD_SGL           32
-+#define QPIC_PER_CW_DATA_SGL          8
-+
-+#define QPIC_NAND_COMPLETION_TIMEOUT  msecs_to_jiffies(2000)
-+
-+/*
-+ * Flags used in DMA descriptor preparation helper functions
-+ * (i.e. qcom_read_reg_dma/qcom_write_reg_dma/qcom_read_data_dma/qcom_write_data_dma)
-+ */
-+/* Don't set the EOT in current tx BAM sgl */
-+#define NAND_BAM_NO_EOT                       BIT(0)
-+/* Set the NWD flag in current BAM sgl */
-+#define NAND_BAM_NWD                  BIT(1)
-+/* Finish writing in the current BAM sgl and start writing in another BAM sgl */
-+#define NAND_BAM_NEXT_SGL             BIT(2)
-+/*
-+ * Erased codeword status is being used two times in single transfer so this
-+ * flag will determine the current value of erased codeword status register
-+ */
-+#define NAND_ERASED_CW_SET            BIT(4)
-+
-+#define MAX_ADDRESS_CYCLE             5
-+
-+/*
-+ * This data type corresponds to the BAM transaction which will be used for all
-+ * NAND transfers.
-+ * @bam_ce - the array of BAM command elements
-+ * @cmd_sgl - sgl for NAND BAM command pipe
-+ * @data_sgl - sgl for NAND BAM consumer/producer pipe
-+ * @last_data_desc - last DMA desc in data channel (tx/rx).
-+ * @last_cmd_desc - last DMA desc in command channel.
-+ * @txn_done - completion for NAND transfer.
-+ * @bam_ce_pos - the index in bam_ce which is available for next sgl
-+ * @bam_ce_start - the index in bam_ce which marks the start position ce
-+ *               for current sgl. It will be used for size calculation
-+ *               for current sgl
-+ * @cmd_sgl_pos - current index in command sgl.
-+ * @cmd_sgl_start - start index in command sgl.
-+ * @tx_sgl_pos - current index in data sgl for tx.
-+ * @tx_sgl_start - start index in data sgl for tx.
-+ * @rx_sgl_pos - current index in data sgl for rx.
-+ * @rx_sgl_start - start index in data sgl for rx.
-+ */
-+struct bam_transaction {
-+      struct bam_cmd_element *bam_ce;
-+      struct scatterlist *cmd_sgl;
-+      struct scatterlist *data_sgl;
-+      struct dma_async_tx_descriptor *last_data_desc;
-+      struct dma_async_tx_descriptor *last_cmd_desc;
-+      struct completion txn_done;
-+      u32 bam_ce_pos;
-+      u32 bam_ce_start;
-+      u32 cmd_sgl_pos;
-+      u32 cmd_sgl_start;
-+      u32 tx_sgl_pos;
-+      u32 tx_sgl_start;
-+      u32 rx_sgl_pos;
-+      u32 rx_sgl_start;
-+};
-+
-+/*
-+ * This data type corresponds to the nand dma descriptor
-+ * @dma_desc - low level DMA engine descriptor
-+ * @list - list for desc_info
-+ *
-+ * @adm_sgl - sgl which will be used for single sgl dma descriptor. Only used by
-+ *          ADM
-+ * @bam_sgl - sgl which will be used for dma descriptor. Only used by BAM
-+ * @sgl_cnt - number of SGL in bam_sgl. Only used by BAM
-+ * @dir - DMA transfer direction
-+ */
-+struct desc_info {
-+      struct dma_async_tx_descriptor *dma_desc;
-+      struct list_head node;
-+
-+      union {
-+              struct scatterlist adm_sgl;
-+              struct {
-+                      struct scatterlist *bam_sgl;
-+                      int sgl_cnt;
-+              };
-+      };
-+      enum dma_data_direction dir;
-+};
-+
-+/*
-+ * holds the current register values that we want to write. acts as a contiguous
-+ * chunk of memory which we use to write the controller registers through DMA.
-+ */
-+struct nandc_regs {
-+      __le32 cmd;
-+      __le32 addr0;
-+      __le32 addr1;
-+      __le32 chip_sel;
-+      __le32 exec;
-+
-+      __le32 cfg0;
-+      __le32 cfg1;
-+      __le32 ecc_bch_cfg;
-+
-+      __le32 clrflashstatus;
-+      __le32 clrreadstatus;
-+
-+      __le32 cmd1;
-+      __le32 vld;
-+
-+      __le32 orig_cmd1;
-+      __le32 orig_vld;
-+
-+      __le32 ecc_buf_cfg;
-+      __le32 read_location0;
-+      __le32 read_location1;
-+      __le32 read_location2;
-+      __le32 read_location3;
-+      __le32 read_location_last0;
-+      __le32 read_location_last1;
-+      __le32 read_location_last2;
-+      __le32 read_location_last3;
-+
-+      __le32 erased_cw_detect_cfg_clr;
-+      __le32 erased_cw_detect_cfg_set;
-+};
-+
-+/*
-+ * NAND controller data struct
-+ *
-+ * @dev:                      parent device
-+ *
-+ * @base:                     MMIO base
-+ *
-+ * @core_clk:                 controller clock
-+ * @aon_clk:                  another controller clock
-+ *
-+ * @regs:                     a contiguous chunk of memory for DMA register
-+ *                            writes. contains the register values to be
-+ *                            written to controller
-+ *
-+ * @props:                    properties of current NAND controller,
-+ *                            initialized via DT match data
-+ *
-+ * @controller:                       base controller structure
-+ * @host_list:                        list containing all the chips attached to the
-+ *                            controller
-+ *
-+ * @chan:                     dma channel
-+ * @cmd_crci:                 ADM DMA CRCI for command flow control
-+ * @data_crci:                        ADM DMA CRCI for data flow control
-+ *
-+ * @desc_list:                        DMA descriptor list (list of desc_infos)
-+ *
-+ * @data_buffer:              our local DMA buffer for page read/writes,
-+ *                            used when we can't use the buffer provided
-+ *                            by upper layers directly
-+ * @reg_read_buf:             local buffer for reading back registers via DMA
-+ *
-+ * @base_phys:                        physical base address of controller registers
-+ * @base_dma:                 dma base address of controller registers
-+ * @reg_read_dma:             contains dma address for register read buffer
-+ *
-+ * @buf_size/count/start:     markers for chip->legacy.read_buf/write_buf
-+ *                            functions
-+ * @max_cwperpage:            maximum QPIC codewords required. calculated
-+ *                            from all connected NAND devices pagesize
-+ *
-+ * @reg_read_pos:             marker for data read in reg_read_buf
-+ *
-+ * @cmd1/vld:                 some fixed controller register values
-+ *
-+ * @exec_opwrite:             flag to select correct number of code word
-+ *                            while reading status
-+ */
-+struct qcom_nand_controller {
-+      struct device *dev;
-+
-+      void __iomem *base;
-+
-+      struct clk *core_clk;
-+      struct clk *aon_clk;
-+
-+      struct nandc_regs *regs;
-+      struct bam_transaction *bam_txn;
-+
-+      const struct qcom_nandc_props *props;
-+
-+      struct nand_controller *controller;
-+      struct list_head host_list;
-+
-+      union {
-+              /* will be used only by QPIC for BAM DMA */
-+              struct {
-+                      struct dma_chan *tx_chan;
-+                      struct dma_chan *rx_chan;
-+                      struct dma_chan *cmd_chan;
-+              };
-+
-+              /* will be used only by EBI2 for ADM DMA */
-+              struct {
-+                      struct dma_chan *chan;
-+                      unsigned int cmd_crci;
-+                      unsigned int data_crci;
-+              };
-+      };
-+
-+      struct list_head desc_list;
-+
-+      u8              *data_buffer;
-+      __le32          *reg_read_buf;
-+
-+      phys_addr_t base_phys;
-+      dma_addr_t base_dma;
-+      dma_addr_t reg_read_dma;
-+
-+      int             buf_size;
-+      int             buf_count;
-+      int             buf_start;
-+      unsigned int    max_cwperpage;
-+
-+      int reg_read_pos;
-+
-+      u32 cmd1, vld;
-+      bool exec_opwrite;
-+};
-+
-+/*
-+ * This data type corresponds to the NAND controller properties which varies
-+ * among different NAND controllers.
-+ * @ecc_modes - ecc mode for NAND
-+ * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset
-+ * @supports_bam - whether NAND controller is using BAM
-+ * @nandc_part_of_qpic - whether NAND controller is part of qpic IP
-+ * @qpic_version2 - flag to indicate QPIC IP version 2
-+ * @use_codeword_fixup - whether NAND has different layout for boot partitions
-+ */
-+struct qcom_nandc_props {
-+      u32 ecc_modes;
-+      u32 dev_cmd_reg_start;
-+      bool supports_bam;
-+      bool nandc_part_of_qpic;
-+      bool qpic_version2;
-+      bool use_codeword_fixup;
-+};
-+
-+void qcom_free_bam_transaction(struct qcom_nand_controller *nandc);
-+struct bam_transaction *qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc);
-+void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc);
-+void qcom_qpic_bam_dma_done(void *data);
-+void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu);
-+int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc,
-+                              struct dma_chan *chan, unsigned long flags);
-+int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
-+                             int reg_off, const void *vaddr, int size, unsigned int flags);
-+int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
-+                              const void *vaddr, int size, unsigned int flags);
-+int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, int reg_off,
-+                         const void *vaddr, int size, bool flow_control);
-+int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first, int num_regs,
-+                    unsigned int flags);
-+int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, int first,
-+                     int num_regs, unsigned int flags);
-+int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off, const u8 *vaddr,
-+                     int size, unsigned int flags);
-+int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off, const u8 *vaddr,
-+                      int size, unsigned int flags);
-+int qcom_submit_descs(struct qcom_nand_controller *nandc);
-+void qcom_clear_read_regs(struct qcom_nand_controller *nandc);
-+void qcom_nandc_unalloc(struct qcom_nand_controller *nandc);
-+int qcom_nandc_alloc(struct qcom_nand_controller *nandc);
-+#endif
-+
diff --git a/target/linux/generic/backport-6.18/410-04-v6.14-mtd-rawnand-qcom-use-FIELD_PREP-and-GENMASK.patch b/target/linux/generic/backport-6.18/410-04-v6.14-mtd-rawnand-qcom-use-FIELD_PREP-and-GENMASK.patch
deleted file mode 100644 (file)
index c19f681..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-From 0c08080fd71cd5dd59643104b39d3c89d793ab3c Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Wed, 20 Nov 2024 14:45:03 +0530
-Subject: [PATCH 4/4] mtd: rawnand: qcom: use FIELD_PREP and GENMASK
-
-Use the bitfield macro FIELD_PREP, and GENMASK to
-do the shift and mask in one go. This makes the code
-more readable.
-
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/raw/qcom_nandc.c    | 97 ++++++++++++++--------------
- include/linux/mtd/nand-qpic-common.h | 31 +++++----
- 2 files changed, 67 insertions(+), 61 deletions(-)
-
---- a/drivers/mtd/nand/raw/qcom_nandc.c
-+++ b/drivers/mtd/nand/raw/qcom_nandc.c
-@@ -281,7 +281,7 @@ static void update_rw_regs(struct qcom_n
-                               (num_cw - 1) << CW_PER_PAGE);
-               cfg1 = cpu_to_le32(host->cfg1_raw);
--              ecc_bch_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE);
-+              ecc_bch_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE);
-       }
-       nandc->regs->cmd = cmd;
-@@ -1494,42 +1494,41 @@ static int qcom_nand_attach_chip(struct
-       host->cw_size = host->cw_data + ecc->bytes;
-       bad_block_byte = mtd->writesize - host->cw_size * (cwperpage - 1) + 1;
--      host->cfg0 = (cwperpage - 1) << CW_PER_PAGE
--                              | host->cw_data << UD_SIZE_BYTES
--                              | 0 << DISABLE_STATUS_AFTER_WRITE
--                              | 5 << NUM_ADDR_CYCLES
--                              | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_RS
--                              | 0 << STATUS_BFR_READ
--                              | 1 << SET_RD_MODE_AFTER_STATUS
--                              | host->spare_bytes << SPARE_SIZE_BYTES;
--
--      host->cfg1 = 7 << NAND_RECOVERY_CYCLES
--                              | 0 <<  CS_ACTIVE_BSY
--                              | bad_block_byte << BAD_BLOCK_BYTE_NUM
--                              | 0 << BAD_BLOCK_IN_SPARE_AREA
--                              | 2 << WR_RD_BSY_GAP
--                              | wide_bus << WIDE_FLASH
--                              | host->bch_enabled << ENABLE_BCH_ECC;
--
--      host->cfg0_raw = (cwperpage - 1) << CW_PER_PAGE
--                              | host->cw_size << UD_SIZE_BYTES
--                              | 5 << NUM_ADDR_CYCLES
--                              | 0 << SPARE_SIZE_BYTES;
--
--      host->cfg1_raw = 7 << NAND_RECOVERY_CYCLES
--                              | 0 << CS_ACTIVE_BSY
--                              | 17 << BAD_BLOCK_BYTE_NUM
--                              | 1 << BAD_BLOCK_IN_SPARE_AREA
--                              | 2 << WR_RD_BSY_GAP
--                              | wide_bus << WIDE_FLASH
--                              | 1 << DEV0_CFG1_ECC_DISABLE;
--
--      host->ecc_bch_cfg = !host->bch_enabled << ECC_CFG_ECC_DISABLE
--                              | 0 << ECC_SW_RESET
--                              | host->cw_data << ECC_NUM_DATA_BYTES
--                              | 1 << ECC_FORCE_CLK_OPEN
--                              | ecc_mode << ECC_MODE
--                              | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_BCH;
-+      host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
-+                   FIELD_PREP(UD_SIZE_BYTES_MASK, host->cw_data) |
-+                   FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 0) |
-+                   FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
-+                   FIELD_PREP(ECC_PARITY_SIZE_BYTES_RS, host->ecc_bytes_hw) |
-+                   FIELD_PREP(STATUS_BFR_READ, 0) |
-+                   FIELD_PREP(SET_RD_MODE_AFTER_STATUS, 1) |
-+                   FIELD_PREP(SPARE_SIZE_BYTES_MASK, host->spare_bytes);
-+
-+      host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
-+                   FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, bad_block_byte) |
-+                   FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 0) |
-+                   FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
-+                   FIELD_PREP(WIDE_FLASH, wide_bus) |
-+                   FIELD_PREP(ENABLE_BCH_ECC, host->bch_enabled);
-+
-+      host->cfg0_raw = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
-+                       FIELD_PREP(UD_SIZE_BYTES_MASK, host->cw_size) |
-+                       FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
-+                       FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0);
-+
-+      host->cfg1_raw = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
-+                       FIELD_PREP(CS_ACTIVE_BSY, 0) |
-+                       FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
-+                       FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
-+                       FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
-+                       FIELD_PREP(WIDE_FLASH, wide_bus) |
-+                       FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1);
-+
-+      host->ecc_bch_cfg = FIELD_PREP(ECC_CFG_ECC_DISABLE, !host->bch_enabled) |
-+                          FIELD_PREP(ECC_SW_RESET, 0) |
-+                          FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, host->cw_data) |
-+                          FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) |
-+                          FIELD_PREP(ECC_MODE_MASK, ecc_mode) |
-+                          FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, host->ecc_bytes_hw);
-       if (!nandc->props->qpic_version2)
-               host->ecc_buf_cfg = 0x203 << NUM_STEPS;
-@@ -1887,21 +1886,21 @@ static int qcom_param_page_type_exec(str
-       nandc->regs->addr0 = 0;
-       nandc->regs->addr1 = 0;
--      nandc->regs->cfg0 = cpu_to_le32(0 << CW_PER_PAGE |
--                                      512 << UD_SIZE_BYTES |
--                                      5 << NUM_ADDR_CYCLES |
--                                      0 << SPARE_SIZE_BYTES);
--
--      nandc->regs->cfg1 = cpu_to_le32(7 << NAND_RECOVERY_CYCLES |
--                                      0 << CS_ACTIVE_BSY |
--                                      17 << BAD_BLOCK_BYTE_NUM |
--                                      1 << BAD_BLOCK_IN_SPARE_AREA |
--                                      2 << WR_RD_BSY_GAP |
--                                      0 << WIDE_FLASH |
--                                      1 << DEV0_CFG1_ECC_DISABLE);
-+      host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, 0) |
-+                   FIELD_PREP(UD_SIZE_BYTES_MASK, 512) |
-+                   FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
-+                   FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0);
-+
-+      host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
-+                   FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
-+                   FIELD_PREP(CS_ACTIVE_BSY, 0) |
-+                   FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
-+                   FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
-+                   FIELD_PREP(WIDE_FLASH, 0) |
-+                   FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1);
-       if (!nandc->props->qpic_version2)
--              nandc->regs->ecc_buf_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE);
-+              nandc->regs->ecc_buf_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE);
-       /* configure CMD1 and VLD for ONFI param probing in QPIC v1 */
-       if (!nandc->props->qpic_version2) {
---- a/include/linux/mtd/nand-qpic-common.h
-+++ b/include/linux/mtd/nand-qpic-common.h
-@@ -70,35 +70,42 @@
- #define       BS_CORRECTABLE_ERR_MSK          0x1f
- /* NAND_DEVn_CFG0 bits */
--#define       DISABLE_STATUS_AFTER_WRITE      4
-+#define       DISABLE_STATUS_AFTER_WRITE      BIT(4)
- #define       CW_PER_PAGE                     6
-+#define       CW_PER_PAGE_MASK                GENMASK(8, 6)
- #define       UD_SIZE_BYTES                   9
- #define       UD_SIZE_BYTES_MASK              GENMASK(18, 9)
--#define       ECC_PARITY_SIZE_BYTES_RS        19
-+#define       ECC_PARITY_SIZE_BYTES_RS        GENMASK(22, 19)
- #define       SPARE_SIZE_BYTES                23
- #define       SPARE_SIZE_BYTES_MASK           GENMASK(26, 23)
- #define       NUM_ADDR_CYCLES                 27
--#define       STATUS_BFR_READ                 30
--#define       SET_RD_MODE_AFTER_STATUS        31
-+#define       NUM_ADDR_CYCLES_MASK            GENMASK(29, 27)
-+#define       STATUS_BFR_READ                 BIT(30)
-+#define       SET_RD_MODE_AFTER_STATUS        BIT(31)
- /* NAND_DEVn_CFG0 bits */
--#define       DEV0_CFG1_ECC_DISABLE           0
--#define       WIDE_FLASH                      1
-+#define       DEV0_CFG1_ECC_DISABLE           BIT(0)
-+#define       WIDE_FLASH                      BIT(1)
- #define       NAND_RECOVERY_CYCLES            2
--#define       CS_ACTIVE_BSY                   5
-+#define       NAND_RECOVERY_CYCLES_MASK       GENMASK(4, 2)
-+#define       CS_ACTIVE_BSY                   BIT(5)
- #define       BAD_BLOCK_BYTE_NUM              6
--#define       BAD_BLOCK_IN_SPARE_AREA         16
-+#define       BAD_BLOCK_BYTE_NUM_MASK         GENMASK(15, 6)
-+#define       BAD_BLOCK_IN_SPARE_AREA         BIT(16)
- #define       WR_RD_BSY_GAP                   17
--#define       ENABLE_BCH_ECC                  27
-+#define       WR_RD_BSY_GAP_MASK              GENMASK(22, 17)
-+#define       ENABLE_BCH_ECC                  BIT(27)
- /* NAND_DEV0_ECC_CFG bits */
--#define       ECC_CFG_ECC_DISABLE             0
--#define       ECC_SW_RESET                    1
-+#define       ECC_CFG_ECC_DISABLE             BIT(0)
-+#define       ECC_SW_RESET                    BIT(1)
- #define       ECC_MODE                        4
-+#define       ECC_MODE_MASK                   GENMASK(5, 4)
- #define       ECC_PARITY_SIZE_BYTES_BCH       8
-+#define       ECC_PARITY_SIZE_BYTES_BCH_MASK  GENMASK(12, 8)
- #define       ECC_NUM_DATA_BYTES              16
- #define       ECC_NUM_DATA_BYTES_MASK         GENMASK(25, 16)
--#define       ECC_FORCE_CLK_OPEN              30
-+#define       ECC_FORCE_CLK_OPEN              BIT(30)
- /* NAND_DEV_CMD1 bits */
- #define       READ_ADDR                       0
diff --git a/target/linux/generic/backport-6.18/410-05-v6.14-mtd-rawnand-qcom-fix-broken-config-in-qcom_param_pag.patch b/target/linux/generic/backport-6.18/410-05-v6.14-mtd-rawnand-qcom-fix-broken-config-in-qcom_param_pag.patch
deleted file mode 100644 (file)
index 238a1f9..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-From 9d4ffbcfde283f2a87ea45128ddf7e6651facdd9 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Fri, 7 Feb 2025 20:42:38 +0100
-Subject: [PATCH] mtd: rawnand: qcom: fix broken config in
- qcom_param_page_type_exec
-
-Fix broken config in qcom_param_page_type_exec caused by copy-paste error
-from commit 0c08080fd71c ("mtd: rawnand: qcom: use FIELD_PREP and GENMASK")
-
-In qcom_param_page_type_exec the value needs to be set to
-nandc->regs->cfg0 instead of host->cfg0. This wrong configuration caused
-the Qcom NANDC driver to malfunction on any device that makes use of it
-(IPQ806x, IPQ40xx, IPQ807x, IPQ60xx) with the following error:
-
-[    0.885369] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xaa
-[    0.885909] nand: Micron NAND 256MiB 1,8V 8-bit
-[    0.892499] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
-[    0.896823] nand: ECC (step, strength) = (512, 8) does not fit in OOB
-[    0.896836] qcom-nandc 79b0000.nand-controller: No valid ECC settings possible
-[    0.910996] bam-dma-engine 7984000.dma-controller: Cannot free busy channel
-[    0.918070] qcom-nandc: probe of 79b0000.nand-controller failed with error -28
-
-Restore original configuration fix the problem and makes the driver work
-again.
-
-Cc: stable@vger.kernel.org
-Fixes: 0c08080fd71c ("mtd: rawnand: qcom: use FIELD_PREP and GENMASK")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/mtd/nand/raw/qcom_nandc.c | 24 ++++++++++++------------
- 1 file changed, 12 insertions(+), 12 deletions(-)
-
---- a/drivers/mtd/nand/raw/qcom_nandc.c
-+++ b/drivers/mtd/nand/raw/qcom_nandc.c
-@@ -1886,18 +1886,18 @@ static int qcom_param_page_type_exec(str
-       nandc->regs->addr0 = 0;
-       nandc->regs->addr1 = 0;
--      host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, 0) |
--                   FIELD_PREP(UD_SIZE_BYTES_MASK, 512) |
--                   FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
--                   FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0);
-+      nandc->regs->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, 0) |
-+                          FIELD_PREP(UD_SIZE_BYTES_MASK, 512) |
-+                          FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
-+                          FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0);
--      host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
--                   FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
--                   FIELD_PREP(CS_ACTIVE_BSY, 0) |
--                   FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
--                   FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
--                   FIELD_PREP(WIDE_FLASH, 0) |
--                   FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1);
-+      nandc->regs->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
-+                          FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
-+                          FIELD_PREP(CS_ACTIVE_BSY, 0) |
-+                          FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
-+                          FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
-+                          FIELD_PREP(WIDE_FLASH, 0) |
-+                          FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1);
-       if (!nandc->props->qpic_version2)
-               nandc->regs->ecc_buf_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE);
diff --git a/target/linux/generic/backport-6.18/410-06-v6.14-mtd-rawnand-qcom-Fix-build-issue-on-x86-architecture.patch b/target/linux/generic/backport-6.18/410-06-v6.14-mtd-rawnand-qcom-Fix-build-issue-on-x86-architecture.patch
deleted file mode 100644 (file)
index 67beed3..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From b9371866799d67a80be0ea9e01bd41987db22f26 Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Mon, 6 Jan 2025 18:45:58 +0530
-Subject: [PATCH] mtd: rawnand: qcom: Fix build issue on x86 architecture
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Fix a buffer overflow issue in qcom_clear_bam_transaction by using
-struct_group to group related fields and avoid FORTIFY_SOURCE warnings.
-
-On x86 architecture, the following error occurs due to warnings being
-treated as errors:
-
-In function ‘fortify_memset_chk’,
-    inlined from ‘qcom_clear_bam_transaction’ at
-drivers/mtd/nand/qpic_common.c:88:2:
-./include/linux/fortify-string.h:480:25: error: call to ‘__write_overflow_field’
-declared with attribute warning: detected write beyond size of field
-(1st parameter); maybe use struct_group()? [-Werror=attribute-warning]
-  480 |                         __write_overflow_field(p_size_field, size);
-      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  LD [M]  drivers/mtd/nand/nandcore.o
-  CC [M]  drivers/w1/masters/mxc_w1.o
-cc1: all warnings being treated as errors
-
-This patch addresses the issue by grouping the related fields in
-struct bam_transaction using struct_group and updating the memset call
-accordingly.
-
-Fixes: 8c52932da5e6 ("mtd: rawnand: qcom: cleanup qcom_nandc driver")
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/qpic_common.c       |  2 +-
- include/linux/mtd/nand-qpic-common.h | 19 +++++++++++--------
- 2 files changed, 12 insertions(+), 9 deletions(-)
-
---- a/drivers/mtd/nand/qpic_common.c
-+++ b/drivers/mtd/nand/qpic_common.c
-@@ -85,7 +85,7 @@ void qcom_clear_bam_transaction(struct q
-       if (!nandc->props->supports_bam)
-               return;
--      memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8);
-+      memset(&bam_txn->bam_positions, 0, sizeof(bam_txn->bam_positions));
-       bam_txn->last_data_desc = NULL;
-       sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
---- a/include/linux/mtd/nand-qpic-common.h
-+++ b/include/linux/mtd/nand-qpic-common.h
-@@ -254,14 +254,17 @@ struct bam_transaction {
-       struct dma_async_tx_descriptor *last_data_desc;
-       struct dma_async_tx_descriptor *last_cmd_desc;
-       struct completion txn_done;
--      u32 bam_ce_pos;
--      u32 bam_ce_start;
--      u32 cmd_sgl_pos;
--      u32 cmd_sgl_start;
--      u32 tx_sgl_pos;
--      u32 tx_sgl_start;
--      u32 rx_sgl_pos;
--      u32 rx_sgl_start;
-+      struct_group(bam_positions,
-+              u32 bam_ce_pos;
-+              u32 bam_ce_start;
-+              u32 cmd_sgl_pos;
-+              u32 cmd_sgl_start;
-+              u32 tx_sgl_pos;
-+              u32 tx_sgl_start;
-+              u32 rx_sgl_pos;
-+              u32 rx_sgl_start;
-+
-+      );
- };
- /*
diff --git a/target/linux/generic/backport-6.18/410-07-v6.15-spi-spi-qpic-add-driver-for-QCOM-SPI-NAND-flash-Inte.patch b/target/linux/generic/backport-6.18/410-07-v6.15-spi-spi-qpic-add-driver-for-QCOM-SPI-NAND-flash-Inte.patch
deleted file mode 100644 (file)
index 310d902..0000000
+++ /dev/null
@@ -1,1737 +0,0 @@
-From 7304d1909080ef0c9da703500a97f46c98393fcd Mon Sep 17 00:00:00 2001
-From: Md Sadre Alam <quic_mdalam@quicinc.com>
-Date: Mon, 24 Feb 2025 16:44:14 +0530
-Subject: [PATCH] spi: spi-qpic: add driver for QCOM SPI NAND flash Interface
-
-This driver implements support for the SPI-NAND mode of QCOM NAND Flash
-Interface as a SPI-MEM controller with pipelined ECC capability.
-
-Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
-Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
-Co-developed-by: Varadarajan Narayanan <quic_varada@quicinc.com>
-Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
-Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Link: https://patch.msgid.link/20250224111414.2809669-3-quic_mdalam@quicinc.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/mtd/nand/Makefile            |    4 +
- drivers/spi/Kconfig                  |    9 +
- drivers/spi/Makefile                 |    1 +
- drivers/spi/spi-qpic-snand.c         | 1631 ++++++++++++++++++++++++++
- include/linux/mtd/nand-qpic-common.h |    7 +
- 5 files changed, 1652 insertions(+)
- create mode 100644 drivers/spi/spi-qpic-snand.c
-
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -3,7 +3,11 @@
- nandcore-objs := core.o bbt.o
- obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
- obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
-+ifeq ($(CONFIG_SPI_QPIC_SNAND),y)
-+obj-$(CONFIG_SPI_QPIC_SNAND) += qpic_common.o
-+else
- obj-$(CONFIG_MTD_NAND_QCOM) += qpic_common.o
-+endif
- obj-y += onenand/
- obj-y += raw/
- obj-y += spi/
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -898,6 +898,15 @@ config SPI_QCOM_QSPI
-       help
-         QSPI(Quad SPI) driver for Qualcomm QSPI controller.
-+config SPI_QPIC_SNAND
-+      bool "QPIC SNAND controller"
-+      depends on ARCH_QCOM || COMPILE_TEST
-+      select MTD
-+      help
-+        QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller.
-+        QPIC controller supports both parallel nand and serial nand.
-+        This config will enable serial nand driver for QPIC controller.
-+
- config SPI_QUP
-       tristate "Qualcomm SPI controller with QUP interface"
-       depends on ARCH_QCOM || COMPILE_TEST
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -114,6 +114,7 @@ obj-$(CONFIG_SPI_PXA2XX)           += spi-pxa2xx-
- obj-$(CONFIG_SPI_PXA2XX_PCI)          += spi-pxa2xx-pci.o
- obj-$(CONFIG_SPI_QCOM_GENI)           += spi-geni-qcom.o
- obj-$(CONFIG_SPI_QCOM_QSPI)           += spi-qcom-qspi.o
-+obj-$(CONFIG_SPI_QPIC_SNAND)            += spi-qpic-snand.o
- obj-$(CONFIG_SPI_QUP)                 += spi-qup.o
- obj-$(CONFIG_SPI_ROCKCHIP)            += spi-rockchip.o
- obj-$(CONFIG_SPI_ROCKCHIP_SFC)                += spi-rockchip-sfc.o
---- /dev/null
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -0,0 +1,1631 @@
-+/*
-+ * SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
-+ *
-+ * Authors:
-+ *    Md Sadre Alam <quic_mdalam@quicinc.com>
-+ *    Sricharan R <quic_srichara@quicinc.com>
-+ *    Varadarajan Narayanan <quic_varada@quicinc.com>
-+ */
-+#include <linux/bitops.h>
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/dmaengine.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dma/qcom_adm.h>
-+#include <linux/dma/qcom_bam_dma.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/mtd/nand-qpic-common.h>
-+#include <linux/mtd/spinand.h>
-+#include <linux/bitfield.h>
-+
-+#define NAND_FLASH_SPI_CFG            0xc0
-+#define NAND_NUM_ADDR_CYCLES          0xc4
-+#define NAND_BUSY_CHECK_WAIT_CNT      0xc8
-+#define NAND_FLASH_FEATURES           0xf64
-+
-+/* QSPI NAND config reg bits */
-+#define LOAD_CLK_CNTR_INIT_EN         BIT(28)
-+#define CLK_CNTR_INIT_VAL_VEC         0x924
-+#define CLK_CNTR_INIT_VAL_VEC_MASK    GENMASK(27, 16)
-+#define FEA_STATUS_DEV_ADDR           0xc0
-+#define FEA_STATUS_DEV_ADDR_MASK      GENMASK(15, 8)
-+#define SPI_CFG                               BIT(0)
-+#define SPI_NUM_ADDR                  0xDA4DB
-+#define SPI_WAIT_CNT                  0x10
-+#define QPIC_QSPI_NUM_CS              1
-+#define SPI_TRANSFER_MODE_x1          BIT(29)
-+#define SPI_TRANSFER_MODE_x4          (3 << 29)
-+#define SPI_WP                                BIT(28)
-+#define SPI_HOLD                      BIT(27)
-+#define QPIC_SET_FEATURE              BIT(31)
-+
-+#define SPINAND_RESET                 0xff
-+#define SPINAND_READID                        0x9f
-+#define SPINAND_GET_FEATURE           0x0f
-+#define SPINAND_SET_FEATURE           0x1f
-+#define SPINAND_READ                  0x13
-+#define SPINAND_ERASE                 0xd8
-+#define SPINAND_WRITE_EN              0x06
-+#define SPINAND_PROGRAM_EXECUTE               0x10
-+#define SPINAND_PROGRAM_LOAD          0x84
-+
-+#define ACC_FEATURE                   0xe
-+#define BAD_BLOCK_MARKER_SIZE         0x2
-+#define OOB_BUF_SIZE                  128
-+#define ecceng_to_qspi(eng)           container_of(eng, struct qpic_spi_nand, ecc_eng)
-+
-+struct qpic_snand_op {
-+      u32 cmd_reg;
-+      u32 addr1_reg;
-+      u32 addr2_reg;
-+};
-+
-+struct snandc_read_status {
-+      __le32 snandc_flash;
-+      __le32 snandc_buffer;
-+      __le32 snandc_erased_cw;
-+};
-+
-+/*
-+ * ECC state struct
-+ * @corrected:                ECC corrected
-+ * @bitflips:         Max bit flip
-+ * @failed:           ECC failed
-+ */
-+struct qcom_ecc_stats {
-+      u32 corrected;
-+      u32 bitflips;
-+      u32 failed;
-+};
-+
-+struct qpic_ecc {
-+      struct device *dev;
-+      int ecc_bytes_hw;
-+      int spare_bytes;
-+      int bbm_size;
-+      int ecc_mode;
-+      int bytes;
-+      int steps;
-+      int step_size;
-+      int strength;
-+      int cw_size;
-+      int cw_data;
-+      u32 cfg0;
-+      u32 cfg1;
-+      u32 cfg0_raw;
-+      u32 cfg1_raw;
-+      u32 ecc_buf_cfg;
-+      u32 ecc_bch_cfg;
-+      u32 clrflashstatus;
-+      u32 clrreadstatus;
-+      bool bch_enabled;
-+};
-+
-+struct qpic_spi_nand {
-+      struct qcom_nand_controller *snandc;
-+      struct spi_controller *ctlr;
-+      struct mtd_info *mtd;
-+      struct clk *iomacro_clk;
-+      struct qpic_ecc *ecc;
-+      struct qcom_ecc_stats ecc_stats;
-+      struct nand_ecc_engine ecc_eng;
-+      u8 *data_buf;
-+      u8 *oob_buf;
-+      u32 wlen;
-+      __le32 addr1;
-+      __le32 addr2;
-+      __le32 cmd;
-+      u32 num_cw;
-+      bool oob_rw;
-+      bool page_rw;
-+      bool raw_rw;
-+};
-+
-+static void qcom_spi_set_read_loc_first(struct qcom_nand_controller *snandc,
-+                                      int reg, int cw_offset, int read_size,
-+                                      int is_last_read_loc)
-+{
-+      __le32 locreg_val;
-+      u32 val = (((cw_offset) << READ_LOCATION_OFFSET) |
-+                ((read_size) << READ_LOCATION_SIZE) | ((is_last_read_loc)
-+                << READ_LOCATION_LAST));
-+
-+      locreg_val = cpu_to_le32(val);
-+
-+      if (reg == NAND_READ_LOCATION_0)
-+              snandc->regs->read_location0 = locreg_val;
-+      else if (reg == NAND_READ_LOCATION_1)
-+              snandc->regs->read_location1 = locreg_val;
-+      else if (reg == NAND_READ_LOCATION_2)
-+              snandc->regs->read_location1 = locreg_val;
-+      else if (reg == NAND_READ_LOCATION_3)
-+              snandc->regs->read_location3 = locreg_val;
-+}
-+
-+static void qcom_spi_set_read_loc_last(struct qcom_nand_controller *snandc,
-+                                     int reg, int cw_offset, int read_size,
-+                                     int is_last_read_loc)
-+{
-+      __le32 locreg_val;
-+      u32 val = (((cw_offset) << READ_LOCATION_OFFSET) |
-+                ((read_size) << READ_LOCATION_SIZE) | ((is_last_read_loc)
-+                << READ_LOCATION_LAST));
-+
-+      locreg_val = cpu_to_le32(val);
-+
-+      if (reg == NAND_READ_LOCATION_LAST_CW_0)
-+              snandc->regs->read_location_last0 = locreg_val;
-+      else if (reg == NAND_READ_LOCATION_LAST_CW_1)
-+              snandc->regs->read_location_last1 = locreg_val;
-+      else if (reg == NAND_READ_LOCATION_LAST_CW_2)
-+              snandc->regs->read_location_last2 = locreg_val;
-+      else if (reg == NAND_READ_LOCATION_LAST_CW_3)
-+              snandc->regs->read_location_last3 = locreg_val;
-+}
-+
-+static struct qcom_nand_controller *nand_to_qcom_snand(struct nand_device *nand)
-+{
-+      struct nand_ecc_engine *eng = nand->ecc.engine;
-+      struct qpic_spi_nand *qspi = ecceng_to_qspi(eng);
-+
-+      return qspi->snandc;
-+}
-+
-+static int qcom_spi_init(struct qcom_nand_controller *snandc)
-+{
-+      u32 snand_cfg_val = 0x0;
-+      int ret;
-+
-+      snand_cfg_val = FIELD_PREP(CLK_CNTR_INIT_VAL_VEC_MASK, CLK_CNTR_INIT_VAL_VEC) |
-+                      FIELD_PREP(LOAD_CLK_CNTR_INIT_EN, 0) |
-+                      FIELD_PREP(FEA_STATUS_DEV_ADDR_MASK, FEA_STATUS_DEV_ADDR) |
-+                      FIELD_PREP(SPI_CFG, 0);
-+
-+      snandc->regs->spi_cfg = cpu_to_le32(snand_cfg_val);
-+      snandc->regs->num_addr_cycle = cpu_to_le32(SPI_NUM_ADDR);
-+      snandc->regs->busy_wait_cnt = cpu_to_le32(SPI_WAIT_CNT);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->spi_cfg, NAND_FLASH_SPI_CFG, 1, 0);
-+
-+      snand_cfg_val &= ~LOAD_CLK_CNTR_INIT_EN;
-+      snandc->regs->spi_cfg = cpu_to_le32(snand_cfg_val);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->spi_cfg, NAND_FLASH_SPI_CFG, 1, 0);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->num_addr_cycle, NAND_NUM_ADDR_CYCLES, 1, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->busy_wait_cnt, NAND_BUSY_CHECK_WAIT_CNT, 1,
-+                         NAND_BAM_NEXT_SGL);
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failure in submitting spi init descriptor\n");
-+              return ret;
-+      }
-+
-+      return ret;
-+}
-+
-+static int qcom_spi_ooblayout_ecc(struct mtd_info *mtd, int section,
-+                                struct mtd_oob_region *oobregion)
-+{
-+      struct nand_device *nand = mtd_to_nanddev(mtd);
-+      struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand);
-+      struct qpic_ecc *qecc = snandc->qspi->ecc;
-+
-+      if (section > 1)
-+              return -ERANGE;
-+
-+      oobregion->length = qecc->ecc_bytes_hw + qecc->spare_bytes;
-+      oobregion->offset = mtd->oobsize - oobregion->length;
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_ooblayout_free(struct mtd_info *mtd, int section,
-+                                 struct mtd_oob_region *oobregion)
-+{
-+      struct nand_device *nand = mtd_to_nanddev(mtd);
-+      struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand);
-+      struct qpic_ecc *qecc = snandc->qspi->ecc;
-+
-+      if (section)
-+              return -ERANGE;
-+
-+      oobregion->length = qecc->steps * 4;
-+      oobregion->offset = ((qecc->steps - 1) * qecc->bytes) + qecc->bbm_size;
-+
-+      return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops qcom_spi_ooblayout = {
-+      .ecc = qcom_spi_ooblayout_ecc,
-+      .free = qcom_spi_ooblayout_free,
-+};
-+
-+static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
-+{
-+      struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand);
-+      struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
-+      struct mtd_info *mtd = nanddev_to_mtd(nand);
-+      int cwperpage, bad_block_byte;
-+      struct qpic_ecc *ecc_cfg;
-+
-+      cwperpage = mtd->writesize / NANDC_STEP_SIZE;
-+      snandc->qspi->num_cw = cwperpage;
-+
-+      ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL);
-+      if (!ecc_cfg)
-+              return -ENOMEM;
-+      snandc->qspi->oob_buf = kzalloc(mtd->writesize + mtd->oobsize,
-+                                      GFP_KERNEL);
-+      if (!snandc->qspi->oob_buf)
-+              return -ENOMEM;
-+
-+      memset(snandc->qspi->oob_buf, 0xff, mtd->writesize + mtd->oobsize);
-+
-+      nand->ecc.ctx.priv = ecc_cfg;
-+      snandc->qspi->mtd = mtd;
-+
-+      ecc_cfg->ecc_bytes_hw = 7;
-+      ecc_cfg->spare_bytes = 4;
-+      ecc_cfg->bbm_size = 1;
-+      ecc_cfg->bch_enabled = true;
-+      ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size;
-+
-+      ecc_cfg->steps = 4;
-+      ecc_cfg->strength = 4;
-+      ecc_cfg->step_size = 512;
-+      ecc_cfg->cw_data = 516;
-+      ecc_cfg->cw_size = ecc_cfg->cw_data + ecc_cfg->bytes;
-+      bad_block_byte = mtd->writesize - ecc_cfg->cw_size * (cwperpage - 1) + 1;
-+
-+      mtd_set_ooblayout(mtd, &qcom_spi_ooblayout);
-+
-+      ecc_cfg->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
-+                      FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_data) |
-+                      FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 1) |
-+                      FIELD_PREP(NUM_ADDR_CYCLES_MASK, 3) |
-+                      FIELD_PREP(ECC_PARITY_SIZE_BYTES_RS, ecc_cfg->ecc_bytes_hw) |
-+                      FIELD_PREP(STATUS_BFR_READ, 0) |
-+                      FIELD_PREP(SET_RD_MODE_AFTER_STATUS, 1) |
-+                      FIELD_PREP(SPARE_SIZE_BYTES_MASK, ecc_cfg->spare_bytes);
-+
-+      ecc_cfg->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 0) |
-+                      FIELD_PREP(CS_ACTIVE_BSY, 0) |
-+                      FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, bad_block_byte) |
-+                      FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 0) |
-+                      FIELD_PREP(WR_RD_BSY_GAP_MASK, 20) |
-+                      FIELD_PREP(WIDE_FLASH, 0) |
-+                      FIELD_PREP(ENABLE_BCH_ECC, ecc_cfg->bch_enabled);
-+
-+      ecc_cfg->cfg0_raw = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
-+                          FIELD_PREP(NUM_ADDR_CYCLES_MASK, 3) |
-+                          FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_size) |
-+                          FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0);
-+
-+      ecc_cfg->cfg1_raw = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 0) |
-+                          FIELD_PREP(CS_ACTIVE_BSY, 0) |
-+                          FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
-+                          FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
-+                          FIELD_PREP(WR_RD_BSY_GAP_MASK, 20) |
-+                          FIELD_PREP(WIDE_FLASH, 0) |
-+                          FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1);
-+
-+      ecc_cfg->ecc_bch_cfg = FIELD_PREP(ECC_CFG_ECC_DISABLE, !ecc_cfg->bch_enabled) |
-+                             FIELD_PREP(ECC_SW_RESET, 0) |
-+                             FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, ecc_cfg->cw_data) |
-+                             FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) |
-+                             FIELD_PREP(ECC_MODE_MASK, 0) |
-+                             FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, ecc_cfg->ecc_bytes_hw);
-+
-+      ecc_cfg->ecc_buf_cfg = 0x203 << NUM_STEPS;
-+      ecc_cfg->clrflashstatus = FS_READY_BSY_N;
-+      ecc_cfg->clrreadstatus = 0xc0;
-+
-+      conf->step_size = ecc_cfg->step_size;
-+      conf->strength = ecc_cfg->strength;
-+
-+      snandc->regs->erased_cw_detect_cfg_clr = cpu_to_le32(CLR_ERASED_PAGE_DET);
-+      snandc->regs->erased_cw_detect_cfg_set = cpu_to_le32(SET_ERASED_PAGE_DET);
-+
-+      dev_dbg(snandc->dev, "ECC strength: %u bits per %u bytes\n",
-+              ecc_cfg->strength, ecc_cfg->step_size);
-+
-+      return 0;
-+}
-+
-+static void qcom_spi_ecc_cleanup_ctx_pipelined(struct nand_device *nand)
-+{
-+      struct qpic_ecc *ecc_cfg = nand_to_ecc_ctx(nand);
-+
-+      kfree(ecc_cfg);
-+}
-+
-+static int qcom_spi_ecc_prepare_io_req_pipelined(struct nand_device *nand,
-+                                               struct nand_page_io_req *req)
-+{
-+      struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand);
-+      struct qpic_ecc *ecc_cfg = nand_to_ecc_ctx(nand);
-+
-+      snandc->qspi->ecc = ecc_cfg;
-+      snandc->qspi->raw_rw = false;
-+      snandc->qspi->oob_rw = false;
-+      snandc->qspi->page_rw = false;
-+
-+      if (req->datalen)
-+              snandc->qspi->page_rw = true;
-+
-+      if (req->ooblen)
-+              snandc->qspi->oob_rw = true;
-+
-+      if (req->mode == MTD_OPS_RAW)
-+              snandc->qspi->raw_rw = true;
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_ecc_finish_io_req_pipelined(struct nand_device *nand,
-+                                              struct nand_page_io_req *req)
-+{
-+      struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand);
-+      struct mtd_info *mtd = nanddev_to_mtd(nand);
-+
-+      if (req->mode == MTD_OPS_RAW || req->type != NAND_PAGE_READ)
-+              return 0;
-+
-+      if (snandc->qspi->ecc_stats.failed)
-+              mtd->ecc_stats.failed += snandc->qspi->ecc_stats.failed;
-+      else
-+              mtd->ecc_stats.corrected += snandc->qspi->ecc_stats.corrected;
-+
-+      if (snandc->qspi->ecc_stats.failed)
-+              return -EBADMSG;
-+      else
-+              return snandc->qspi->ecc_stats.bitflips;
-+}
-+
-+static struct nand_ecc_engine_ops qcom_spi_ecc_engine_ops_pipelined = {
-+      .init_ctx = qcom_spi_ecc_init_ctx_pipelined,
-+      .cleanup_ctx = qcom_spi_ecc_cleanup_ctx_pipelined,
-+      .prepare_io_req = qcom_spi_ecc_prepare_io_req_pipelined,
-+      .finish_io_req = qcom_spi_ecc_finish_io_req_pipelined,
-+};
-+
-+/* helper to configure location register values */
-+static void qcom_spi_set_read_loc(struct qcom_nand_controller *snandc, int cw, int reg,
-+                                int cw_offset, int read_size, int is_last_read_loc)
-+{
-+      int reg_base = NAND_READ_LOCATION_0;
-+      int num_cw = snandc->qspi->num_cw;
-+
-+      if (cw == (num_cw - 1))
-+              reg_base = NAND_READ_LOCATION_LAST_CW_0;
-+
-+      reg_base += reg * 4;
-+
-+      if (cw == (num_cw - 1))
-+              return qcom_spi_set_read_loc_last(snandc, reg_base, cw_offset,
-+                                                read_size, is_last_read_loc);
-+      else
-+              return qcom_spi_set_read_loc_first(snandc, reg_base, cw_offset,
-+                                                 read_size, is_last_read_loc);
-+}
-+
-+static void
-+qcom_spi_config_cw_read(struct qcom_nand_controller *snandc, bool use_ecc, int cw)
-+{
-+      __le32 *reg = &snandc->regs->read_location0;
-+      int num_cw = snandc->qspi->num_cw;
-+
-+      qcom_write_reg_dma(snandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL);
-+      if (cw == (num_cw - 1)) {
-+              reg = &snandc->regs->read_location_last0;
-+              qcom_write_reg_dma(snandc, reg, NAND_READ_LOCATION_LAST_CW_0, 4,
-+                                 NAND_BAM_NEXT_SGL);
-+      }
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+
-+      qcom_read_reg_dma(snandc, NAND_FLASH_STATUS, 2, 0);
-+      qcom_read_reg_dma(snandc, NAND_ERASED_CW_DETECT_STATUS, 1,
-+                        NAND_BAM_NEXT_SGL);
-+}
-+
-+static int qcom_spi_block_erase(struct qcom_nand_controller *snandc)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      int ret;
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+      qcom_clear_bam_transaction(snandc);
-+
-+      snandc->regs->cmd = snandc->qspi->cmd;
-+      snandc->regs->addr0 = snandc->qspi->addr1;
-+      snandc->regs->addr1 = snandc->qspi->addr2;
-+      snandc->regs->cfg0 = cpu_to_le32(ecc_cfg->cfg0_raw & ~(7 << CW_PER_PAGE));
-+      snandc->regs->cfg1 = cpu_to_le32(ecc_cfg->cfg1_raw);
-+      snandc->regs->exec = cpu_to_le32(1);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failure to erase block\n");
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static void qcom_spi_config_single_cw_page_read(struct qcom_nand_controller *snandc,
-+                                              bool use_ecc, int cw)
-+{
-+      __le32 *reg = &snandc->regs->read_location0;
-+      int num_cw = snandc->qspi->num_cw;
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr,
-+                         NAND_ERASED_CW_DETECT_CFG, 1, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set,
-+                         NAND_ERASED_CW_DETECT_CFG, 1,
-+                         NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
-+
-+      if (cw == (num_cw - 1)) {
-+              reg = &snandc->regs->read_location_last0;
-+              qcom_write_reg_dma(snandc, reg, NAND_READ_LOCATION_LAST_CW_0, 4, NAND_BAM_NEXT_SGL);
-+      }
-+      qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+
-+      qcom_read_reg_dma(snandc, NAND_FLASH_STATUS, 1, 0);
-+}
-+
-+static int qcom_spi_read_last_cw(struct qcom_nand_controller *snandc,
-+                               const struct spi_mem_op *op)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      struct mtd_info *mtd = snandc->qspi->mtd;
-+      int size, ret = 0;
-+      int col,  bbpos;
-+      u32 cfg0, cfg1, ecc_bch_cfg;
-+      u32 num_cw = snandc->qspi->num_cw;
-+
-+      qcom_clear_bam_transaction(snandc);
-+      qcom_clear_read_regs(snandc);
-+
-+      size = ecc_cfg->cw_size;
-+      col = ecc_cfg->cw_size * (num_cw - 1);
-+
-+      memset(snandc->data_buffer, 0xff, size);
-+      snandc->regs->addr0 = (snandc->qspi->addr1 | cpu_to_le32(col));
-+      snandc->regs->addr1 = snandc->qspi->addr2;
-+
-+      cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) |
-+              0 << CW_PER_PAGE;
-+      cfg1 = ecc_cfg->cfg1_raw;
-+      ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE;
-+
-+      snandc->regs->cmd = snandc->qspi->cmd;
-+      snandc->regs->cfg0 = cpu_to_le32(cfg0);
-+      snandc->regs->cfg1 = cpu_to_le32(cfg1);
-+      snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg);
-+      snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus);
-+      snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus);
-+      snandc->regs->exec = cpu_to_le32(1);
-+
-+      qcom_spi_set_read_loc(snandc, num_cw - 1, 0, 0, ecc_cfg->cw_size, 1);
-+
-+      qcom_spi_config_single_cw_page_read(snandc, false, num_cw - 1);
-+
-+      qcom_read_data_dma(snandc, FLASH_BUF_ACC, snandc->data_buffer, size, 0);
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failed to read last cw\n");
-+              return ret;
-+      }
-+
-+      qcom_nandc_dev_to_mem(snandc, true);
-+      u32 flash = le32_to_cpu(snandc->reg_read_buf[0]);
-+
-+      if (flash & (FS_OP_ERR | FS_MPU_ERR))
-+              return -EIO;
-+
-+      bbpos = mtd->writesize - ecc_cfg->cw_size * (num_cw - 1);
-+
-+      if (snandc->data_buffer[bbpos] == 0xff)
-+              snandc->data_buffer[bbpos + 1] = 0xff;
-+      if (snandc->data_buffer[bbpos] != 0xff)
-+              snandc->data_buffer[bbpos + 1] = snandc->data_buffer[bbpos];
-+
-+      memcpy(op->data.buf.in, snandc->data_buffer + bbpos, op->data.nbytes);
-+
-+      return ret;
-+}
-+
-+static int qcom_spi_check_error(struct qcom_nand_controller *snandc, u8 *data_buf, u8 *oob_buf)
-+{
-+      struct snandc_read_status *buf;
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      int i, num_cw = snandc->qspi->num_cw;
-+      bool flash_op_err = false, erased;
-+      unsigned int max_bitflips = 0;
-+      unsigned int uncorrectable_cws = 0;
-+
-+      snandc->qspi->ecc_stats.failed = 0;
-+      snandc->qspi->ecc_stats.corrected = 0;
-+
-+      qcom_nandc_dev_to_mem(snandc, true);
-+      buf = (struct snandc_read_status *)snandc->reg_read_buf;
-+
-+      for (i = 0; i < num_cw; i++, buf++) {
-+              u32 flash, buffer, erased_cw;
-+              int data_len, oob_len;
-+
-+              if (i == (num_cw - 1)) {
-+                      data_len = NANDC_STEP_SIZE - ((num_cw - 1) << 2);
-+                      oob_len = num_cw << 2;
-+              } else {
-+                      data_len = ecc_cfg->cw_data;
-+                      oob_len = 0;
-+              }
-+
-+              flash = le32_to_cpu(buf->snandc_flash);
-+              buffer = le32_to_cpu(buf->snandc_buffer);
-+              erased_cw = le32_to_cpu(buf->snandc_erased_cw);
-+
-+              if ((flash & FS_OP_ERR) && (buffer & BS_UNCORRECTABLE_BIT)) {
-+                      if (ecc_cfg->bch_enabled)
-+                              erased = (erased_cw & ERASED_CW) == ERASED_CW;
-+                      else
-+                              erased = false;
-+
-+                      if (!erased)
-+                              uncorrectable_cws |= BIT(i);
-+
-+              } else if (flash & (FS_OP_ERR | FS_MPU_ERR)) {
-+                      flash_op_err = true;
-+              } else {
-+                      unsigned int stat;
-+
-+                      stat = buffer & BS_CORRECTABLE_ERR_MSK;
-+                      snandc->qspi->ecc_stats.corrected += stat;
-+                      max_bitflips = max(max_bitflips, stat);
-+              }
-+
-+              if (data_buf)
-+                      data_buf += data_len;
-+              if (oob_buf)
-+                      oob_buf += oob_len + ecc_cfg->bytes;
-+      }
-+
-+      if (flash_op_err)
-+              return -EIO;
-+
-+      if (!uncorrectable_cws)
-+              snandc->qspi->ecc_stats.bitflips = max_bitflips;
-+      else
-+              snandc->qspi->ecc_stats.failed++;
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_check_raw_flash_errors(struct qcom_nand_controller *snandc, int cw_cnt)
-+{
-+      int i;
-+
-+      qcom_nandc_dev_to_mem(snandc, true);
-+
-+      for (i = 0; i < cw_cnt; i++) {
-+              u32 flash = le32_to_cpu(snandc->reg_read_buf[i]);
-+
-+              if (flash & (FS_OP_ERR | FS_MPU_ERR))
-+                      return -EIO;
-+      }
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_read_cw_raw(struct qcom_nand_controller *snandc, u8 *data_buf,
-+                              u8 *oob_buf, int cw)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      struct mtd_info *mtd = snandc->qspi->mtd;
-+      int data_size1, data_size2, oob_size1, oob_size2;
-+      int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
-+      int raw_cw = cw;
-+      u32 cfg0, cfg1, ecc_bch_cfg, num_cw = snandc->qspi->num_cw;
-+      int col;
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+      qcom_clear_bam_transaction(snandc);
-+      raw_cw = num_cw - 1;
-+
-+      cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) |
-+                              0 << CW_PER_PAGE;
-+      cfg1 = ecc_cfg->cfg1_raw;
-+      ecc_bch_cfg = ECC_CFG_ECC_DISABLE;
-+
-+      col = ecc_cfg->cw_size * cw;
-+
-+      snandc->regs->addr0 = (snandc->qspi->addr1 | cpu_to_le32(col));
-+      snandc->regs->addr1 = snandc->qspi->addr2;
-+      snandc->regs->cmd = snandc->qspi->cmd;
-+      snandc->regs->cfg0 = cpu_to_le32(cfg0);
-+      snandc->regs->cfg1 = cpu_to_le32(cfg1);
-+      snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg);
-+      snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus);
-+      snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus);
-+      snandc->regs->exec = cpu_to_le32(1);
-+
-+      qcom_spi_set_read_loc(snandc, raw_cw, 0, 0, ecc_cfg->cw_size, 1);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr,
-+                         NAND_ERASED_CW_DETECT_CFG, 1, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set,
-+                         NAND_ERASED_CW_DETECT_CFG, 1,
-+                         NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
-+
-+      data_size1 = mtd->writesize - ecc_cfg->cw_size * (num_cw - 1);
-+      oob_size1 = ecc_cfg->bbm_size;
-+
-+      if (cw == (num_cw - 1)) {
-+              data_size2 = NANDC_STEP_SIZE - data_size1 -
-+                           ((num_cw - 1) * 4);
-+              oob_size2 = (num_cw * 4) + ecc_cfg->ecc_bytes_hw +
-+                          ecc_cfg->spare_bytes;
-+      } else {
-+              data_size2 = ecc_cfg->cw_data - data_size1;
-+              oob_size2 = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes;
-+      }
-+
-+      qcom_spi_set_read_loc(snandc, cw, 0, read_loc, data_size1, 0);
-+      read_loc += data_size1;
-+
-+      qcom_spi_set_read_loc(snandc, cw, 1, read_loc, oob_size1, 0);
-+      read_loc += oob_size1;
-+
-+      qcom_spi_set_read_loc(snandc, cw, 2, read_loc, data_size2, 0);
-+      read_loc += data_size2;
-+
-+      qcom_spi_set_read_loc(snandc, cw, 3, read_loc, oob_size2, 1);
-+
-+      qcom_spi_config_cw_read(snandc, false, raw_cw);
-+
-+      qcom_read_data_dma(snandc, reg_off, data_buf, data_size1, 0);
-+      reg_off += data_size1;
-+
-+      qcom_read_data_dma(snandc, reg_off, oob_buf, oob_size1, 0);
-+      reg_off += oob_size1;
-+
-+      qcom_read_data_dma(snandc, reg_off, data_buf + data_size1, data_size2, 0);
-+      reg_off += data_size2;
-+
-+      qcom_read_data_dma(snandc, reg_off, oob_buf + oob_size1, oob_size2, 0);
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failure to read raw cw %d\n", cw);
-+              return ret;
-+      }
-+
-+      return qcom_spi_check_raw_flash_errors(snandc, 1);
-+}
-+
-+static int qcom_spi_read_page_raw(struct qcom_nand_controller *snandc,
-+                                const struct spi_mem_op *op)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      u8 *data_buf = NULL, *oob_buf = NULL;
-+      int ret, cw;
-+      u32 num_cw = snandc->qspi->num_cw;
-+
-+      if (snandc->qspi->page_rw)
-+              data_buf = op->data.buf.in;
-+
-+      oob_buf = snandc->qspi->oob_buf;
-+      memset(oob_buf, 0xff, OOB_BUF_SIZE);
-+
-+      for (cw = 0; cw < num_cw; cw++) {
-+              ret = qcom_spi_read_cw_raw(snandc, data_buf, oob_buf, cw);
-+              if (ret)
-+                      return ret;
-+
-+              if (data_buf)
-+                      data_buf += ecc_cfg->cw_data;
-+              if (oob_buf)
-+                      oob_buf += ecc_cfg->bytes;
-+      }
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_read_page_ecc(struct qcom_nand_controller *snandc,
-+                                const struct spi_mem_op *op)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      u8 *data_buf = NULL, *data_buf_start, *oob_buf = NULL, *oob_buf_start;
-+      int ret, i;
-+      u32 cfg0, cfg1, ecc_bch_cfg, num_cw = snandc->qspi->num_cw;
-+
-+      data_buf = op->data.buf.in;
-+      data_buf_start = data_buf;
-+
-+      oob_buf = snandc->qspi->oob_buf;
-+      oob_buf_start = oob_buf;
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+
-+      cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) |
-+                              (num_cw - 1) << CW_PER_PAGE;
-+      cfg1 = ecc_cfg->cfg1;
-+      ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-+
-+      snandc->regs->addr0 = snandc->qspi->addr1;
-+      snandc->regs->addr1 = snandc->qspi->addr2;
-+      snandc->regs->cmd = snandc->qspi->cmd;
-+      snandc->regs->cfg0 = cpu_to_le32(cfg0);
-+      snandc->regs->cfg1 = cpu_to_le32(cfg1);
-+      snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg);
-+      snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus);
-+      snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus);
-+      snandc->regs->exec = cpu_to_le32(1);
-+
-+      qcom_spi_set_read_loc(snandc, 0, 0, 0, ecc_cfg->cw_data, 1);
-+
-+      qcom_clear_bam_transaction(snandc);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr,
-+                         NAND_ERASED_CW_DETECT_CFG, 1, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set,
-+                         NAND_ERASED_CW_DETECT_CFG, 1,
-+                         NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
-+
-+      for (i = 0; i < num_cw; i++) {
-+              int data_size, oob_size;
-+
-+              if (i == (num_cw - 1)) {
-+                      data_size = 512 - ((num_cw - 1) << 2);
-+                      oob_size = (num_cw << 2) + ecc_cfg->ecc_bytes_hw +
-+                                  ecc_cfg->spare_bytes;
-+              } else {
-+                      data_size = ecc_cfg->cw_data;
-+                      oob_size = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes;
-+              }
-+
-+              if (data_buf && oob_buf) {
-+                      qcom_spi_set_read_loc(snandc, i, 0, 0, data_size, 0);
-+                      qcom_spi_set_read_loc(snandc, i, 1, data_size, oob_size, 1);
-+              } else if (data_buf) {
-+                      qcom_spi_set_read_loc(snandc, i, 0, 0, data_size, 1);
-+              } else {
-+                      qcom_spi_set_read_loc(snandc, i, 0, data_size, oob_size, 1);
-+              }
-+
-+              qcom_spi_config_cw_read(snandc, true, i);
-+
-+              if (data_buf)
-+                      qcom_read_data_dma(snandc, FLASH_BUF_ACC, data_buf,
-+                                         data_size, 0);
-+              if (oob_buf) {
-+                      int j;
-+
-+                      for (j = 0; j < ecc_cfg->bbm_size; j++)
-+                              *oob_buf++ = 0xff;
-+
-+                      qcom_read_data_dma(snandc, FLASH_BUF_ACC + data_size,
-+                                         oob_buf, oob_size, 0);
-+              }
-+
-+              if (data_buf)
-+                      data_buf += data_size;
-+              if (oob_buf)
-+                      oob_buf += oob_size;
-+      }
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failure to read page\n");
-+              return ret;
-+      }
-+
-+      return qcom_spi_check_error(snandc, data_buf_start, oob_buf_start);
-+}
-+
-+static int qcom_spi_read_page_oob(struct qcom_nand_controller *snandc,
-+                                const struct spi_mem_op *op)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      u8 *data_buf = NULL, *data_buf_start, *oob_buf = NULL, *oob_buf_start;
-+      int ret, i;
-+      u32 cfg0, cfg1, ecc_bch_cfg, num_cw = snandc->qspi->num_cw;
-+
-+      oob_buf = op->data.buf.in;
-+      oob_buf_start = oob_buf;
-+
-+      data_buf_start = data_buf;
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+      qcom_clear_bam_transaction(snandc);
-+
-+      cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) |
-+                              (num_cw - 1) << CW_PER_PAGE;
-+      cfg1 = ecc_cfg->cfg1;
-+      ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-+
-+      snandc->regs->addr0 = snandc->qspi->addr1;
-+      snandc->regs->addr1 = snandc->qspi->addr2;
-+      snandc->regs->cmd = snandc->qspi->cmd;
-+      snandc->regs->cfg0 = cpu_to_le32(cfg0);
-+      snandc->regs->cfg1 = cpu_to_le32(cfg1);
-+      snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg);
-+      snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus);
-+      snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus);
-+      snandc->regs->exec = cpu_to_le32(1);
-+
-+      qcom_spi_set_read_loc(snandc, 0, 0, 0, ecc_cfg->cw_data, 1);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr,
-+                         NAND_ERASED_CW_DETECT_CFG, 1, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set,
-+                         NAND_ERASED_CW_DETECT_CFG, 1,
-+                         NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
-+
-+      for (i = 0; i < num_cw; i++) {
-+              int data_size, oob_size;
-+
-+              if (i == (num_cw - 1)) {
-+                      data_size = NANDC_STEP_SIZE - ((num_cw - 1) << 2);
-+                      oob_size = (num_cw << 2) + ecc_cfg->ecc_bytes_hw +
-+                                  ecc_cfg->spare_bytes;
-+              } else {
-+                      data_size = ecc_cfg->cw_data;
-+                      oob_size = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes;
-+              }
-+
-+              qcom_spi_set_read_loc(snandc, i, 0, data_size, oob_size, 1);
-+
-+              qcom_spi_config_cw_read(snandc, true, i);
-+
-+              if (oob_buf) {
-+                      int j;
-+
-+                      for (j = 0; j < ecc_cfg->bbm_size; j++)
-+                              *oob_buf++ = 0xff;
-+
-+                      qcom_read_data_dma(snandc, FLASH_BUF_ACC + data_size,
-+                                         oob_buf, oob_size, 0);
-+              }
-+
-+              if (oob_buf)
-+                      oob_buf += oob_size;
-+      }
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failure to read oob\n");
-+              return ret;
-+      }
-+
-+      return qcom_spi_check_error(snandc, data_buf_start, oob_buf_start);
-+}
-+
-+static int qcom_spi_read_page(struct qcom_nand_controller *snandc,
-+                            const struct spi_mem_op *op)
-+{
-+      if (snandc->qspi->page_rw && snandc->qspi->raw_rw)
-+              return qcom_spi_read_page_raw(snandc, op);
-+
-+      if (snandc->qspi->page_rw)
-+              return qcom_spi_read_page_ecc(snandc, op);
-+
-+      if (snandc->qspi->oob_rw && snandc->qspi->raw_rw)
-+              return qcom_spi_read_last_cw(snandc, op);
-+
-+      if (snandc->qspi->oob_rw)
-+              return qcom_spi_read_page_oob(snandc, op);
-+
-+      return 0;
-+}
-+
-+static void qcom_spi_config_page_write(struct qcom_nand_controller *snandc)
-+{
-+      qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG,
-+                         1, NAND_BAM_NEXT_SGL);
-+}
-+
-+static void qcom_spi_config_cw_write(struct qcom_nand_controller *snandc)
-+{
-+      qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+      qcom_read_reg_dma(snandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0);
-+      qcom_write_reg_dma(snandc, &snandc->regs->clrreadstatus, NAND_READ_STATUS, 1,
-+                         NAND_BAM_NEXT_SGL);
-+}
-+
-+static int qcom_spi_program_raw(struct qcom_nand_controller *snandc,
-+                              const struct spi_mem_op *op)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      struct mtd_info *mtd = snandc->qspi->mtd;
-+      u8 *data_buf = NULL, *oob_buf = NULL;
-+      int i, ret;
-+      int num_cw = snandc->qspi->num_cw;
-+      u32 cfg0, cfg1, ecc_bch_cfg;
-+
-+      cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) |
-+                      (num_cw - 1) << CW_PER_PAGE;
-+      cfg1 = ecc_cfg->cfg1_raw;
-+      ecc_bch_cfg = ECC_CFG_ECC_DISABLE;
-+
-+      data_buf = snandc->qspi->data_buf;
-+
-+      oob_buf = snandc->qspi->oob_buf;
-+      memset(oob_buf, 0xff, OOB_BUF_SIZE);
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+      qcom_clear_bam_transaction(snandc);
-+
-+      snandc->regs->addr0 = snandc->qspi->addr1;
-+      snandc->regs->addr1 = snandc->qspi->addr2;
-+      snandc->regs->cmd = snandc->qspi->cmd;
-+      snandc->regs->cfg0 = cpu_to_le32(cfg0);
-+      snandc->regs->cfg1 = cpu_to_le32(cfg1);
-+      snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg);
-+      snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus);
-+      snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus);
-+      snandc->regs->exec = cpu_to_le32(1);
-+
-+      qcom_spi_config_page_write(snandc);
-+
-+      for (i = 0; i < num_cw; i++) {
-+              int data_size1, data_size2, oob_size1, oob_size2;
-+              int reg_off = FLASH_BUF_ACC;
-+
-+              data_size1 = mtd->writesize - ecc_cfg->cw_size * (num_cw - 1);
-+              oob_size1 = ecc_cfg->bbm_size;
-+
-+              if (i == (num_cw - 1)) {
-+                      data_size2 = NANDC_STEP_SIZE - data_size1 -
-+                                   ((num_cw - 1) << 2);
-+                      oob_size2 = (num_cw << 2) + ecc_cfg->ecc_bytes_hw +
-+                                  ecc_cfg->spare_bytes;
-+              } else {
-+                      data_size2 = ecc_cfg->cw_data - data_size1;
-+                      oob_size2 = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes;
-+              }
-+
-+              qcom_write_data_dma(snandc, reg_off, data_buf, data_size1,
-+                                  NAND_BAM_NO_EOT);
-+              reg_off += data_size1;
-+              data_buf += data_size1;
-+
-+              qcom_write_data_dma(snandc, reg_off, oob_buf, oob_size1,
-+                                  NAND_BAM_NO_EOT);
-+              oob_buf += oob_size1;
-+              reg_off += oob_size1;
-+
-+              qcom_write_data_dma(snandc, reg_off, data_buf, data_size2,
-+                                  NAND_BAM_NO_EOT);
-+              reg_off += data_size2;
-+              data_buf += data_size2;
-+
-+              qcom_write_data_dma(snandc, reg_off, oob_buf, oob_size2, 0);
-+              oob_buf += oob_size2;
-+
-+              qcom_spi_config_cw_write(snandc);
-+      }
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failure to write raw page\n");
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_program_ecc(struct qcom_nand_controller *snandc,
-+                              const struct spi_mem_op *op)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      u8 *data_buf = NULL, *oob_buf = NULL;
-+      int i, ret;
-+      int num_cw = snandc->qspi->num_cw;
-+      u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg;
-+
-+      cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) |
-+                              (num_cw - 1) << CW_PER_PAGE;
-+      cfg1 = ecc_cfg->cfg1;
-+      ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-+      ecc_buf_cfg = ecc_cfg->ecc_buf_cfg;
-+
-+      if (snandc->qspi->data_buf)
-+              data_buf = snandc->qspi->data_buf;
-+
-+      oob_buf = snandc->qspi->oob_buf;
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+      qcom_clear_bam_transaction(snandc);
-+
-+      snandc->regs->addr0 = snandc->qspi->addr1;
-+      snandc->regs->addr1 = snandc->qspi->addr2;
-+      snandc->regs->cmd = snandc->qspi->cmd;
-+      snandc->regs->cfg0 = cpu_to_le32(cfg0);
-+      snandc->regs->cfg1 = cpu_to_le32(cfg1);
-+      snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg);
-+      snandc->regs->ecc_buf_cfg = cpu_to_le32(ecc_buf_cfg);
-+      snandc->regs->exec = cpu_to_le32(1);
-+
-+      qcom_spi_config_page_write(snandc);
-+
-+      for (i = 0; i < num_cw; i++) {
-+              int data_size, oob_size;
-+
-+              if (i == (num_cw - 1)) {
-+                      data_size = NANDC_STEP_SIZE - ((num_cw - 1) << 2);
-+                      oob_size = (num_cw << 2) + ecc_cfg->ecc_bytes_hw +
-+                                  ecc_cfg->spare_bytes;
-+              } else {
-+                      data_size = ecc_cfg->cw_data;
-+                      oob_size = ecc_cfg->bytes;
-+              }
-+
-+              if (data_buf)
-+                      qcom_write_data_dma(snandc, FLASH_BUF_ACC, data_buf, data_size,
-+                                          i == (num_cw - 1) ? NAND_BAM_NO_EOT : 0);
-+
-+              if (i == (num_cw - 1)) {
-+                      if (oob_buf) {
-+                              oob_buf += ecc_cfg->bbm_size;
-+                              qcom_write_data_dma(snandc, FLASH_BUF_ACC + data_size,
-+                                                  oob_buf, oob_size, 0);
-+                      }
-+              }
-+
-+              qcom_spi_config_cw_write(snandc);
-+
-+              if (data_buf)
-+                      data_buf += data_size;
-+              if (oob_buf)
-+                      oob_buf += oob_size;
-+      }
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failure to write page\n");
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_program_oob(struct qcom_nand_controller *snandc,
-+                              const struct spi_mem_op *op)
-+{
-+      struct qpic_ecc *ecc_cfg = snandc->qspi->ecc;
-+      u8 *oob_buf = NULL;
-+      int ret, col, data_size, oob_size;
-+      int num_cw = snandc->qspi->num_cw;
-+      u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg;
-+
-+      cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) |
-+                              (num_cw - 1) << CW_PER_PAGE;
-+      cfg1 = ecc_cfg->cfg1;
-+      ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-+      ecc_buf_cfg = ecc_cfg->ecc_buf_cfg;
-+
-+      col = ecc_cfg->cw_size * (num_cw - 1);
-+
-+      oob_buf = snandc->qspi->data_buf;
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+      qcom_clear_bam_transaction(snandc);
-+      snandc->regs->addr0 = (snandc->qspi->addr1 | cpu_to_le32(col));
-+      snandc->regs->addr1 = snandc->qspi->addr2;
-+      snandc->regs->cmd = snandc->qspi->cmd;
-+      snandc->regs->cfg0 = cpu_to_le32(cfg0);
-+      snandc->regs->cfg1 = cpu_to_le32(cfg1);
-+      snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg);
-+      snandc->regs->ecc_buf_cfg = cpu_to_le32(ecc_buf_cfg);
-+      snandc->regs->exec = cpu_to_le32(1);
-+
-+      /* calculate the data and oob size for the last codeword/step */
-+      data_size = NANDC_STEP_SIZE - ((num_cw - 1) << 2);
-+      oob_size = snandc->qspi->mtd->oobavail;
-+
-+      memset(snandc->data_buffer, 0xff, ecc_cfg->cw_data);
-+      /* override new oob content to last codeword */
-+      mtd_ooblayout_get_databytes(snandc->qspi->mtd, snandc->data_buffer + data_size,
-+                                  oob_buf, 0, snandc->qspi->mtd->oobavail);
-+      qcom_spi_config_page_write(snandc);
-+      qcom_write_data_dma(snandc, FLASH_BUF_ACC, snandc->data_buffer, data_size + oob_size, 0);
-+      qcom_spi_config_cw_write(snandc);
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret) {
-+              dev_err(snandc->dev, "failure to write oob\n");
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_program_execute(struct qcom_nand_controller *snandc,
-+                                  const struct spi_mem_op *op)
-+{
-+      if (snandc->qspi->page_rw && snandc->qspi->raw_rw)
-+              return qcom_spi_program_raw(snandc, op);
-+
-+      if (snandc->qspi->page_rw)
-+              return qcom_spi_program_ecc(snandc, op);
-+
-+      if (snandc->qspi->oob_rw)
-+              return qcom_spi_program_oob(snandc, op);
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_cmd_mapping(struct qcom_nand_controller *snandc, u32 opcode, u32 *cmd)
-+{
-+      switch (opcode) {
-+      case SPINAND_RESET:
-+              *cmd = (SPI_WP | SPI_HOLD | SPI_TRANSFER_MODE_x1 | OP_RESET_DEVICE);
-+              break;
-+      case SPINAND_READID:
-+              *cmd = (SPI_WP | SPI_HOLD | SPI_TRANSFER_MODE_x1 | OP_FETCH_ID);
-+              break;
-+      case SPINAND_GET_FEATURE:
-+              *cmd = (SPI_TRANSFER_MODE_x1 | SPI_WP | SPI_HOLD | ACC_FEATURE);
-+              break;
-+      case SPINAND_SET_FEATURE:
-+              *cmd = (SPI_TRANSFER_MODE_x1 | SPI_WP | SPI_HOLD | ACC_FEATURE |
-+                      QPIC_SET_FEATURE);
-+              break;
-+      case SPINAND_READ:
-+              if (snandc->qspi->raw_rw) {
-+                      *cmd = (PAGE_ACC | LAST_PAGE | SPI_TRANSFER_MODE_x1 |
-+                                      SPI_WP | SPI_HOLD | OP_PAGE_READ);
-+              } else {
-+                      *cmd = (PAGE_ACC | LAST_PAGE | SPI_TRANSFER_MODE_x1 |
-+                                      SPI_WP | SPI_HOLD | OP_PAGE_READ_WITH_ECC);
-+              }
-+
-+              break;
-+      case SPINAND_ERASE:
-+              *cmd = OP_BLOCK_ERASE | PAGE_ACC | LAST_PAGE | SPI_WP |
-+                      SPI_HOLD | SPI_TRANSFER_MODE_x1;
-+              break;
-+      case SPINAND_WRITE_EN:
-+              *cmd = SPINAND_WRITE_EN;
-+              break;
-+      case SPINAND_PROGRAM_EXECUTE:
-+              *cmd = (PAGE_ACC | LAST_PAGE | SPI_TRANSFER_MODE_x1 |
-+                              SPI_WP | SPI_HOLD | OP_PROGRAM_PAGE);
-+              break;
-+      case SPINAND_PROGRAM_LOAD:
-+              *cmd = SPINAND_PROGRAM_LOAD;
-+              break;
-+      default:
-+              dev_err(snandc->dev, "Opcode not supported: %u\n", opcode);
-+              return -EOPNOTSUPP;
-+      }
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_write_page(struct qcom_nand_controller *snandc,
-+                             const struct spi_mem_op *op)
-+{
-+      int ret;
-+      u32 cmd;
-+
-+      ret = qcom_spi_cmd_mapping(snandc, op->cmd.opcode, &cmd);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (op->cmd.opcode == SPINAND_PROGRAM_LOAD)
-+              snandc->qspi->data_buf = (u8 *)op->data.buf.out;
-+
-+      return 0;
-+}
-+
-+static int qcom_spi_send_cmdaddr(struct qcom_nand_controller *snandc,
-+                               const struct spi_mem_op *op)
-+{
-+      struct qpic_snand_op s_op = {};
-+      u32 cmd;
-+      int ret, opcode;
-+
-+      ret = qcom_spi_cmd_mapping(snandc, op->cmd.opcode, &cmd);
-+      if (ret < 0)
-+              return ret;
-+
-+      s_op.cmd_reg = cmd;
-+      s_op.addr1_reg = op->addr.val;
-+      s_op.addr2_reg = 0;
-+
-+      opcode = op->cmd.opcode;
-+
-+      switch (opcode) {
-+      case SPINAND_WRITE_EN:
-+              return 0;
-+      case SPINAND_PROGRAM_EXECUTE:
-+              s_op.addr1_reg = op->addr.val << 16;
-+              s_op.addr2_reg = op->addr.val >> 16 & 0xff;
-+              snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg);
-+              snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg);
-+              snandc->qspi->cmd = cpu_to_le32(cmd);
-+              return qcom_spi_program_execute(snandc, op);
-+      case SPINAND_READ:
-+              s_op.addr1_reg = (op->addr.val << 16);
-+              s_op.addr2_reg = op->addr.val >> 16 & 0xff;
-+              snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg);
-+              snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg);
-+              snandc->qspi->cmd = cpu_to_le32(cmd);
-+              return 0;
-+      case SPINAND_ERASE:
-+              s_op.addr2_reg = (op->addr.val >> 16) & 0xffff;
-+              s_op.addr1_reg = op->addr.val;
-+              snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg << 16);
-+              snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg);
-+              snandc->qspi->cmd = cpu_to_le32(cmd);
-+              qcom_spi_block_erase(snandc);
-+              return 0;
-+      default:
-+              break;
-+      }
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+      qcom_clear_bam_transaction(snandc);
-+
-+      snandc->regs->cmd = cpu_to_le32(s_op.cmd_reg);
-+      snandc->regs->exec = cpu_to_le32(1);
-+      snandc->regs->addr0 = cpu_to_le32(s_op.addr1_reg);
-+      snandc->regs->addr1 = cpu_to_le32(s_op.addr2_reg);
-+
-+      qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL);
-+      qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret)
-+              dev_err(snandc->dev, "failure in submitting cmd descriptor\n");
-+
-+      return ret;
-+}
-+
-+static int qcom_spi_io_op(struct qcom_nand_controller *snandc, const struct spi_mem_op *op)
-+{
-+      int ret, val, opcode;
-+      bool copy = false, copy_ftr = false;
-+
-+      ret = qcom_spi_send_cmdaddr(snandc, op);
-+      if (ret)
-+              return ret;
-+
-+      snandc->buf_count = 0;
-+      snandc->buf_start = 0;
-+      qcom_clear_read_regs(snandc);
-+      qcom_clear_bam_transaction(snandc);
-+      opcode = op->cmd.opcode;
-+
-+      switch (opcode) {
-+      case SPINAND_READID:
-+              snandc->buf_count = 4;
-+              qcom_read_reg_dma(snandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
-+              copy = true;
-+              break;
-+      case SPINAND_GET_FEATURE:
-+              snandc->buf_count = 4;
-+              qcom_read_reg_dma(snandc, NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL);
-+              copy_ftr = true;
-+              break;
-+      case SPINAND_SET_FEATURE:
-+              snandc->regs->flash_feature = cpu_to_le32(*(u32 *)op->data.buf.out);
-+              qcom_write_reg_dma(snandc, &snandc->regs->flash_feature,
-+                                 NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL);
-+              break;
-+      case SPINAND_PROGRAM_EXECUTE:
-+      case SPINAND_WRITE_EN:
-+      case SPINAND_RESET:
-+      case SPINAND_ERASE:
-+      case SPINAND_READ:
-+              return 0;
-+      default:
-+              return -EOPNOTSUPP;
-+      }
-+
-+      ret = qcom_submit_descs(snandc);
-+      if (ret)
-+              dev_err(snandc->dev, "failure in submitting descriptor for:%d\n", opcode);
-+
-+      if (copy) {
-+              qcom_nandc_dev_to_mem(snandc, true);
-+              memcpy(op->data.buf.in, snandc->reg_read_buf, snandc->buf_count);
-+      }
-+
-+      if (copy_ftr) {
-+              qcom_nandc_dev_to_mem(snandc, true);
-+              val = le32_to_cpu(*(__le32 *)snandc->reg_read_buf);
-+              val >>= 8;
-+              memcpy(op->data.buf.in, &val, snandc->buf_count);
-+      }
-+
-+      return ret;
-+}
-+
-+static bool qcom_spi_is_page_op(const struct spi_mem_op *op)
-+{
-+      if (op->addr.buswidth != 1 && op->addr.buswidth != 2 && op->addr.buswidth != 4)
-+              return false;
-+
-+      if (op->data.dir == SPI_MEM_DATA_IN) {
-+              if (op->addr.buswidth == 4 && op->data.buswidth == 4)
-+                      return true;
-+
-+              if (op->addr.nbytes == 2 && op->addr.buswidth == 1)
-+                      return true;
-+
-+      } else if (op->data.dir == SPI_MEM_DATA_OUT) {
-+              if (op->data.buswidth == 4)
-+                      return true;
-+              if (op->addr.nbytes == 2 && op->addr.buswidth == 1)
-+                      return true;
-+      }
-+
-+      return false;
-+}
-+
-+static bool qcom_spi_supports_op(struct spi_mem *mem, const struct spi_mem_op *op)
-+{
-+      if (!spi_mem_default_supports_op(mem, op))
-+              return false;
-+
-+      if (op->cmd.nbytes != 1 || op->cmd.buswidth != 1)
-+              return false;
-+
-+      if (qcom_spi_is_page_op(op))
-+              return true;
-+
-+      return ((!op->addr.nbytes || op->addr.buswidth == 1) &&
-+              (!op->dummy.nbytes || op->dummy.buswidth == 1) &&
-+              (!op->data.nbytes || op->data.buswidth == 1));
-+}
-+
-+static int qcom_spi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
-+{
-+      struct qcom_nand_controller *snandc = spi_controller_get_devdata(mem->spi->controller);
-+
-+      dev_dbg(snandc->dev, "OP %02x ADDR %08llX@%d:%u DATA %d:%u", op->cmd.opcode,
-+              op->addr.val, op->addr.buswidth, op->addr.nbytes,
-+              op->data.buswidth, op->data.nbytes);
-+
-+      if (qcom_spi_is_page_op(op)) {
-+              if (op->data.dir == SPI_MEM_DATA_IN)
-+                      return qcom_spi_read_page(snandc, op);
-+              if (op->data.dir == SPI_MEM_DATA_OUT)
-+                      return qcom_spi_write_page(snandc, op);
-+      } else {
-+              return qcom_spi_io_op(snandc, op);
-+      }
-+
-+      return 0;
-+}
-+
-+static const struct spi_controller_mem_ops qcom_spi_mem_ops = {
-+      .supports_op = qcom_spi_supports_op,
-+      .exec_op = qcom_spi_exec_op,
-+};
-+
-+static const struct spi_controller_mem_caps qcom_spi_mem_caps = {
-+      .ecc = true,
-+};
-+
-+static int qcom_spi_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      struct spi_controller *ctlr;
-+      struct qcom_nand_controller *snandc;
-+      struct qpic_spi_nand *qspi;
-+      struct qpic_ecc *ecc;
-+      struct resource *res;
-+      const void *dev_data;
-+      int ret;
-+
-+      ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL);
-+      if (!ecc)
-+              return -ENOMEM;
-+
-+      qspi = devm_kzalloc(dev, sizeof(*qspi), GFP_KERNEL);
-+      if (!qspi)
-+              return -ENOMEM;
-+
-+      ctlr = __devm_spi_alloc_controller(dev, sizeof(*snandc), false);
-+      if (!ctlr)
-+              return -ENOMEM;
-+
-+      platform_set_drvdata(pdev, ctlr);
-+
-+      snandc = spi_controller_get_devdata(ctlr);
-+      qspi->snandc = snandc;
-+
-+      snandc->dev = dev;
-+      snandc->qspi = qspi;
-+      snandc->qspi->ctlr = ctlr;
-+      snandc->qspi->ecc = ecc;
-+
-+      dev_data = of_device_get_match_data(dev);
-+      if (!dev_data) {
-+              dev_err(&pdev->dev, "failed to get device data\n");
-+              return -ENODEV;
-+      }
-+
-+      snandc->props = dev_data;
-+      snandc->dev = &pdev->dev;
-+
-+      snandc->core_clk = devm_clk_get(dev, "core");
-+      if (IS_ERR(snandc->core_clk))
-+              return PTR_ERR(snandc->core_clk);
-+
-+      snandc->aon_clk = devm_clk_get(dev, "aon");
-+      if (IS_ERR(snandc->aon_clk))
-+              return PTR_ERR(snandc->aon_clk);
-+
-+      snandc->qspi->iomacro_clk = devm_clk_get(dev, "iom");
-+      if (IS_ERR(snandc->qspi->iomacro_clk))
-+              return PTR_ERR(snandc->qspi->iomacro_clk);
-+
-+      snandc->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+      if (IS_ERR(snandc->base))
-+              return PTR_ERR(snandc->base);
-+
-+      snandc->base_phys = res->start;
-+      snandc->base_dma = dma_map_resource(dev, res->start, resource_size(res),
-+                                          DMA_BIDIRECTIONAL, 0);
-+      if (dma_mapping_error(dev, snandc->base_dma))
-+              return -ENXIO;
-+
-+      ret = clk_prepare_enable(snandc->core_clk);
-+      if (ret)
-+              goto err_dis_core_clk;
-+
-+      ret = clk_prepare_enable(snandc->aon_clk);
-+      if (ret)
-+              goto err_dis_aon_clk;
-+
-+      ret = clk_prepare_enable(snandc->qspi->iomacro_clk);
-+      if (ret)
-+              goto err_dis_iom_clk;
-+
-+      ret = qcom_nandc_alloc(snandc);
-+      if (ret)
-+              goto err_snand_alloc;
-+
-+      ret = qcom_spi_init(snandc);
-+      if (ret)
-+              goto err_spi_init;
-+
-+      /* setup ECC engine */
-+      snandc->qspi->ecc_eng.dev = &pdev->dev;
-+      snandc->qspi->ecc_eng.integration = NAND_ECC_ENGINE_INTEGRATION_PIPELINED;
-+      snandc->qspi->ecc_eng.ops = &qcom_spi_ecc_engine_ops_pipelined;
-+      snandc->qspi->ecc_eng.priv = snandc;
-+
-+      ret = nand_ecc_register_on_host_hw_engine(&snandc->qspi->ecc_eng);
-+      if (ret) {
-+              dev_err(&pdev->dev, "failed to register ecc engine:%d\n", ret);
-+              goto err_spi_init;
-+      }
-+
-+      ctlr->num_chipselect = QPIC_QSPI_NUM_CS;
-+      ctlr->mem_ops = &qcom_spi_mem_ops;
-+      ctlr->mem_caps = &qcom_spi_mem_caps;
-+      ctlr->dev.of_node = pdev->dev.of_node;
-+      ctlr->mode_bits = SPI_TX_DUAL | SPI_RX_DUAL |
-+                          SPI_TX_QUAD | SPI_RX_QUAD;
-+
-+      ret = spi_register_controller(ctlr);
-+      if (ret) {
-+              dev_err(&pdev->dev, "spi_register_controller failed.\n");
-+              goto err_spi_init;
-+      }
-+
-+      return 0;
-+
-+err_spi_init:
-+      qcom_nandc_unalloc(snandc);
-+err_snand_alloc:
-+      clk_disable_unprepare(snandc->qspi->iomacro_clk);
-+err_dis_iom_clk:
-+      clk_disable_unprepare(snandc->aon_clk);
-+err_dis_aon_clk:
-+      clk_disable_unprepare(snandc->core_clk);
-+err_dis_core_clk:
-+      dma_unmap_resource(dev, res->start, resource_size(res),
-+                         DMA_BIDIRECTIONAL, 0);
-+      return ret;
-+}
-+
-+static void qcom_spi_remove(struct platform_device *pdev)
-+{
-+      struct spi_controller *ctlr = platform_get_drvdata(pdev);
-+      struct qcom_nand_controller *snandc = spi_controller_get_devdata(ctlr);
-+      struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+
-+      spi_unregister_controller(ctlr);
-+
-+      qcom_nandc_unalloc(snandc);
-+
-+      clk_disable_unprepare(snandc->aon_clk);
-+      clk_disable_unprepare(snandc->core_clk);
-+      clk_disable_unprepare(snandc->qspi->iomacro_clk);
-+
-+      dma_unmap_resource(&pdev->dev, snandc->base_dma, resource_size(res),
-+                         DMA_BIDIRECTIONAL, 0);
-+}
-+
-+static const struct qcom_nandc_props ipq9574_snandc_props = {
-+      .dev_cmd_reg_start = 0x7000,
-+      .supports_bam = true,
-+};
-+
-+static const struct of_device_id qcom_snandc_of_match[] = {
-+      {
-+              .compatible = "qcom,ipq9574-snand",
-+              .data = &ipq9574_snandc_props,
-+      },
-+      {}
-+}
-+MODULE_DEVICE_TABLE(of, qcom_snandc_of_match);
-+
-+static struct platform_driver qcom_spi_driver = {
-+      .driver = {
-+              .name           = "qcom_snand",
-+              .of_match_table = qcom_snandc_of_match,
-+      },
-+      .probe = qcom_spi_probe,
-+      .remove_new = qcom_spi_remove,
-+};
-+module_platform_driver(qcom_spi_driver);
-+
-+MODULE_DESCRIPTION("SPI driver for QPIC QSPI cores");
-+MODULE_AUTHOR("Md Sadre Alam <quic_mdalam@quicinc.com>");
-+MODULE_LICENSE("GPL");
-+
---- a/include/linux/mtd/nand-qpic-common.h
-+++ b/include/linux/mtd/nand-qpic-common.h
-@@ -325,6 +325,10 @@ struct nandc_regs {
-       __le32 read_location_last1;
-       __le32 read_location_last2;
-       __le32 read_location_last3;
-+      __le32 spi_cfg;
-+      __le32 num_addr_cycle;
-+      __le32 busy_wait_cnt;
-+      __le32 flash_feature;
-       __le32 erased_cw_detect_cfg_clr;
-       __le32 erased_cw_detect_cfg_set;
-@@ -339,6 +343,7 @@ struct nandc_regs {
-  *
-  * @core_clk:                 controller clock
-  * @aon_clk:                  another controller clock
-+ * @iomacro_clk:              io macro clock
-  *
-  * @regs:                     a contiguous chunk of memory for DMA register
-  *                            writes. contains the register values to be
-@@ -348,6 +353,7 @@ struct nandc_regs {
-  *                            initialized via DT match data
-  *
-  * @controller:                       base controller structure
-+ * @qspi:                     qpic spi structure
-  * @host_list:                        list containing all the chips attached to the
-  *                            controller
-  *
-@@ -392,6 +398,7 @@ struct qcom_nand_controller {
-       const struct qcom_nandc_props *props;
-       struct nand_controller *controller;
-+      struct qpic_spi_nand *qspi;
-       struct list_head host_list;
-       union {
diff --git a/target/linux/generic/backport-6.18/410-08-v6.15-spi-spi-qpic-snand-Fix-ECC_CFG_ECC_DISABLE-shift-in-.patch b/target/linux/generic/backport-6.18/410-08-v6.15-spi-spi-qpic-snand-Fix-ECC_CFG_ECC_DISABLE-shift-in-.patch
deleted file mode 100644 (file)
index ad43f8d..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From cf1ba3cb245020459f2ca446b7a7b199839f5d83 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@linaro.org>
-Date: Thu, 6 Mar 2025 12:40:01 +0300
-Subject: [PATCH] spi: spi-qpic-snand: Fix ECC_CFG_ECC_DISABLE shift in
- qcom_spi_read_last_cw()
-
-The ECC_CFG_ECC_DISABLE define is BIT(0).  It's supposed to be used
-directly instead of used as a shifter.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
-Link: https://patch.msgid.link/2f4b0a0b-2c03-41c0-8a4a-3d789a83832d@stanley.mountain
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -514,7 +514,7 @@ static int qcom_spi_read_last_cw(struct
-       cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) |
-               0 << CW_PER_PAGE;
-       cfg1 = ecc_cfg->cfg1_raw;
--      ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE;
-+      ecc_bch_cfg = ECC_CFG_ECC_DISABLE;
-       snandc->regs->cmd = snandc->qspi->cmd;
-       snandc->regs->cfg0 = cpu_to_le32(cfg0);
diff --git a/target/linux/generic/backport-6.18/410-09-v6.15-spi-spi-qpic-snand-avoid-memleak-in-qcom_spi_ecc_ini.patch b/target/linux/generic/backport-6.18/410-09-v6.15-spi-spi-qpic-snand-avoid-memleak-in-qcom_spi_ecc_ini.patch
deleted file mode 100644 (file)
index 1e2a3b0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From d450cdd9c4398add1f2aa7200f2c95f1e3b9f9fa Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Thu, 13 Mar 2025 19:31:21 +0100
-Subject: [PATCH] spi: spi-qpic-snand: avoid memleak in
- qcom_spi_ecc_init_ctx_pipelined()
-
-When the allocation of the OOB buffer fails, the
-qcom_spi_ecc_init_ctx_pipelined() function returns without freeing
-the memory allocated for 'ecc_cfg' thus it can cause a memory leak.
-
-Call kfree() to free 'ecc_cfg' before returning from the function
-to avoid that.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Link: https://patch.msgid.link/20250313-qpic-snand-memleak-fix-v1-1-e54e78d1da3a@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -263,8 +263,10 @@ static int qcom_spi_ecc_init_ctx_pipelin
-               return -ENOMEM;
-       snandc->qspi->oob_buf = kzalloc(mtd->writesize + mtd->oobsize,
-                                       GFP_KERNEL);
--      if (!snandc->qspi->oob_buf)
-+      if (!snandc->qspi->oob_buf) {
-+              kfree(ecc_cfg);
-               return -ENOMEM;
-+      }
-       memset(snandc->qspi->oob_buf, 0xff, mtd->writesize + mtd->oobsize);
diff --git a/target/linux/generic/backport-6.18/410-10-v6.15-spi-SPI_QPIC_SNAND-should-be-tristate-and-depend-on-.patch b/target/linux/generic/backport-6.18/410-10-v6.15-spi-SPI_QPIC_SNAND-should-be-tristate-and-depend-on-.patch
deleted file mode 100644 (file)
index 5e92048..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-From d32c4e58545f17caaa854415f854691e32d42075 Mon Sep 17 00:00:00 2001
-From: Geert Uytterhoeven <geert+renesas@glider.be>
-Date: Wed, 26 Mar 2025 15:22:19 +0100
-Subject: [PATCH] spi: SPI_QPIC_SNAND should be tristate and depend on MTD
-
-SPI_QPIC_SNAND is the only driver that selects MTD instead of depending
-on it, which could lead to circular dependencies.  Moreover, as
-SPI_QPIC_SNAND is bool, this forces MTD (and various related symbols) to
-be built-in, as can be seen in an allmodconfig kernel.
-
-Except for a missing semicolon, there is no reason why SPI_QPIC_SNAND
-cannot be tristate; all MODULE_*() boilerplate is already present.
-Hence make SPI_QPIC_SNAND tristate, let it depend on MTD, and add the
-missing semicolon.
-
-Fixes: 7304d1909080ef0c ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
-Link: https://patch.msgid.link/b63db431cbf35223a4400e44c296293d32c4543c.1742998909.git.geert+renesas@glider.be
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/Kconfig          | 4 ++--
- drivers/spi/spi-qpic-snand.c | 2 +-
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -899,9 +899,9 @@ config SPI_QCOM_QSPI
-         QSPI(Quad SPI) driver for Qualcomm QSPI controller.
- config SPI_QPIC_SNAND
--      bool "QPIC SNAND controller"
-+      tristate "QPIC SNAND controller"
-       depends on ARCH_QCOM || COMPILE_TEST
--      select MTD
-+      depends on MTD
-       help
-         QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller.
-         QPIC controller supports both parallel nand and serial nand.
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -1614,7 +1614,7 @@ static const struct of_device_id qcom_sn
-               .data = &ipq9574_snandc_props,
-       },
-       {}
--}
-+};
- MODULE_DEVICE_TABLE(of, qcom_snandc_of_match);
- static struct platform_driver qcom_spi_driver = {
diff --git a/target/linux/generic/backport-6.18/410-11-v6.15-spi-spi-qpic-snand-propagate-errors-from-qcom_spi_block_erase.patch b/target/linux/generic/backport-6.18/410-11-v6.15-spi-spi-qpic-snand-propagate-errors-from-qcom_spi_block_erase.patch
deleted file mode 100644 (file)
index 9da531b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Wed, 23 Apr 2025 21:31:57 +0200
-Subject: [PATCH] spi: spi-qpic-snand: propagate errors from
- qcom_spi_block_erase()
-
-The qcom_spi_block_erase() function returns with error in case of
-failure. Change the qcom_spi_send_cmdaddr() function to propagate
-these errors to the callers instead of returning with success.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
-Reviewed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
----
- drivers/spi/spi-qpic-snand.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-
----
-base-commit: 9c32cda43eb78f78c73aee4aa344b777714e259b
-change-id: 20250422-qpic-snand-propagate-error-9c95811ab811
-
-Best regards,
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -1307,8 +1307,7 @@ static int qcom_spi_send_cmdaddr(struct
-               snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg << 16);
-               snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg);
-               snandc->qspi->cmd = cpu_to_le32(cmd);
--              qcom_spi_block_erase(snandc);
--              return 0;
-+              return qcom_spi_block_erase(snandc);
-       default:
-               break;
-       }
diff --git a/target/linux/generic/backport-6.18/410-12-v6.15-spi-spi-qpic-snand-fix-NAND_READ_LOCATION_2-register-handling.patch b/target/linux/generic/backport-6.18/410-12-v6.15-spi-spi-qpic-snand-fix-NAND_READ_LOCATION_2-register-handling.patch
deleted file mode 100644 (file)
index a2cd636..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Mon, 28 Apr 2025 09:30:55 +0200
-Subject: [PATCH] spi: spi-qpic-snand: fix NAND_READ_LOCATION_2 register
- handling
-
-The precomputed value for the NAND_READ_LOCATION_2 register should be
-stored in 'snandc->regs->read_location2'.
-
-Fix the qcom_spi_set_read_loc_first() function accordingly.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Reviewed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
----
- drivers/spi/spi-qpic-snand.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-
----
-base-commit: 15cfe55ec58ace931a73e19e5367598734ceb074
-change-id: 20250428-qpic-snand-readloc2-fix-bccd07cf26d3
-
-Best regards,
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -142,7 +142,7 @@ static void qcom_spi_set_read_loc_first(
-       else if (reg == NAND_READ_LOCATION_1)
-               snandc->regs->read_location1 = locreg_val;
-       else if (reg == NAND_READ_LOCATION_2)
--              snandc->regs->read_location1 = locreg_val;
-+              snandc->regs->read_location2 = locreg_val;
-       else if (reg == NAND_READ_LOCATION_3)
-               snandc->regs->read_location3 = locreg_val;
- }
diff --git a/target/linux/generic/backport-6.18/410-13-v6.15-spi-spi-qpic-snand-use-kmalloc-for-OOB-buffer-alloca.patch b/target/linux/generic/backport-6.18/410-13-v6.15-spi-spi-qpic-snand-use-kmalloc-for-OOB-buffer-alloca.patch
deleted file mode 100644 (file)
index 5a3d498..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From f48d80503504257682e493dc17408f2f0b47bcfa Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Thu, 20 Mar 2025 19:11:59 +0100
-Subject: [PATCH] spi: spi-qpic-snand: use kmalloc() for OOB buffer allocation
-
-The qcom_spi_ecc_init_ctx_pipelined() function allocates zeroed
-memory for the OOB buffer, then it fills the buffer with '0xff'
-bytes right after the allocation. In this case zeroing the memory
-during allocation is superfluous, so use kmalloc() instead of
-kzalloc() to avoid that.
-
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Link: https://patch.msgid.link/20250320-qpic-snand-kmalloc-v1-1-94e267550675@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -261,7 +261,7 @@ static int qcom_spi_ecc_init_ctx_pipelin
-       ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL);
-       if (!ecc_cfg)
-               return -ENOMEM;
--      snandc->qspi->oob_buf = kzalloc(mtd->writesize + mtd->oobsize,
-+      snandc->qspi->oob_buf = kmalloc(mtd->writesize + mtd->oobsize,
-                                       GFP_KERNEL);
-       if (!snandc->qspi->oob_buf) {
-               kfree(ecc_cfg);
diff --git a/target/linux/generic/backport-6.18/410-14-v6.16-spi-spi-qpic-snand-remove-unused-wlen-member-of-struct-qpic_spi_nand.patch b/target/linux/generic/backport-6.18/410-14-v6.16-spi-spi-qpic-snand-remove-unused-wlen-member-of-struct-qpic_spi_nand.patch
deleted file mode 100644 (file)
index 55e84da..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Thu, 24 Apr 2025 20:10:59 +0200
-Subject: [PATCH] spi: spi-qpic-snand: remove unused 'wlen' member of
- 'struct qpic_spi_nand'
-
-The 'wlen' member of the qpic_spi_nand structure is never used in the
-code so remove that.
-
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
----
- drivers/spi/spi-qpic-snand.c | 1 -
- 1 file changed, 1 deletion(-)
-
-
----
-base-commit: 9c32cda43eb78f78c73aee4aa344b777714e259b
-change-id: 20250424-qpic-snand-remove-wlen-c0cef3801a7f
-
-Best regards,
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -116,7 +116,6 @@ struct qpic_spi_nand {
-       struct nand_ecc_engine ecc_eng;
-       u8 *data_buf;
-       u8 *oob_buf;
--      u32 wlen;
-       __le32 addr1;
-       __le32 addr2;
-       __le32 cmd;
diff --git a/target/linux/generic/backport-6.18/411-v6.15-mtd-nand-Drop-explicit-test-for-built-in-CONFIG_SPI_.patch b/target/linux/generic/backport-6.18/411-v6.15-mtd-nand-Drop-explicit-test-for-built-in-CONFIG_SPI_.patch
deleted file mode 100644 (file)
index 8019d2c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From 36c6468724aa98d33fea9a1d7e07ddda6302f5d4 Mon Sep 17 00:00:00 2001
-From: Geert Uytterhoeven <geert+renesas@glider.be>
-Date: Fri, 28 Mar 2025 09:24:01 +0100
-Subject: mtd: nand: Drop explicit test for built-in CONFIG_SPI_QPIC_SNAND
-
-If CONFIG_SPI_QPIC_SNAND=m, but CONFIG_MTD_NAND_QCOM=n:
-
-    ERROR: modpost: "qcom_nandc_unalloc" [drivers/spi/spi-qpic-snand.ko] undefined!
-    ...
-
-Fix this by dropping the explicit test for a built-in
-CONFIG_SPI_QPIC_SNAND completely.  Kbuild handles multiple and mixed
-obj-y/obj-m rules for the same object file fine.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Closes: https://lore.kernel.org/oe-kbuild-all/202503280759.XhwLcV7m-lkp@intel.com/
-Fixes: 7304d1909080ef0c ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/Makefile | 3 ---
- 1 file changed, 3 deletions(-)
-
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -3,11 +3,8 @@
- nandcore-objs := core.o bbt.o
- obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
- obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
--ifeq ($(CONFIG_SPI_QPIC_SNAND),y)
- obj-$(CONFIG_SPI_QPIC_SNAND) += qpic_common.o
--else
- obj-$(CONFIG_MTD_NAND_QCOM) += qpic_common.o
--endif
- obj-y += onenand/
- obj-y += raw/
- obj-y += spi/
diff --git a/target/linux/generic/backport-6.18/412-v6.16-next-spi-spi-qpic-snand-validate-user-chip-specific-ECC-properties.patch b/target/linux/generic/backport-6.18/412-v6.16-next-spi-spi-qpic-snand-validate-user-chip-specific-ECC-properties.patch
deleted file mode 100644 (file)
index 2f95156..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-From 65cb56d49f6edea409600a3c61effc70ee5d43d8 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Thu, 1 May 2025 18:19:16 +0200
-Subject: spi: spi-qpic-snand: validate user/chip specific ECC properties
-
-The driver only supports 512 bytes ECC step size and 4 bit ECC strength
-at the moment, however it does not reject unsupported step/strength
-configurations. Due to this, whenever the driver is used with a flash
-chip which needs stronger ECC protection, the following warning is shown
-in the kernel log:
-
-  [    0.574648] spi-nand spi0.0: GigaDevice SPI NAND was found.
-  [    0.635748] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
-  [    0.649079] nand: WARNING: (null): the ECC used on your system is too weak compared to the one required by the NAND chip
-
-Although the message indicates that something is wrong, but it often gets
-unnoticed, which can cause serious problems. For example when the user
-writes something into the flash chip despite the warning, the written data
-may won't be readable by the bootloader or by the boot ROM. In the worst
-case, when the attached SPI NAND chip is the boot device, the board may not
-be able to boot anymore.
-
-Also, it is not even possible to create a backup of the flash, because
-reading its content results in bogus data. For example, dumping the first
-page of the flash gives this:
-
-  # hexdump -C -n 2048 /dev/mtd0
-  00000000  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  00000040  0f 0f 0f 0f 0f 0f 0f 0d  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  00000050  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  000001c0  0f 0f 0f 0f ff 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  000001d0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  00000200  0f 0f 0f 0f f5 5b ff ff  0f 0f 0f 0f 0f 0f 0f 0f  |.....[..........|
-  00000210  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  000002f0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 1f 0f 0f  |................|
-  00000300  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  000003c0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f ff 0f 0f 0f  |................|
-  000003d0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  00000400  0f 0f 0f 0f 0f 0f 0f 0f  e9 74 c9 06 f5 5b ff ff  |.........t...[..|
-  00000410  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  000005d0  0f 0f 0f 0f ff 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  000005e0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  00000600  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f c6 be 0f c3  |................|
-  00000610  e9 74 c9 06 f5 5b ff ff  0f 0f 0f 0f 0f 0f 0f 0f  |.t...[..........|
-  00000620  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  00000770  0f 0f 0f 0f 8f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  00000780  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  00000800
-  #
-
-Doing the same by using the downstream kernel results in different output:
-
-  # hexdump -C -n 2048 /dev/mtd0
-  00000000  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
-  *
-  00000800
-  #
-
-This patch adds some sanity checks to the code to prevent using the driver
-with unsupported ECC step/strength configurations. After the change, probing
-of the driver fails in such cases:
-
-  [    0.655038] spi-nand spi0.0: GigaDevice SPI NAND was found.
-  [    0.659159] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
-  [    0.669138] qcom_snand 79b0000.spi: only 4 bits ECC strength is supported
-  [    0.677476] nand: No suitable ECC configuration
-  [    0.689909] spi-nand spi0.0: probe with driver spi-nand failed with error -95
-
-This helps to avoid the aforementioned hassles until support for 8 bit ECC
-strength gets implemented.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Link: https://patch.msgid.link/20250501-qpic-snand-validate-ecc-v1-1-532776581a66@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 42 +++++++++++++++++++++++++++++++-----
- 1 file changed, 37 insertions(+), 5 deletions(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -249,9 +249,11 @@ static const struct mtd_ooblayout_ops qc
- static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
- {
-       struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand);
-+      struct nand_ecc_props *reqs = &nand->ecc.requirements;
-+      struct nand_ecc_props *user = &nand->ecc.user_conf;
-       struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
-       struct mtd_info *mtd = nanddev_to_mtd(nand);
--      int cwperpage, bad_block_byte;
-+      int cwperpage, bad_block_byte, ret;
-       struct qpic_ecc *ecc_cfg;
-       cwperpage = mtd->writesize / NANDC_STEP_SIZE;
-@@ -260,11 +262,39 @@ static int qcom_spi_ecc_init_ctx_pipelin
-       ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL);
-       if (!ecc_cfg)
-               return -ENOMEM;
-+
-+      if (user->step_size && user->strength) {
-+              ecc_cfg->step_size = user->step_size;
-+              ecc_cfg->strength = user->strength;
-+      } else if (reqs->step_size && reqs->strength) {
-+              ecc_cfg->step_size = reqs->step_size;
-+              ecc_cfg->strength = reqs->strength;
-+      } else {
-+              /* use defaults */
-+              ecc_cfg->step_size = NANDC_STEP_SIZE;
-+              ecc_cfg->strength = 4;
-+      }
-+
-+      if (ecc_cfg->step_size != NANDC_STEP_SIZE) {
-+              dev_err(snandc->dev,
-+                      "only %u bytes ECC step size is supported\n",
-+                      NANDC_STEP_SIZE);
-+              ret = -EOPNOTSUPP;
-+              goto err_free_ecc_cfg;
-+      }
-+
-+      if (ecc_cfg->strength != 4) {
-+              dev_err(snandc->dev,
-+                      "only 4 bits ECC strength is supported\n");
-+              ret = -EOPNOTSUPP;
-+              goto err_free_ecc_cfg;
-+      }
-+
-       snandc->qspi->oob_buf = kmalloc(mtd->writesize + mtd->oobsize,
-                                       GFP_KERNEL);
-       if (!snandc->qspi->oob_buf) {
--              kfree(ecc_cfg);
--              return -ENOMEM;
-+              ret = -ENOMEM;
-+              goto err_free_ecc_cfg;
-       }
-       memset(snandc->qspi->oob_buf, 0xff, mtd->writesize + mtd->oobsize);
-@@ -279,8 +309,6 @@ static int qcom_spi_ecc_init_ctx_pipelin
-       ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size;
-       ecc_cfg->steps = 4;
--      ecc_cfg->strength = 4;
--      ecc_cfg->step_size = 512;
-       ecc_cfg->cw_data = 516;
-       ecc_cfg->cw_size = ecc_cfg->cw_data + ecc_cfg->bytes;
-       bad_block_byte = mtd->writesize - ecc_cfg->cw_size * (cwperpage - 1) + 1;
-@@ -338,6 +366,10 @@ static int qcom_spi_ecc_init_ctx_pipelin
-               ecc_cfg->strength, ecc_cfg->step_size);
-       return 0;
-+
-+err_free_ecc_cfg:
-+      kfree(ecc_cfg);
-+      return ret;
- }
- static void qcom_spi_ecc_cleanup_ctx_pipelined(struct nand_device *nand)
diff --git a/target/linux/generic/backport-6.18/413-v6.16-spi-spi-qpic-snand-use-CW_PER_PAGE_MASK-bitmask.patch b/target/linux/generic/backport-6.18/413-v6.16-spi-spi-qpic-snand-use-CW_PER_PAGE_MASK-bitmask.patch
deleted file mode 100644 (file)
index 10c1651..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-From 2abf107dcd797c60c86e9f17319cd1658862f6b2 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Thu, 15 May 2025 20:58:05 +0200
-Subject: spi: spi-qpic-snand: use CW_PER_PAGE_MASK bitmask
-
-Change the code to use the already defined CW_PER_PAGE_MASK
-bitmask along with the FIELD_PREP() macro instead of using
-magic values.
-
-This makes the code more readable. It also syncs the affected
-codes with their counterparts in the 'qcom_nandc' driver, so it
-makes it easier to spot the differences between the two
-implementations.
-
-No functional changes intended.
-
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Reviewed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Link: https://patch.msgid.link/20250515-qpic-snand-use-bitmasks-v1-1-11729aeae73b@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 31 ++++++++++++++++---------------
- 1 file changed, 16 insertions(+), 15 deletions(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -483,7 +483,8 @@ static int qcom_spi_block_erase(struct q
-       snandc->regs->cmd = snandc->qspi->cmd;
-       snandc->regs->addr0 = snandc->qspi->addr1;
-       snandc->regs->addr1 = snandc->qspi->addr2;
--      snandc->regs->cfg0 = cpu_to_le32(ecc_cfg->cfg0_raw & ~(7 << CW_PER_PAGE));
-+      snandc->regs->cfg0 = cpu_to_le32((ecc_cfg->cfg0_raw & ~CW_PER_PAGE_MASK) |
-+                                       FIELD_PREP(CW_PER_PAGE_MASK, 0));
-       snandc->regs->cfg1 = cpu_to_le32(ecc_cfg->cfg1_raw);
-       snandc->regs->exec = cpu_to_le32(1);
-@@ -544,8 +545,8 @@ static int qcom_spi_read_last_cw(struct
-       snandc->regs->addr0 = (snandc->qspi->addr1 | cpu_to_le32(col));
-       snandc->regs->addr1 = snandc->qspi->addr2;
--      cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) |
--              0 << CW_PER_PAGE;
-+      cfg0 = (ecc_cfg->cfg0_raw & ~CW_PER_PAGE_MASK) |
-+             FIELD_PREP(CW_PER_PAGE_MASK, 0);
-       cfg1 = ecc_cfg->cfg1_raw;
-       ecc_bch_cfg = ECC_CFG_ECC_DISABLE;
-@@ -687,8 +688,8 @@ static int qcom_spi_read_cw_raw(struct q
-       qcom_clear_bam_transaction(snandc);
-       raw_cw = num_cw - 1;
--      cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) |
--                              0 << CW_PER_PAGE;
-+      cfg0 = (ecc_cfg->cfg0_raw & ~CW_PER_PAGE_MASK) |
-+             FIELD_PREP(CW_PER_PAGE_MASK, 0);
-       cfg1 = ecc_cfg->cfg1_raw;
-       ecc_bch_cfg = ECC_CFG_ECC_DISABLE;
-@@ -808,8 +809,8 @@ static int qcom_spi_read_page_ecc(struct
-       snandc->buf_start = 0;
-       qcom_clear_read_regs(snandc);
--      cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) |
--                              (num_cw - 1) << CW_PER_PAGE;
-+      cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) |
-+             FIELD_PREP(CW_PER_PAGE_MASK, num_cw - 1);
-       cfg1 = ecc_cfg->cfg1;
-       ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-@@ -904,8 +905,8 @@ static int qcom_spi_read_page_oob(struct
-       qcom_clear_read_regs(snandc);
-       qcom_clear_bam_transaction(snandc);
--      cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) |
--                              (num_cw - 1) << CW_PER_PAGE;
-+      cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) |
-+             FIELD_PREP(CW_PER_PAGE_MASK, num_cw - 1);
-       cfg1 = ecc_cfg->cfg1;
-       ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-@@ -1015,8 +1016,8 @@ static int qcom_spi_program_raw(struct q
-       int num_cw = snandc->qspi->num_cw;
-       u32 cfg0, cfg1, ecc_bch_cfg;
--      cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) |
--                      (num_cw - 1) << CW_PER_PAGE;
-+      cfg0 = (ecc_cfg->cfg0_raw & ~CW_PER_PAGE_MASK) |
-+             FIELD_PREP(CW_PER_PAGE_MASK, num_cw - 1);
-       cfg1 = ecc_cfg->cfg1_raw;
-       ecc_bch_cfg = ECC_CFG_ECC_DISABLE;
-@@ -1098,8 +1099,8 @@ static int qcom_spi_program_ecc(struct q
-       int num_cw = snandc->qspi->num_cw;
-       u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg;
--      cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) |
--                              (num_cw - 1) << CW_PER_PAGE;
-+      cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) |
-+             FIELD_PREP(CW_PER_PAGE_MASK, num_cw - 1);
-       cfg1 = ecc_cfg->cfg1;
-       ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-       ecc_buf_cfg = ecc_cfg->ecc_buf_cfg;
-@@ -1175,8 +1176,8 @@ static int qcom_spi_program_oob(struct q
-       int num_cw = snandc->qspi->num_cw;
-       u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg;
--      cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) |
--                              (num_cw - 1) << CW_PER_PAGE;
-+      cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) |
-+             FIELD_PREP(CW_PER_PAGE_MASK, num_cw - 1);
-       cfg1 = ecc_cfg->cfg1;
-       ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-       ecc_buf_cfg = ecc_cfg->ecc_buf_cfg;
diff --git a/target/linux/generic/backport-6.18/414-v6.16-spi-spi-qpic-snand-reallocate-BAM-transactions.patch b/target/linux/generic/backport-6.18/414-v6.16-spi-spi-qpic-snand-reallocate-BAM-transactions.patch
deleted file mode 100644 (file)
index 6d61016..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-From d85d0380292a7e618915069c3579ae23c7c80339 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Wed, 18 Jun 2025 22:22:49 +0200
-Subject: spi: spi-qpic-snand: reallocate BAM transactions
-
-Using the mtd_nandbiterrs module for testing the driver occasionally
-results in weird things like below.
-
-1. swiotlb mapping fails with the following message:
-
-  [   85.926216] qcom_snand 79b0000.spi: swiotlb buffer is full (sz: 4294967294 bytes), total 512 (slots), used 0 (slots)
-  [   85.932937] qcom_snand 79b0000.spi: failure in mapping desc
-  [   87.999314] qcom_snand 79b0000.spi: failure to write raw page
-  [   87.999352] mtd_nandbiterrs: error: write_oob failed (-110)
-
-  Rebooting the board after this causes a panic due to a NULL pointer
-  dereference.
-
-2. If the swiotlb mapping does not fail, rebooting the board may result
-   in a different panic due to a bad spinlock magic:
-
-  [  256.104459] BUG: spinlock bad magic on CPU#3, procd/2241
-  [  256.104488] Unable to handle kernel paging request at virtual address ffffffff0000049b
-  ...
-
-Investigating the issue revealed that these symptoms are results of
-memory corruption which is caused by out of bounds access within the
-driver.
-
-The driver uses a dynamically allocated structure for BAM transactions,
-which structure must have enough space for all possible variations of
-different flash operations initiated by the driver. The required space
-heavily depends on the actual number of 'codewords' which is calculated
-from the pagesize of the actual NAND chip.
-
-Although the qcom_nandc_alloc() function allocates memory for the BAM
-transactions during probe, but since the actual number of 'codewords'
-is not yet know the allocation is done for one 'codeword' only.
-
-Because of this, whenever the driver does a flash operation, and the
-number of the required transactions exceeds the size of the allocated
-arrays the driver accesses memory out of the allocated range.
-
-To avoid this, change the code to free the initially allocated BAM
-transactions memory, and allocate a new one once the actual number of
-'codewords' required for a given NAND chip is known.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Reviewed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Link: https://patch.msgid.link/20250618-qpic-snand-avoid-mem-corruption-v3-1-319c71296cda@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -315,6 +315,22 @@ static int qcom_spi_ecc_init_ctx_pipelin
-       mtd_set_ooblayout(mtd, &qcom_spi_ooblayout);
-+      /*
-+       * Free the temporary BAM transaction allocated initially by
-+       * qcom_nandc_alloc(), and allocate a new one based on the
-+       * updated max_cwperpage value.
-+       */
-+      qcom_free_bam_transaction(snandc);
-+
-+      snandc->max_cwperpage = cwperpage;
-+
-+      snandc->bam_txn = qcom_alloc_bam_transaction(snandc);
-+      if (!snandc->bam_txn) {
-+              dev_err(snandc->dev, "failed to allocate BAM transaction\n");
-+              ret = -ENOMEM;
-+              goto err_free_ecc_cfg;
-+      }
-+
-       ecc_cfg->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
-                       FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_data) |
-                       FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 1) |
diff --git a/target/linux/generic/backport-6.18/415-v6.16-spi-spi-qpic-snand-don-t-hardcode-ECC-steps.patch b/target/linux/generic/backport-6.18/415-v6.16-spi-spi-qpic-snand-don-t-hardcode-ECC-steps.patch
deleted file mode 100644 (file)
index eab7b79..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From f820034864dd463cdcd2bebe7940f2eca0eb4223 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Wed, 23 Jul 2025 10:06:43 +0200
-Subject: spi: spi-qpic-snand: don't hardcode ECC steps
-
-NAND devices with different page sizes requires different number
-of ECC steps, yet the qcom_spi_ecc_init_ctx_pipelined() function
-sets 4 steps in 'ecc_cfg' unconditionally.
-
-The correct number of the steps is calculated earlier in the
-function already, so use that instead of the hardcoded value.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Link: https://patch.msgid.link/20250723-qpic-snand-fix-steps-v1-1-d800695dde4c@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -308,7 +308,7 @@ static int qcom_spi_ecc_init_ctx_pipelin
-       ecc_cfg->bch_enabled = true;
-       ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size;
--      ecc_cfg->steps = 4;
-+      ecc_cfg->steps = cwperpage;
-       ecc_cfg->cw_data = 516;
-       ecc_cfg->cw_size = ecc_cfg->cw_data + ecc_cfg->bytes;
-       bad_block_byte = mtd->writesize - ecc_cfg->cw_size * (cwperpage - 1) + 1;
diff --git a/target/linux/generic/backport-6.18/416-v6.17-mtd-nand-qpic-common-add-defines-for-ECC_MODE-values.patch b/target/linux/generic/backport-6.18/416-v6.17-mtd-nand-qpic-common-add-defines-for-ECC_MODE-values.patch
deleted file mode 100644 (file)
index 7ddf15e..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-From 0dc7e656ddd54c3267b7cc18c1ac8ec1297ed02f Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Wed, 2 Jul 2025 14:35:23 +0200
-Subject: mtd: nand: qpic-common: add defines for ECC_MODE values
-
-Add defines for the values of the ECC_MODE field of the NAND_DEV0_ECC_CFG
-register and change both the 'qcom-nandc' and 'spi-qpic-snand' drivers to
-use those instead of magic numbers.
-
-No functional changes. This is in preparation for adding 8 bit ECC strength
-support for the 'spi-qpic-snand' driver.
-
-Reviewed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://patch.msgid.link/20250702-qpic-snand-8bit-ecc-v2-1-ae2c17a30bb7@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/mtd/nand/raw/qcom_nandc.c    | 6 +++---
- drivers/spi/spi-qpic-snand.c         | 2 +-
- include/linux/mtd/nand-qpic-common.h | 2 ++
- 3 files changed, 6 insertions(+), 4 deletions(-)
-
---- a/drivers/mtd/nand/raw/qcom_nandc.c
-+++ b/drivers/mtd/nand/raw/qcom_nandc.c
-@@ -1379,7 +1379,7 @@ static int qcom_nand_attach_chip(struct
-       struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-       int cwperpage, bad_block_byte, ret;
-       bool wide_bus;
--      int ecc_mode = 1;
-+      int ecc_mode = ECC_MODE_8BIT;
-       /* controller only supports 512 bytes data steps */
-       ecc->size = NANDC_STEP_SIZE;
-@@ -1400,7 +1400,7 @@ static int qcom_nand_attach_chip(struct
-       if (ecc->strength >= 8) {
-               /* 8 bit ECC defaults to BCH ECC on all platforms */
-               host->bch_enabled = true;
--              ecc_mode = 1;
-+              ecc_mode = ECC_MODE_8BIT;
-               if (wide_bus) {
-                       host->ecc_bytes_hw = 14;
-@@ -1420,7 +1420,7 @@ static int qcom_nand_attach_chip(struct
-               if (nandc->props->ecc_modes & ECC_BCH_4BIT) {
-                       /* BCH */
-                       host->bch_enabled = true;
--                      ecc_mode = 0;
-+                      ecc_mode = ECC_MODE_4BIT;
-                       if (wide_bus) {
-                               host->ecc_bytes_hw = 8;
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -365,7 +365,7 @@ static int qcom_spi_ecc_init_ctx_pipelin
-                              FIELD_PREP(ECC_SW_RESET, 0) |
-                              FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, ecc_cfg->cw_data) |
-                              FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) |
--                             FIELD_PREP(ECC_MODE_MASK, 0) |
-+                             FIELD_PREP(ECC_MODE_MASK, ECC_MODE_4BIT) |
-                              FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, ecc_cfg->ecc_bytes_hw);
-       ecc_cfg->ecc_buf_cfg = 0x203 << NUM_STEPS;
---- a/include/linux/mtd/nand-qpic-common.h
-+++ b/include/linux/mtd/nand-qpic-common.h
-@@ -101,6 +101,8 @@
- #define       ECC_SW_RESET                    BIT(1)
- #define       ECC_MODE                        4
- #define       ECC_MODE_MASK                   GENMASK(5, 4)
-+#define       ECC_MODE_4BIT                   0
-+#define       ECC_MODE_8BIT                   1
- #define       ECC_PARITY_SIZE_BYTES_BCH       8
- #define       ECC_PARITY_SIZE_BYTES_BCH_MASK  GENMASK(12, 8)
- #define       ECC_NUM_DATA_BYTES              16
diff --git a/target/linux/generic/backport-6.18/417-v6.17-spi-spi-qpic-snand-add-support-for-8-bits-ECC-strength.patch b/target/linux/generic/backport-6.18/417-v6.17-spi-spi-qpic-snand-add-support-for-8-bits-ECC-strength.patch
deleted file mode 100644 (file)
index 4eff84f..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-From 913bf8d50cbd144c87e9660b591781179182ff59 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Wed, 2 Jul 2025 14:35:24 +0200
-Subject: spi: spi-qpic-snand: add support for 8 bits ECC strength
-
-Even though the hardware supports 8 bits ECC strength, but that is not
-handled in the driver yet. This change adds the missing bits in order
-to allow using the driver with chips which require 8 bits ECC strength.
-
-No functional changes intended with regard to the existing 4 bits ECC
-strength support.
-
-Tested on an IPQ9574 platform using a GigaDevice GD5F2GM7REYIG chip.
-
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Link: https://patch.msgid.link/20250702-qpic-snand-8bit-ecc-v2-2-ae2c17a30bb7@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 21 ++++++++++++++++-----
- 1 file changed, 16 insertions(+), 5 deletions(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -283,9 +283,22 @@ static int qcom_spi_ecc_init_ctx_pipelin
-               goto err_free_ecc_cfg;
-       }
--      if (ecc_cfg->strength != 4) {
-+      switch (ecc_cfg->strength) {
-+      case 4:
-+              ecc_cfg->ecc_mode = ECC_MODE_4BIT;
-+              ecc_cfg->ecc_bytes_hw = 7;
-+              ecc_cfg->spare_bytes = 4;
-+              break;
-+
-+      case 8:
-+              ecc_cfg->ecc_mode = ECC_MODE_8BIT;
-+              ecc_cfg->ecc_bytes_hw = 13;
-+              ecc_cfg->spare_bytes = 2;
-+              break;
-+
-+      default:
-               dev_err(snandc->dev,
--                      "only 4 bits ECC strength is supported\n");
-+                      "only 4 or 8 bits ECC strength is supported\n");
-               ret = -EOPNOTSUPP;
-               goto err_free_ecc_cfg;
-       }
-@@ -302,8 +315,6 @@ static int qcom_spi_ecc_init_ctx_pipelin
-       nand->ecc.ctx.priv = ecc_cfg;
-       snandc->qspi->mtd = mtd;
--      ecc_cfg->ecc_bytes_hw = 7;
--      ecc_cfg->spare_bytes = 4;
-       ecc_cfg->bbm_size = 1;
-       ecc_cfg->bch_enabled = true;
-       ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size;
-@@ -365,7 +376,7 @@ static int qcom_spi_ecc_init_ctx_pipelin
-                              FIELD_PREP(ECC_SW_RESET, 0) |
-                              FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, ecc_cfg->cw_data) |
-                              FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) |
--                             FIELD_PREP(ECC_MODE_MASK, ECC_MODE_4BIT) |
-+                             FIELD_PREP(ECC_MODE_MASK, ecc_cfg->ecc_mode) |
-                              FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, ecc_cfg->ecc_bytes_hw);
-       ecc_cfg->ecc_buf_cfg = 0x203 << NUM_STEPS;
diff --git a/target/linux/generic/backport-6.18/418-v6.17-spi-spi-qpic-snand-use-correct-CW_PER_PAGE-value-for.patch b/target/linux/generic/backport-6.18/418-v6.17-spi-spi-qpic-snand-use-correct-CW_PER_PAGE-value-for.patch
deleted file mode 100644 (file)
index b67645e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From 6bc829220b33da8522572cc50fdf5067c51d3bf3 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Fri, 1 Aug 2025 09:58:35 +0200
-Subject: spi: spi-qpic-snand: use correct CW_PER_PAGE value for OOB write
-
-The qcom_spi_program_oob() function uses only the last codeword to write
-the OOB data into the flash, but it sets the CW_PER_PAGE field in the
-CFG0 register as it would use all codewords.
-
-It seems that this confuses the hardware somehow, and any access to the
-flash fails with a timeout error after the function is called. The problem
-can be easily reproduced with the following commands:
-
-    # dd if=/dev/zero bs=2176 count=1 > /tmp/test.bin
-    1+0 records in
-    1+0 records out
-    # flash_erase /dev/mtd4 0 0
-    Erasing 128 Kibyte @ 0 -- 100 % complete
-    # nandwrite -O /dev/mtd4 /tmp/test.bin
-    Writing data to block 0 at offset 0x0
-    # nanddump -o /dev/mtd4 >/dev/null
-    ECC failed: 0
-    ECC corrected: 0
-    Number of bad blocks: 0
-    Number of bbt blocks: 0
-    Block size 131072, page size 2048, OOB size 128
-    Dumping data starting at 0x00000000 and ending at 0x00020000...
-    [   33.197605] qcom_snand 79b0000.spi: failure to read oob
-    libmtd: error!: MEMREADOOB64 ioctl failed for mtd4, offset 0 (eraseblock 0)
-            error 110 (Operation timed out)
-    [   35.277582] qcom_snand 79b0000.spi: failure in submitting cmd descriptor
-    libmtd: error!: cannot read 2048 bytes from mtd4 (eraseblock 0, offset 2048)
-            error 110 (Operation timed out)
-    nanddump: error!: mtd_read
-
-Change the code to use the correct CW_PER_PAGE value to avoid this.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Link: https://patch.msgid.link/20250801-qpic-snand-oob-cwpp-fix-v1-1-f5a41b86af2e@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -1204,7 +1204,7 @@ static int qcom_spi_program_oob(struct q
-       u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg;
-       cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) |
--             FIELD_PREP(CW_PER_PAGE_MASK, num_cw - 1);
-+             FIELD_PREP(CW_PER_PAGE_MASK, 0);
-       cfg1 = ecc_cfg->cfg1;
-       ecc_bch_cfg = ecc_cfg->ecc_bch_cfg;
-       ecc_buf_cfg = ecc_cfg->ecc_buf_cfg;
diff --git a/target/linux/generic/backport-6.18/419-v6.17-spi-spi-qpic-snand-fix-calculating-of-ECC-OOB-region.patch b/target/linux/generic/backport-6.18/419-v6.17-spi-spi-qpic-snand-fix-calculating-of-ECC-OOB-region.patch
deleted file mode 100644 (file)
index 35d5d30..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-From 13d0fe84a214658254a7412b2b46ec1507dc51f0 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Tue, 5 Aug 2025 18:05:42 +0200
-Subject: spi: spi-qpic-snand: fix calculating of ECC OOB regions' properties
-
-The OOB layout used by the driver has two distinct regions which contains
-hardware specific ECC data, yet the qcom_spi_ooblayout_ecc() function sets
-the same offset and length values for both regions which is clearly wrong.
-
-Change the code to calculate the correct values for both regions.
-
-For reference, the following table shows the computed offset and length
-values for various OOB size/ECC strength configurations:
-
-                              +-----------------+-----------------+
-                              |before the change| after the change|
-  +-------+----------+--------+--------+--------+--------+--------+
-  |  OOB  |   ECC    | region | region | region | region | region |
-  |  size | strength | index  | offset | length | offset | length |
-  +-------+----------+--------+--------+--------+--------+--------+
-  |  128  |     8    |    0   |   113  |   15   |    0   |   49   |
-  |       |          |    1   |   113  |   15   |   65   |   63   |
-  +-------+----------+--------+--------+--------+--------+--------+
-  |  128  |     4    |    0   |   117  |   11   |    0   |   37   |
-  |       |          |    1   |   117  |   11   |   53   |   75   |
-  +-------+----------+--------+--------+--------+--------+--------+
-  |   64  |     4    |    0   |    53  |   11   |    0   |   37   |
-  |       |          |    1   |    53  |   11   |   53   |   11   |
-  +-------+----------+--------+--------+--------+--------+--------+
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
-Link: https://patch.msgid.link/20250805-qpic-snand-oob-ecc-fix-v2-1-e6f811c70d6f@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 20 ++++++++++++++------
- 1 file changed, 14 insertions(+), 6 deletions(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -216,13 +216,21 @@ static int qcom_spi_ooblayout_ecc(struct
-       struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand);
-       struct qpic_ecc *qecc = snandc->qspi->ecc;
--      if (section > 1)
--              return -ERANGE;
-+      switch (section) {
-+      case 0:
-+              oobregion->offset = 0;
-+              oobregion->length = qecc->bytes * (qecc->steps - 1) +
-+                                  qecc->bbm_size;
-+              return 0;
-+      case 1:
-+              oobregion->offset = qecc->bytes * (qecc->steps - 1) +
-+                                  qecc->bbm_size +
-+                                  qecc->steps * 4;
-+              oobregion->length = mtd->oobsize - oobregion->offset;
-+              return 0;
-+      }
--      oobregion->length = qecc->ecc_bytes_hw + qecc->spare_bytes;
--      oobregion->offset = mtd->oobsize - oobregion->length;
--
--      return 0;
-+      return -ERANGE;
- }
- static int qcom_spi_ooblayout_free(struct mtd_info *mtd, int section,
diff --git a/target/linux/generic/backport-6.18/420-01-v6.16-mtd-rawnand-brcmnand-remove-unused-parameters.patch b/target/linux/generic/backport-6.18/420-01-v6.16-mtd-rawnand-brcmnand-remove-unused-parameters.patch
deleted file mode 100644 (file)
index 3bc6038..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-From 56fce75470041b5b0d92ae10637416e1a4cceb1b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Wed, 14 May 2025 08:14:54 +0200
-Subject: [PATCH] mtd: rawnand: brcmnand: remove unused parameters
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-last_cmd and last_byte are now unused brcmnand_host members.
-last_addr is only written and never read so we can remove it too.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Reviewed-by: William Zhang <william.zhang@broadcom.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 24 ++++++------------------
- 1 file changed, 6 insertions(+), 18 deletions(-)
-
---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-@@ -310,9 +310,6 @@ struct brcmnand_host {
-       struct platform_device  *pdev;
-       int                     cs;
--      unsigned int            last_cmd;
--      unsigned int            last_byte;
--      u64                     last_addr;
-       struct brcmnand_cfg     hwcfg;
-       struct brcmnand_controller *ctrl;
- };
-@@ -2233,14 +2230,11 @@ static int brcmnand_read_page(struct nan
-                             int oob_required, int page)
- {
-       struct mtd_info *mtd = nand_to_mtd(chip);
--      struct brcmnand_host *host = nand_get_controller_data(chip);
-       u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL;
-       u64 addr = (u64)page << chip->page_shift;
--      host->last_addr = addr;
--
--      return brcmnand_read(mtd, chip, host->last_addr,
--                      mtd->writesize >> FC_SHIFT, (u32 *)buf, oob);
-+      return brcmnand_read(mtd, chip, addr, mtd->writesize >> FC_SHIFT,
-+                           (u32 *)buf, oob);
- }
- static int brcmnand_read_page_raw(struct nand_chip *chip, uint8_t *buf,
-@@ -2252,11 +2246,9 @@ static int brcmnand_read_page_raw(struct
-       int ret;
-       u64 addr = (u64)page << chip->page_shift;
--      host->last_addr = addr;
--
-       brcmnand_set_ecc_enabled(host, 0);
--      ret = brcmnand_read(mtd, chip, host->last_addr,
--                      mtd->writesize >> FC_SHIFT, (u32 *)buf, oob);
-+      ret = brcmnand_read(mtd, chip, addr, mtd->writesize >> FC_SHIFT,
-+                          (u32 *)buf, oob);
-       brcmnand_set_ecc_enabled(host, 1);
-       return ret;
- }
-@@ -2363,13 +2355,10 @@ static int brcmnand_write_page(struct na
-                              int oob_required, int page)
- {
-       struct mtd_info *mtd = nand_to_mtd(chip);
--      struct brcmnand_host *host = nand_get_controller_data(chip);
-       void *oob = oob_required ? chip->oob_poi : NULL;
-       u64 addr = (u64)page << chip->page_shift;
--      host->last_addr = addr;
--
--      return brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob);
-+      return brcmnand_write(mtd, chip, addr, (const u32 *)buf, oob);
- }
- static int brcmnand_write_page_raw(struct nand_chip *chip, const uint8_t *buf,
-@@ -2381,9 +2370,8 @@ static int brcmnand_write_page_raw(struc
-       u64 addr = (u64)page << chip->page_shift;
-       int ret = 0;
--      host->last_addr = addr;
-       brcmnand_set_ecc_enabled(host, 0);
--      ret = brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob);
-+      ret = brcmnand_write(mtd, chip, addr, (const u32 *)buf, oob);
-       brcmnand_set_ecc_enabled(host, 1);
-       return ret;
diff --git a/target/linux/generic/backport-6.18/420-02-v6.16-mtd-nand-brcmnand-fix-NAND-timeout-when-accessing-eM.patch b/target/linux/generic/backport-6.18/420-02-v6.16-mtd-nand-brcmnand-fix-NAND-timeout-when-accessing-eM.patch
deleted file mode 100644 (file)
index d3dbde8..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 528b541b71cf03e263272b051b70696f92258e9d Mon Sep 17 00:00:00 2001
-From: David Regan <dregan@broadcom.com>
-Date: Thu, 22 May 2025 10:25:17 -0700
-Subject: [PATCH] mtd: nand: brcmnand: fix NAND timeout when accessing eMMC
-
-When booting a board to NAND and accessing NAND while eMMC
-transactions are occurring the NAND will sometimes timeout. This
-is due to both NAND and eMMC controller sharing the same data bus
-on BCMBCA chips. Fix is to extend NAND timeout to allow eMMC
-transactions time to complete.
-
-Signed-off-by: David Regan <dregan@broadcom.com>
-Reviewed-by: William Zhang <william.zhang@broadcom.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-@@ -101,7 +101,7 @@ struct brcm_nand_dma_desc {
- #define BRCMNAND_MIN_DEVSIZE  (4ULL * 1024 * 1024)
- #define NAND_CTRL_RDY                 (INTFC_CTLR_READY | INTFC_FLASH_READY)
--#define NAND_POLL_STATUS_TIMEOUT_MS   100
-+#define NAND_POLL_STATUS_TIMEOUT_MS   500
- #define EDU_CMD_WRITE          0x00
- #define EDU_CMD_READ           0x01
diff --git a/target/linux/generic/backport-6.18/420-03-v6.16-mtd-rawnand-brcmnand-legacy-exec_op-implementation.patch b/target/linux/generic/backport-6.18/420-03-v6.16-mtd-rawnand-brcmnand-legacy-exec_op-implementation.patch
deleted file mode 100644 (file)
index 6c75c2b..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-From 3bfb22cecfe6b6f0d8ee56ef4b533cf68599c5d9 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Wed, 21 May 2025 10:03:25 +0200
-Subject: [PATCH] mtd: rawnand: brcmnand: legacy exec_op implementation
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Commit 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
-removed legacy interface functions, breaking < v5.0 controllers support.
-In order to fix older controllers we need to add an alternative exec_op
-implementation which doesn't rely on low level registers.
-
-Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: David Regan <dregan@broadcom.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Reviewed-by: William Zhang <william.zhang@broadcom.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 222 ++++++++++++++++++++++-
- 1 file changed, 215 insertions(+), 7 deletions(-)
-
---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
-@@ -65,6 +65,7 @@ module_param(wp_on, int, 0444);
- #define CMD_PARAMETER_READ            0x0e
- #define CMD_PARAMETER_CHANGE_COL      0x0f
- #define CMD_LOW_LEVEL_OP              0x10
-+#define CMD_NOT_SUPPORTED             0xff
- struct brcm_nand_dma_desc {
-       u32 next_desc;
-@@ -199,6 +200,30 @@ static const u16 flash_dma_regs_v4[] = {
-       [FLASH_DMA_CURRENT_DESC_EXT]    = 0x34,
- };
-+/* Native command conversion for legacy controllers (< v5.0) */
-+static const u8 native_cmd_conv[] = {
-+      [NAND_CMD_READ0]        = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_READ1]        = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_RNDOUT]       = CMD_PARAMETER_CHANGE_COL,
-+      [NAND_CMD_PAGEPROG]     = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_READOOB]      = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_ERASE1]       = CMD_BLOCK_ERASE,
-+      [NAND_CMD_STATUS]       = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_SEQIN]        = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_RNDIN]        = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_READID]       = CMD_DEVICE_ID_READ,
-+      [NAND_CMD_ERASE2]       = CMD_NULL,
-+      [NAND_CMD_PARAM]        = CMD_PARAMETER_READ,
-+      [NAND_CMD_GET_FEATURES] = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_SET_FEATURES] = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_RESET]        = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_READSTART]    = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_READCACHESEQ] = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_READCACHEEND] = CMD_NOT_SUPPORTED,
-+      [NAND_CMD_RNDOUTSTART]  = CMD_NULL,
-+      [NAND_CMD_CACHEDPROG]   = CMD_NOT_SUPPORTED,
-+};
-+
- /* Controller feature flags */
- enum {
-       BRCMNAND_HAS_1K_SECTORS                 = BIT(0),
-@@ -237,6 +262,12 @@ struct brcmnand_controller {
-       /* List of NAND hosts (one for each chip-select) */
-       struct list_head host_list;
-+      /* Functions to be called from exec_op */
-+      int (*check_instr)(struct nand_chip *chip,
-+                         const struct nand_operation *op);
-+      int (*exec_instr)(struct nand_chip *chip,
-+                        const struct nand_operation *op);
-+
-       /* EDU info, per-transaction */
-       const u16               *edu_offsets;
-       void __iomem            *edu_base;
-@@ -2478,18 +2509,190 @@ static int brcmnand_op_is_reset(const st
-       return 0;
- }
-+static int brcmnand_check_instructions(struct nand_chip *chip,
-+                                     const struct nand_operation *op)
-+{
-+      return 0;
-+}
-+
-+static int brcmnand_exec_instructions(struct nand_chip *chip,
-+                                    const struct nand_operation *op)
-+{
-+      struct brcmnand_host *host = nand_get_controller_data(chip);
-+      unsigned int i;
-+      int ret = 0;
-+
-+      for (i = 0; i < op->ninstrs; i++) {
-+              ret = brcmnand_exec_instr(host, i, op);
-+              if (ret)
-+                      break;
-+      }
-+
-+      return ret;
-+}
-+
-+static int brcmnand_check_instructions_legacy(struct nand_chip *chip,
-+                                            const struct nand_operation *op)
-+{
-+      const struct nand_op_instr *instr;
-+      unsigned int i;
-+      u8 cmd;
-+
-+      for (i = 0; i < op->ninstrs; i++) {
-+              instr = &op->instrs[i];
-+
-+              switch (instr->type) {
-+              case NAND_OP_CMD_INSTR:
-+                      cmd = native_cmd_conv[instr->ctx.cmd.opcode];
-+                      if (cmd == CMD_NOT_SUPPORTED)
-+                              return -EOPNOTSUPP;
-+                      break;
-+              case NAND_OP_ADDR_INSTR:
-+              case NAND_OP_DATA_IN_INSTR:
-+              case NAND_OP_WAITRDY_INSTR:
-+                      break;
-+              default:
-+                      return -EOPNOTSUPP;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int brcmnand_exec_instructions_legacy(struct nand_chip *chip,
-+                                           const struct nand_operation *op)
-+{
-+      struct mtd_info *mtd = nand_to_mtd(chip);
-+      struct brcmnand_host *host = nand_get_controller_data(chip);
-+      struct brcmnand_controller *ctrl = host->ctrl;
-+      const struct nand_op_instr *instr;
-+      unsigned int i, j;
-+      u8 cmd = CMD_NULL, last_cmd = CMD_NULL;
-+      int ret = 0;
-+      u64 last_addr;
-+
-+      for (i = 0; i < op->ninstrs; i++) {
-+              instr = &op->instrs[i];
-+
-+              if (instr->type == NAND_OP_CMD_INSTR) {
-+                      cmd = native_cmd_conv[instr->ctx.cmd.opcode];
-+                      if (cmd == CMD_NOT_SUPPORTED) {
-+                              dev_err(ctrl->dev, "unsupported cmd=%d\n",
-+                                      instr->ctx.cmd.opcode);
-+                              ret = -EOPNOTSUPP;
-+                              break;
-+                      }
-+              } else if (instr->type == NAND_OP_ADDR_INSTR) {
-+                      u64 addr = 0;
-+
-+                      if (cmd == CMD_NULL)
-+                              continue;
-+
-+                      if (instr->ctx.addr.naddrs > 8) {
-+                              dev_err(ctrl->dev, "unsupported naddrs=%u\n",
-+                                      instr->ctx.addr.naddrs);
-+                              ret = -EOPNOTSUPP;
-+                              break;
-+                      }
-+
-+                      for (j = 0; j < instr->ctx.addr.naddrs; j++)
-+                              addr |= (instr->ctx.addr.addrs[j]) << (j << 3);
-+
-+                      if (cmd == CMD_BLOCK_ERASE)
-+                              addr <<= chip->page_shift;
-+                      else if (cmd == CMD_PARAMETER_CHANGE_COL)
-+                              addr &= ~((u64)(FC_BYTES - 1));
-+
-+                      brcmnand_set_cmd_addr(mtd, addr);
-+                      brcmnand_send_cmd(host, cmd);
-+                      last_addr = addr;
-+                      last_cmd = cmd;
-+                      cmd = CMD_NULL;
-+                      brcmnand_waitfunc(chip);
-+
-+                      if (last_cmd == CMD_PARAMETER_READ ||
-+                          last_cmd == CMD_PARAMETER_CHANGE_COL) {
-+                              /* Copy flash cache word-wise */
-+                              u32 *flash_cache = (u32 *)ctrl->flash_cache;
-+
-+                              brcmnand_soc_data_bus_prepare(ctrl->soc, true);
-+
-+                              /*
-+                               * Must cache the FLASH_CACHE now, since changes in
-+                               * SECTOR_SIZE_1K may invalidate it
-+                               */
-+                              for (j = 0; j < FC_WORDS; j++)
-+                                      /*
-+                                       * Flash cache is big endian for parameter pages, at
-+                                       * least on STB SoCs
-+                                       */
-+                                      flash_cache[j] = be32_to_cpu(brcmnand_read_fc(ctrl, j));
-+
-+                              brcmnand_soc_data_bus_unprepare(ctrl->soc, true);
-+                      }
-+              } else if (instr->type == NAND_OP_DATA_IN_INSTR) {
-+                      u8 *in = instr->ctx.data.buf.in;
-+
-+                      if (last_cmd == CMD_DEVICE_ID_READ) {
-+                              u32 val;
-+
-+                              if (instr->ctx.data.len > 8) {
-+                                      dev_err(ctrl->dev, "unsupported len=%u\n",
-+                                              instr->ctx.data.len);
-+                                      ret = -EOPNOTSUPP;
-+                                      break;
-+                              }
-+
-+                              for (j = 0; j < instr->ctx.data.len; j++) {
-+                                      if (j == 0)
-+                                              val = brcmnand_read_reg(ctrl, BRCMNAND_ID);
-+                                      else if (j == 4)
-+                                              val = brcmnand_read_reg(ctrl, BRCMNAND_ID_EXT);
-+
-+                                      in[j] = (val >> (24 - ((j % 4) << 3))) & 0xff;
-+                              }
-+                      } else if (last_cmd == CMD_PARAMETER_READ ||
-+                                 last_cmd == CMD_PARAMETER_CHANGE_COL) {
-+                              u64 addr;
-+                              u32 offs;
-+
-+                              for (j = 0; j < instr->ctx.data.len; j++) {
-+                                      addr = last_addr + j;
-+                                      offs = addr & (FC_BYTES - 1);
-+
-+                                      if (j > 0 && offs == 0)
-+                                              nand_change_read_column_op(chip, addr, NULL, 0,
-+                                                                         false);
-+
-+                                      in[j] = ctrl->flash_cache[offs];
-+                              }
-+                      }
-+              } else if (instr->type == NAND_OP_WAITRDY_INSTR) {
-+                      ret = bcmnand_ctrl_poll_status(host, NAND_CTRL_RDY, NAND_CTRL_RDY, 0);
-+                      if (ret)
-+                              break;
-+              } else {
-+                      dev_err(ctrl->dev, "unsupported instruction type: %d\n", instr->type);
-+                      ret = -EOPNOTSUPP;
-+                      break;
-+              }
-+      }
-+
-+      return ret;
-+}
-+
- static int brcmnand_exec_op(struct nand_chip *chip,
-                           const struct nand_operation *op,
-                           bool check_only)
- {
-       struct brcmnand_host *host = nand_get_controller_data(chip);
-+      struct brcmnand_controller *ctrl = host->ctrl;
-       struct mtd_info *mtd = nand_to_mtd(chip);
-       u8 *status;
--      unsigned int i;
-       int ret = 0;
-       if (check_only)
--              return 0;
-+              return ctrl->check_instr(chip, op);
-       if (brcmnand_op_is_status(op)) {
-               status = op->instrs[1].ctx.data.buf.in;
-@@ -2513,11 +2716,7 @@ static int brcmnand_exec_op(struct nand_
-       if (op->deassert_wp)
-               brcmnand_wp(mtd, 0);
--      for (i = 0; i < op->ninstrs; i++) {
--              ret = brcmnand_exec_instr(host, i, op);
--              if (ret)
--                      break;
--      }
-+      ret = ctrl->exec_instr(chip, op);
-       if (op->deassert_wp)
-               brcmnand_wp(mtd, 1);
-@@ -3130,6 +3329,15 @@ int brcmnand_probe(struct platform_devic
-       if (ret)
-               goto err;
-+      /* Only v5.0+ controllers have low level ops support */
-+      if (ctrl->nand_version >= 0x0500) {
-+              ctrl->check_instr = brcmnand_check_instructions;
-+              ctrl->exec_instr = brcmnand_exec_instructions;
-+      } else {
-+              ctrl->check_instr = brcmnand_check_instructions_legacy;
-+              ctrl->exec_instr = brcmnand_exec_instructions_legacy;
-+      }
-+
-       /*
-        * Most chips have this cache at a fixed offset within 'nand' block.
-        * Some must specify this region separately.
diff --git a/target/linux/generic/backport-6.18/422-v6.17-spi-spi-qpic-snand-unregister-ECC-engine-on-probe-er.patch b/target/linux/generic/backport-6.18/422-v6.17-spi-spi-qpic-snand-unregister-ECC-engine-on-probe-er.patch
deleted file mode 100644 (file)
index 46184b5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From 1991a458528588ff34e98b6365362560d208710f Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <j4g8y7@gmail.com>
-Date: Wed, 3 Sep 2025 13:56:24 +0200
-Subject: spi: spi-qpic-snand: unregister ECC engine on probe error and device
- remove
-
-The on-host hardware ECC engine remains registered both when
-the spi_register_controller() function returns with an error
-and also on device removal.
-
-Change the qcom_spi_probe() function to unregister the engine
-on the error path, and add the missing unregistering call to
-qcom_spi_remove() to avoid possible use-after-free issues.
-
-Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
-Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
-Message-ID: <20250903-qpic-snand-unregister-ecceng-v1-1-ef5387b0abdc@gmail.com>
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-qpic-snand.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/spi-qpic-snand.c
-+++ b/drivers/spi/spi-qpic-snand.c
-@@ -1632,11 +1632,13 @@ static int qcom_spi_probe(struct platfor
-       ret = spi_register_controller(ctlr);
-       if (ret) {
-               dev_err(&pdev->dev, "spi_register_controller failed.\n");
--              goto err_spi_init;
-+              goto err_register_controller;
-       }
-       return 0;
-+err_register_controller:
-+      nand_ecc_unregister_on_host_hw_engine(&snandc->qspi->ecc_eng);
- err_spi_init:
-       qcom_nandc_unalloc(snandc);
- err_snand_alloc:
-@@ -1658,7 +1660,7 @@ static void qcom_spi_remove(struct platf
-       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       spi_unregister_controller(ctlr);
--
-+      nand_ecc_unregister_on_host_hw_engine(&snandc->qspi->ecc_eng);
-       qcom_nandc_unalloc(snandc);
-       clk_disable_unprepare(snandc->aon_clk);
diff --git a/target/linux/generic/backport-6.18/429-01-v6.18-mtd-spinand-fix-direct-mapping-creation-sizes.patch b/target/linux/generic/backport-6.18/429-01-v6.18-mtd-spinand-fix-direct-mapping-creation-sizes.patch
deleted file mode 100644 (file)
index 6abc202..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-From e4a0cf9f1d90e6888e5373da3314f761024f6c97 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Thu, 18 Sep 2025 00:53:59 +0300
-Subject: mtd: spinand: fix direct mapping creation sizes
-
-Continuous mode is only supported for data reads, thus writing
-requires only single flash page mapping.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/spi/core.c | 14 +++++++-------
- 1 file changed, 7 insertions(+), 7 deletions(-)
-
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -1036,18 +1036,13 @@ static int spinand_create_dirmap(struct
-                                unsigned int plane)
- {
-       struct nand_device *nand = spinand_to_nand(spinand);
--      struct spi_mem_dirmap_info info = {
--              .length = nanddev_page_size(nand) +
--                        nanddev_per_page_oobsize(nand),
--      };
-+      struct spi_mem_dirmap_info info = { 0 };
-       struct spi_mem_dirmap_desc *desc;
--      if (spinand->cont_read_possible)
--              info.length = nanddev_eraseblock_size(nand);
--
-       /* The plane number is passed in MSB just above the column address */
-       info.offset = plane << fls(nand->memorg.pagesize);
-+      info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
-       info.op_tmpl = *spinand->op_templates.update_cache;
-       desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
-                                         spinand->spimem, &info);
-@@ -1056,6 +1051,8 @@ static int spinand_create_dirmap(struct
-       spinand->dirmaps[plane].wdesc = desc;
-+      if (spinand->cont_read_possible)
-+              info.length = nanddev_eraseblock_size(nand);
-       info.op_tmpl = *spinand->op_templates.read_cache;
-       desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
-                                         spinand->spimem, &info);
-@@ -1071,6 +1068,7 @@ static int spinand_create_dirmap(struct
-               return 0;
-       }
-+      info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
-       info.op_tmpl = *spinand->op_templates.update_cache;
-       info.op_tmpl.data.ecc = true;
-       desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
-@@ -1080,6 +1078,8 @@ static int spinand_create_dirmap(struct
-       spinand->dirmaps[plane].wdesc_ecc = desc;
-+      if (spinand->cont_read_possible)
-+              info.length = nanddev_eraseblock_size(nand);
-       info.op_tmpl = *spinand->op_templates.read_cache;
-       info.op_tmpl.data.ecc = true;
-       desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
diff --git a/target/linux/generic/backport-6.18/429-02-v6.18-mtd-spinand-try-a-regular-dirmap-if-creating-a-di.patch b/target/linux/generic/backport-6.18/429-02-v6.18-mtd-spinand-try-a-regular-dirmap-if-creating-a-di.patch
deleted file mode 100644 (file)
index cc94e6d..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-From 004f8ea0d9917398aabff7388b3bf62a84a4088b Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Thu, 18 Sep 2025 00:54:00 +0300
-Subject: mtd: spinand: try a regular dirmap if creating a dirmap for
- continuous reading fails
-
-Continuous reading may result in multiple flash pages reading in one
-operation. Typically only one flash page has read/written (a little bit
-more than 2-4 Kb), but continuous reading requires the spi controller
-to read up to 512 Kb in one operation without toggling CS in beetween.
-
-Roughly speaking spi controllers can be divided on 2 categories:
- * spi controllers without dirmap acceleration support
- * spi controllers with dirmap acceleration support
-
-Firt of them will have issues with continuous reading if restriction on
-the transfer length is implemented in the adjust_op_size() handler.
-Second group often supports acceleration of single page only reading.
-Thus enabling of continuous reading can break flash reading.
-
-This patch tries to create dirmap for continuous reading first and
-fallback to regular reading if spi controller refuses to create it.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/spi/core.c | 43 ++++++++++++++++++++++++++++++-------
- 1 file changed, 35 insertions(+), 8 deletions(-)
-
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -1032,6 +1032,39 @@ static int spinand_mtd_block_isreserved(
-       return ret;
- }
-+static struct spi_mem_dirmap_desc *spinand_create_rdesc(
-+                                      struct spinand_device *spinand,
-+                                      struct spi_mem_dirmap_info *info)
-+{
-+      struct nand_device *nand = spinand_to_nand(spinand);
-+      struct spi_mem_dirmap_desc *desc = NULL;
-+
-+      if (spinand->cont_read_possible) {
-+              /*
-+               * spi controller may return an error if info->length is
-+               * too large
-+               */
-+              info->length = nanddev_eraseblock_size(nand);
-+              desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
-+                                                spinand->spimem, info);
-+      }
-+
-+      if (IS_ERR_OR_NULL(desc)) {
-+              /*
-+               * continuous reading is not supported by flash or
-+               * its spi controller, use regular reading
-+               */
-+              spinand->cont_read_possible = false;
-+
-+              info->length = nanddev_page_size(nand) +
-+                             nanddev_per_page_oobsize(nand);
-+              desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
-+                                                spinand->spimem, info);
-+      }
-+
-+      return desc;
-+}
-+
- static int spinand_create_dirmap(struct spinand_device *spinand,
-                                unsigned int plane)
- {
-@@ -1051,11 +1084,8 @@ static int spinand_create_dirmap(struct
-       spinand->dirmaps[plane].wdesc = desc;
--      if (spinand->cont_read_possible)
--              info.length = nanddev_eraseblock_size(nand);
-       info.op_tmpl = *spinand->op_templates.read_cache;
--      desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
--                                        spinand->spimem, &info);
-+      desc = spinand_create_rdesc(spinand, &info);
-       if (IS_ERR(desc))
-               return PTR_ERR(desc);
-@@ -1078,12 +1108,9 @@ static int spinand_create_dirmap(struct
-       spinand->dirmaps[plane].wdesc_ecc = desc;
--      if (spinand->cont_read_possible)
--              info.length = nanddev_eraseblock_size(nand);
-       info.op_tmpl = *spinand->op_templates.read_cache;
-       info.op_tmpl.data.ecc = true;
--      desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
--                                        spinand->spimem, &info);
-+      desc = spinand_create_rdesc(spinand, &info);
-       if (IS_ERR(desc))
-               return PTR_ERR(desc);
diff --git a/target/linux/generic/backport-6.18/429-03-v6.18-mtd-spinand-repeat-reading-in-regular-mode-if-con.patch b/target/linux/generic/backport-6.18/429-03-v6.18-mtd-spinand-repeat-reading-in-regular-mode-if-con.patch
deleted file mode 100644 (file)
index 38d5712..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-From 010dc7f2dd6a0078ade3f88f627ed5fbf45ceb94 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Thu, 18 Sep 2025 00:54:01 +0300
-Subject: mtd: spinand: repeat reading in regular mode if continuous reading
- fails
-
-Continuous reading may result in multiple flash pages reading in one
-operation. Unfortunately, not all spinand controllers support such
-large reading. They will read less data. Unfortunately, the operation
-can't be continued.
-
-In this case:
- * disable continuous reading on this (not good enough) spi controller
- * repeat reading in regular mode.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/spi/core.c | 25 +++++++++++++++++++++----
- 1 file changed, 21 insertions(+), 4 deletions(-)
-
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -427,8 +427,16 @@ static int spinand_read_from_cache_op(st
-                * Dirmap accesses are allowed to toggle the CS.
-                * Toggling the CS during a continuous read is forbidden.
-                */
--              if (nbytes && req->continuous)
--                      return -EIO;
-+              if (nbytes && req->continuous) {
-+                      /*
-+                       * Spi controller with broken support of continuous
-+                       * reading was detected. Disable future use of
-+                       * continuous reading and return -EAGAIN to retry
-+                       * reading within regular mode.
-+                       */
-+                      spinand->cont_read_possible = false;
-+                      return -EAGAIN;
-+              }
-       }
-       if (req->datalen)
-@@ -849,10 +857,19 @@ static int spinand_mtd_read(struct mtd_i
-       old_stats = mtd->ecc_stats;
--      if (spinand_use_cont_read(mtd, from, ops))
-+      if (spinand_use_cont_read(mtd, from, ops)) {
-               ret = spinand_mtd_continuous_page_read(mtd, from, ops, &max_bitflips);
--      else
-+              if (ret == -EAGAIN && !spinand->cont_read_possible) {
-+                      /*
-+                       * Spi controller with broken support of continuous
-+                       * reading was detected (see spinand_read_from_cache_op()),
-+                       * repeat reading in regular mode.
-+                       */
-+                      ret = spinand_mtd_regular_page_read(mtd, from, ops, &max_bitflips);
-+              }
-+      } else {
-               ret = spinand_mtd_regular_page_read(mtd, from, ops, &max_bitflips);
-+      }
-       if (ops->stats) {
-               ops->stats->uncorrectable_errors +=
diff --git a/target/linux/generic/backport-6.18/430-v6.14-mtd-spinand-Introduce-a-way-to-avoid-raw-access.patch b/target/linux/generic/backport-6.18/430-v6.14-mtd-spinand-Introduce-a-way-to-avoid-raw-access.patch
deleted file mode 100644 (file)
index 094d89b..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-From 6d9d6ab3a82af50e36e13e7bc8e2d1b970e39f79 Mon Sep 17 00:00:00 2001
-From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
-Date: Tue, 3 Dec 2024 11:46:49 +0900
-Subject: [PATCH 1/1] mtd: spinand: Introduce a way to avoid raw access
-
-SkyHigh spinand device has ECC enable bit in configuration register but
-it must be always enabled. If ECC is disabled, read and write ops
-results in undetermined state. For such devices, a way to avoid raw
-access is needed.
-
-Introduce SPINAND_NO_RAW_ACCESS flag to advertise the device does not
-support raw access. In such devices, the on-die ECC engine ops returns
-error to I/O request in raw mode.
-
-Checking and marking BBM need to be cared as special case, by adding
-fallback mechanism that tries read/write OOB with ECC enabled.
-
-Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/spi/core.c | 22 ++++++++++++++++++++--
- include/linux/mtd/spinand.h |  1 +
- 2 files changed, 21 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -294,6 +294,9 @@ static int spinand_ondie_ecc_prepare_io_
-       struct spinand_device *spinand = nand_to_spinand(nand);
-       bool enable = (req->mode != MTD_OPS_RAW);
-+      if (!enable && spinand->flags & SPINAND_NO_RAW_ACCESS)
-+              return -EOPNOTSUPP;
-+
-       memset(spinand->oobbuf, 0xff, nanddev_per_page_oobsize(nand));
-       /* Only enable or disable the engine */
-@@ -929,9 +932,17 @@ static bool spinand_isbad(struct nand_de
-               .oobbuf.in = marker,
-               .mode = MTD_OPS_RAW,
-       };
-+      int ret;
-       spinand_select_target(spinand, pos->target);
--      spinand_read_page(spinand, &req);
-+
-+      ret = spinand_read_page(spinand, &req);
-+      if (ret == -EOPNOTSUPP) {
-+              /* Retry with ECC in case raw access is not supported */
-+              req.mode = MTD_OPS_PLACE_OOB;
-+              spinand_read_page(spinand, &req);
-+      }
-+
-       if (marker[0] != 0xff || marker[1] != 0xff)
-               return true;
-@@ -974,7 +985,14 @@ static int spinand_markbad(struct nand_d
-       if (ret)
-               return ret;
--      return spinand_write_page(spinand, &req);
-+      ret = spinand_write_page(spinand, &req);
-+      if (ret == -EOPNOTSUPP) {
-+              /* Retry with ECC in case raw access is not supported */
-+              req.mode = MTD_OPS_PLACE_OOB;
-+              ret = spinand_write_page(spinand, &req);
-+      }
-+
-+      return ret;
- }
- static int spinand_mtd_block_markbad(struct mtd_info *mtd, loff_t offs)
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -315,6 +315,7 @@ struct spinand_ecc_info {
- #define SPINAND_HAS_CR_FEAT_BIT               BIT(1)
- #define SPINAND_HAS_PROG_PLANE_SELECT_BIT             BIT(2)
- #define SPINAND_HAS_READ_PLANE_SELECT_BIT             BIT(3)
-+#define SPINAND_NO_RAW_ACCESS                         BIT(4)
- /**
-  * struct spinand_ondie_ecc_conf - private SPI-NAND on-die ECC engine structure
diff --git a/target/linux/generic/backport-6.18/431-v6.14-mtd-spinand-Add-support-for-SkyHigh-S35ML-3-family.patch b/target/linux/generic/backport-6.18/431-v6.14-mtd-spinand-Add-support-for-SkyHigh-S35ML-3-family.patch
deleted file mode 100644 (file)
index 762978d..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-From 1a50e3612de9187857f55ee14a573f7f8e7d4ebc Mon Sep 17 00:00:00 2001
-From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
-Date: Tue, 3 Dec 2024 11:46:50 +0900
-Subject: [PATCH] mtd: spinand: Add support for SkyHigh S35ML-3 family
-
-SkyHigh S35ML01G300, S35ML01G301, S35ML02G300, and S35ML04G300 are 1Gb,
-2Gb, and 4Gb SLC SPI NAND flash family. This family of devices has
-on-die ECC which parity bits are stored to hidden area. In this family
-the on-die ECC cannot be disabled so raw access needs to be prevented.
-
-Link: https://www.skyhighmemory.com/download/SPI_S35ML01_04G3_002_19205.pdf?v=P
-Co-developed-by: KR Kim <kr.kim@skyhighmemory.com>
-Signed-off-by: KR Kim <kr.kim@skyhighmemory.com>
-Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/spi/Makefile  |   2 +-
- drivers/mtd/nand/spi/core.c    |   1 +
- drivers/mtd/nand/spi/skyhigh.c | 147 +++++++++++++++++++++++++++++++++
- include/linux/mtd/spinand.h    |   1 +
- 4 files changed, 150 insertions(+), 1 deletion(-)
- create mode 100644 drivers/mtd/nand/spi/skyhigh.c
-
---- a/drivers/mtd/nand/spi/Makefile
-+++ b/drivers/mtd/nand/spi/Makefile
-@@ -1,4 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
- spinand-objs := core.o alliancememory.o ato.o esmt.o fmsh.o foresee.o gigadevice.o macronix.o
--spinand-objs += micron.o paragon.o toshiba.o winbond.o xtx.o
-+spinand-objs += micron.o paragon.o skyhigh.o toshiba.o winbond.o xtx.o
- obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -1191,6 +1191,7 @@ static const struct spinand_manufacturer
-       &macronix_spinand_manufacturer,
-       &micron_spinand_manufacturer,
-       &paragon_spinand_manufacturer,
-+      &skyhigh_spinand_manufacturer,
-       &toshiba_spinand_manufacturer,
-       &winbond_spinand_manufacturer,
-       &xtx_spinand_manufacturer,
---- /dev/null
-+++ b/drivers/mtd/nand/spi/skyhigh.c
-@@ -0,0 +1,147 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2024 SkyHigh Memory Limited
-+ *
-+ * Author: Takahiro Kuwano <takahiro.kuwano@infineon.com>
-+ * Co-Author: KR Kim <kr.kim@skyhighmemory.com>
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mtd/spinand.h>
-+
-+#define SPINAND_MFR_SKYHIGH                   0x01
-+#define SKYHIGH_STATUS_ECC_1TO2_BITFLIPS      (1 << 4)
-+#define SKYHIGH_STATUS_ECC_3TO6_BITFLIPS      (2 << 4)
-+#define SKYHIGH_STATUS_ECC_UNCOR_ERROR                (3 << 4)
-+#define SKYHIGH_CONFIG_PROTECT_EN             BIT(1)
-+
-+static SPINAND_OP_VARIANTS(read_cache_variants,
-+              SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
-+              SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(write_cache_variants,
-+              SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
-+              SPINAND_PROG_LOAD(true, 0, NULL, 0));
-+
-+static SPINAND_OP_VARIANTS(update_cache_variants,
-+              SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
-+              SPINAND_PROG_LOAD(false, 0, NULL, 0));
-+
-+static int skyhigh_spinand_ooblayout_ecc(struct mtd_info *mtd, int section,
-+                                       struct mtd_oob_region *region)
-+{
-+      /* ECC bytes are stored in hidden area. */
-+      return -ERANGE;
-+}
-+
-+static int skyhigh_spinand_ooblayout_free(struct mtd_info *mtd, int section,
-+                                        struct mtd_oob_region *region)
-+{
-+      if (section)
-+              return -ERANGE;
-+
-+      /* ECC bytes are stored in hidden area. Reserve 2 bytes for the BBM. */
-+      region->offset = 2;
-+      region->length = mtd->oobsize - 2;
-+
-+      return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops skyhigh_spinand_ooblayout = {
-+      .ecc = skyhigh_spinand_ooblayout_ecc,
-+      .free = skyhigh_spinand_ooblayout_free,
-+};
-+
-+static int skyhigh_spinand_ecc_get_status(struct spinand_device *spinand,
-+                                        u8 status)
-+{
-+      switch (status & STATUS_ECC_MASK) {
-+      case STATUS_ECC_NO_BITFLIPS:
-+              return 0;
-+
-+      case SKYHIGH_STATUS_ECC_UNCOR_ERROR:
-+              return -EBADMSG;
-+
-+      case SKYHIGH_STATUS_ECC_1TO2_BITFLIPS:
-+              return 2;
-+
-+      case SKYHIGH_STATUS_ECC_3TO6_BITFLIPS:
-+              return 6;
-+
-+      default:
-+              break;
-+      }
-+
-+      return -EINVAL;
-+}
-+
-+static const struct spinand_info skyhigh_spinand_table[] = {
-+      SPINAND_INFO("S35ML01G301",
-+                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
-+                   NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+                   NAND_ECCREQ(6, 32),
-+                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+                                            &write_cache_variants,
-+                                            &update_cache_variants),
-+                   SPINAND_NO_RAW_ACCESS,
-+                   SPINAND_ECCINFO(&skyhigh_spinand_ooblayout,
-+                                   skyhigh_spinand_ecc_get_status)),
-+      SPINAND_INFO("S35ML01G300",
-+                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
-+                   NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-+                   NAND_ECCREQ(6, 32),
-+                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+                                            &write_cache_variants,
-+                                            &update_cache_variants),
-+                   SPINAND_NO_RAW_ACCESS,
-+                   SPINAND_ECCINFO(&skyhigh_spinand_ooblayout,
-+                                   skyhigh_spinand_ecc_get_status)),
-+      SPINAND_INFO("S35ML02G300",
-+                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
-+                   NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
-+                   NAND_ECCREQ(6, 32),
-+                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+                                            &write_cache_variants,
-+                                            &update_cache_variants),
-+                   SPINAND_NO_RAW_ACCESS,
-+                   SPINAND_ECCINFO(&skyhigh_spinand_ooblayout,
-+                                   skyhigh_spinand_ecc_get_status)),
-+      SPINAND_INFO("S35ML04G300",
-+                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
-+                   NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 2, 1, 1),
-+                   NAND_ECCREQ(6, 32),
-+                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+                                            &write_cache_variants,
-+                                            &update_cache_variants),
-+                   SPINAND_NO_RAW_ACCESS,
-+                   SPINAND_ECCINFO(&skyhigh_spinand_ooblayout,
-+                                   skyhigh_spinand_ecc_get_status)),
-+};
-+
-+static int skyhigh_spinand_init(struct spinand_device *spinand)
-+{
-+      /*
-+       * Config_Protect_En (bit 1 in Block Lock register) must be set to 1
-+       * before writing other bits. Do it here before core unlocks all blocks
-+       * by writing block protection bits.
-+       */
-+      return spinand_write_reg_op(spinand, REG_BLOCK_LOCK,
-+                                  SKYHIGH_CONFIG_PROTECT_EN);
-+}
-+
-+static const struct spinand_manufacturer_ops skyhigh_spinand_manuf_ops = {
-+      .init = skyhigh_spinand_init,
-+};
-+
-+const struct spinand_manufacturer skyhigh_spinand_manufacturer = {
-+      .id = SPINAND_MFR_SKYHIGH,
-+      .name = "SkyHigh",
-+      .chips = skyhigh_spinand_table,
-+      .nchips = ARRAY_SIZE(skyhigh_spinand_table),
-+      .ops = &skyhigh_spinand_manuf_ops,
-+};
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -269,6 +269,7 @@ extern const struct spinand_manufacturer
- extern const struct spinand_manufacturer macronix_spinand_manufacturer;
- extern const struct spinand_manufacturer micron_spinand_manufacturer;
- extern const struct spinand_manufacturer paragon_spinand_manufacturer;
-+extern const struct spinand_manufacturer skyhigh_spinand_manufacturer;
- extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
- extern const struct spinand_manufacturer winbond_spinand_manufacturer;
- extern const struct spinand_manufacturer xtx_spinand_manufacturer;
diff --git a/target/linux/generic/backport-6.18/500-01-v6.13-block-add-support-for-defining-read-only-partitions.patch b/target/linux/generic/backport-6.18/500-01-v6.13-block-add-support-for-defining-read-only-partitions.patch
deleted file mode 100644 (file)
index cdf505f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From 03cb793b26834ddca170ba87057c8f883772dd45 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 3 Oct 2024 00:11:41 +0200
-Subject: [PATCH 1/5] block: add support for defining read-only partitions
-
-Add support for defining read-only partitions and complete support for
-it in the cmdline partition parser as the additional "ro" after a
-partition is scanned but never actually applied.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Christoph Hellwig <hch@lst.de>
-Link: https://lore.kernel.org/r/20241002221306.4403-2-ansuelsmth@gmail.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
----
- block/blk.h                | 1 +
- block/partitions/cmdline.c | 3 +++
- block/partitions/core.c    | 3 +++
- 3 files changed, 7 insertions(+)
-
---- a/block/blk.h
-+++ b/block/blk.h
-@@ -574,6 +574,7 @@ void blk_free_ext_minor(unsigned int min
- #define ADDPART_FLAG_NONE     0
- #define ADDPART_FLAG_RAID     1
- #define ADDPART_FLAG_WHOLEDISK        2
-+#define ADDPART_FLAG_READONLY 4
- int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
-               sector_t length);
- int bdev_del_partition(struct gendisk *disk, int partno);
---- a/block/partitions/cmdline.c
-+++ b/block/partitions/cmdline.c
-@@ -237,6 +237,9 @@ static int add_part(int slot, struct cmd
-       put_partition(state, slot, subpart->from >> 9,
-                     subpart->size >> 9);
-+      if (subpart->flags & PF_RDONLY)
-+              state->parts[slot].flags |= ADDPART_FLAG_READONLY;
-+
-       info = &state->parts[slot].info;
-       strscpy(info->volname, subpart->name, sizeof(info->volname));
---- a/block/partitions/core.c
-+++ b/block/partitions/core.c
-@@ -373,6 +373,9 @@ static struct block_device *add_partitio
-                       goto out_del;
-       }
-+      if (flags & ADDPART_FLAG_READONLY)
-+              bdev_set_flag(bdev, BD_READ_ONLY);
-+
-       /* everything is up and running, commence */
-       err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
-       if (err)
diff --git a/target/linux/generic/backport-6.18/500-02-v6.13-block-introduce-add_disk_fwnode.patch b/target/linux/generic/backport-6.18/500-02-v6.13-block-introduce-add_disk_fwnode.patch
deleted file mode 100644 (file)
index 381838d..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-From e5f587242b6072ffab4f4a084a459a59f3035873 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 3 Oct 2024 00:11:43 +0200
-Subject: [PATCH 3/5] block: introduce add_disk_fwnode()
-
-Introduce add_disk_fwnode() as a replacement of device_add_disk() that
-permits to pass and attach a fwnode to disk dev.
-
-This variant can be useful for eMMC that might have the partition table
-for the disk defined in DT. A parser can later make use of the attached
-fwnode to parse the related table and init the hardcoded partition for
-the disk.
-
-device_add_disk() is converted to a simple wrapper of add_disk_fwnode()
-with the fwnode entry set as NULL.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Christoph Hellwig <hch@lst.de>
-Link: https://lore.kernel.org/r/20241002221306.4403-4-ansuelsmth@gmail.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
----
- block/genhd.c          | 28 ++++++++++++++++++++++++----
- include/linux/blkdev.h |  3 +++
- 2 files changed, 27 insertions(+), 4 deletions(-)
-
---- a/block/genhd.c
-+++ b/block/genhd.c
-@@ -383,16 +383,18 @@ int disk_scan_partitions(struct gendisk
- }
- /**
-- * device_add_disk - add disk information to kernel list
-+ * add_disk_fwnode - add disk information to kernel list with fwnode
-  * @parent: parent device for the disk
-  * @disk: per-device partitioning information
-  * @groups: Additional per-device sysfs groups
-+ * @fwnode: attached disk fwnode
-  *
-  * This function registers the partitioning information in @disk
-- * with the kernel.
-+ * with the kernel. Also attach a fwnode to the disk device.
-  */
--int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
--                               const struct attribute_group **groups)
-+int __must_check add_disk_fwnode(struct device *parent, struct gendisk *disk,
-+                               const struct attribute_group **groups,
-+                               struct fwnode_handle *fwnode)
- {
-       struct device *ddev = disk_to_dev(disk);
-@@ -452,6 +454,8 @@ int __must_check device_add_disk(struct
-       ddev->parent = parent;
-       ddev->groups = groups;
-       dev_set_name(ddev, "%s", disk->disk_name);
-+      if (fwnode)
-+              device_set_node(ddev, fwnode);
-       if (!(disk->flags & GENHD_FL_HIDDEN))
-               ddev->devt = MKDEV(disk->major, disk->first_minor);
-       ret = device_add(ddev);
-@@ -553,6 +557,22 @@ out_exit_elevator:
-               elevator_exit(disk->queue);
-       return ret;
- }
-+EXPORT_SYMBOL_GPL(add_disk_fwnode);
-+
-+/**
-+ * device_add_disk - add disk information to kernel list
-+ * @parent: parent device for the disk
-+ * @disk: per-device partitioning information
-+ * @groups: Additional per-device sysfs groups
-+ *
-+ * This function registers the partitioning information in @disk
-+ * with the kernel.
-+ */
-+int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
-+                               const struct attribute_group **groups)
-+{
-+      return add_disk_fwnode(parent, disk, groups, NULL);
-+}
- EXPORT_SYMBOL(device_add_disk);
- static void blk_report_disk_dead(struct gendisk *disk, bool surprise)
---- a/include/linux/blkdev.h
-+++ b/include/linux/blkdev.h
-@@ -789,6 +789,9 @@ static inline unsigned int blk_queue_dep
- #define for_each_bio(_bio)            \
-       for (; _bio; _bio = _bio->bi_next)
-+int __must_check add_disk_fwnode(struct device *parent, struct gendisk *disk,
-+                               const struct attribute_group **groups,
-+                               struct fwnode_handle *fwnode);
- int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
-                                const struct attribute_group **groups);
- static inline int __must_check add_disk(struct gendisk *disk)
diff --git a/target/linux/generic/backport-6.18/500-03-v6.13-mmc-block-attach-partitions-fwnode-if-found-in-mmc-c.patch b/target/linux/generic/backport-6.18/500-03-v6.13-mmc-block-attach-partitions-fwnode-if-found-in-mmc-c.patch
deleted file mode 100644 (file)
index 0bdeaa8..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-From 45ff6c340ddfc2dade74d5b7a8962c778ab7042c Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 3 Oct 2024 00:11:44 +0200
-Subject: [PATCH 4/5] mmc: block: attach partitions fwnode if found in mmc-card
-
-Attach partitions fwnode if found in mmc-card and register disk with it.
-
-This permits block partition to reference the node and register a
-partition table defined in DT for the special case for embedded device
-that doesn't have a partition table flashed but have an hardcoded
-partition table passed from the system.
-
-JEDEC BOOT partition boot0/boot1 are supported but in DT we refer with
-the JEDEC name of boot1 and boot2 to better adhere to documentation.
-
-Also JEDEC GP partition gp0/1/2/3 are supported but in DT we refer with
-the JEDEC name of gp1/2/3/4 to better adhere to documentration.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20241002221306.4403-5-ansuelsmth@gmail.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
----
- drivers/mmc/core/block.c | 55 +++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 54 insertions(+), 1 deletion(-)
-
---- a/drivers/mmc/core/block.c
-+++ b/drivers/mmc/core/block.c
-@@ -2517,6 +2517,56 @@ static inline int mmc_blk_readonly(struc
-              !(card->csd.cmdclass & CCC_BLOCK_WRITE);
- }
-+/*
-+ * Search for a declared partitions node for the disk in mmc-card related node.
-+ *
-+ * This is to permit support for partition table defined in DT in special case
-+ * where a partition table is not written in the disk and is expected to be
-+ * passed from the running system.
-+ *
-+ * For the user disk, "partitions" node is searched.
-+ * For the special HW disk, "partitions-" node with the appended name is used
-+ * following this conversion table (to adhere to JEDEC naming)
-+ * - boot0 -> partitions-boot1
-+ * - boot1 -> partitions-boot2
-+ * - gp0 -> partitions-gp1
-+ * - gp1 -> partitions-gp2
-+ * - gp2 -> partitions-gp3
-+ * - gp3 -> partitions-gp4
-+ */
-+static struct fwnode_handle *mmc_blk_get_partitions_node(struct device *mmc_dev,
-+                                                       const char *subname)
-+{
-+      const char *node_name = "partitions";
-+
-+      if (subname) {
-+              mmc_dev = mmc_dev->parent;
-+
-+              /*
-+               * Check if we are allocating a BOOT disk boot0/1 disk.
-+               * In DT we use the JEDEC naming boot1/2.
-+               */
-+              if (!strcmp(subname, "boot0"))
-+                      node_name = "partitions-boot1";
-+              if (!strcmp(subname, "boot1"))
-+                      node_name = "partitions-boot2";
-+              /*
-+               * Check if we are allocating a GP disk gp0/1/2/3 disk.
-+               * In DT we use the JEDEC naming gp1/2/3/4.
-+               */
-+              if (!strcmp(subname, "gp0"))
-+                      node_name = "partitions-gp1";
-+              if (!strcmp(subname, "gp1"))
-+                      node_name = "partitions-gp2";
-+              if (!strcmp(subname, "gp2"))
-+                      node_name = "partitions-gp3";
-+              if (!strcmp(subname, "gp3"))
-+                      node_name = "partitions-gp4";
-+      }
-+
-+      return device_get_named_child_node(mmc_dev, node_name);
-+}
-+
- static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
-                                             struct device *parent,
-                                             sector_t size,
-@@ -2525,6 +2575,7 @@ static struct mmc_blk_data *mmc_blk_allo
-                                             int area_type,
-                                             unsigned int part_type)
- {
-+      struct fwnode_handle *disk_fwnode;
-       struct mmc_blk_data *md;
-       int devidx, ret;
-       char cap_str[10];
-@@ -2626,7 +2677,9 @@ static struct mmc_blk_data *mmc_blk_allo
-       /* used in ->open, must be set before add_disk: */
-       if (area_type == MMC_BLK_DATA_AREA_MAIN)
-               dev_set_drvdata(&card->dev, md);
--      ret = device_add_disk(md->parent, md->disk, mmc_disk_attr_groups);
-+      disk_fwnode = mmc_blk_get_partitions_node(parent, subname);
-+      ret = add_disk_fwnode(md->parent, md->disk, mmc_disk_attr_groups,
-+                            disk_fwnode);
-       if (ret)
-               goto err_put_disk;
-       return md;
diff --git a/target/linux/generic/backport-6.18/500-04-v6.13-block-add-support-for-partition-table-defined-in-OF.patch b/target/linux/generic/backport-6.18/500-04-v6.13-block-add-support-for-partition-table-defined-in-OF.patch
deleted file mode 100644 (file)
index d260be1..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-From 884555b557e5e6d41c866e2cd8d7b32f50ec974b Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 3 Oct 2024 00:11:45 +0200
-Subject: [PATCH 5/5] block: add support for partition table defined in OF
-
-Add support for partition table defined in Device Tree. Similar to how
-it's done with MTD, add support for defining a fixed partition table in
-device tree.
-
-A common scenario for this is fixed block (eMMC) embedded devices that
-have no MBR or GPT partition table to save storage space. Bootloader
-access the block device with absolute address of data.
-
-This is to complete the functionality with an equivalent implementation
-with providing partition table with bootargs, for case where the booargs
-can't be modified and tweaking the Device Tree is the only solution to
-have an usabe partition table.
-
-The implementation follow the fixed-partitions parser used on MTD
-devices where a "partitions" node is expected to be declared with
-"fixed-partitions" compatible in the OF node of the disk device
-(mmc-card for eMMC for example) and each child node declare a label
-and a reg with offset and size. If label is not declared, the node name
-is used as fallback. Eventually is also possible to declare the read-only
-property to flag the partition as read-only.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Christoph Hellwig <hch@lst.de>
-Link: https://lore.kernel.org/r/20241002221306.4403-6-ansuelsmth@gmail.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
----
- block/partitions/Kconfig  |   9 ++++
- block/partitions/Makefile |   1 +
- block/partitions/check.h  |   1 +
- block/partitions/core.c   |   3 ++
- block/partitions/of.c     | 110 ++++++++++++++++++++++++++++++++++++++
- 5 files changed, 124 insertions(+)
- create mode 100644 block/partitions/of.c
-
---- a/block/partitions/Kconfig
-+++ b/block/partitions/Kconfig
-@@ -270,4 +270,13 @@ config CMDLINE_PARTITION
-         Say Y here if you want to read the partition table from bootargs.
-         The format for the command line is just like mtdparts.
-+config OF_PARTITION
-+      bool "Device Tree partition support" if PARTITION_ADVANCED
-+      depends on OF
-+      help
-+        Say Y here if you want to enable support for partition table
-+        defined in Device Tree. (mainly for eMMC)
-+        The format for the device tree node is just like MTD fixed-partition
-+        schema.
-+
- endmenu
---- a/block/partitions/Makefile
-+++ b/block/partitions/Makefile
-@@ -12,6 +12,7 @@ obj-$(CONFIG_CMDLINE_PARTITION) += cmdli
- obj-$(CONFIG_MAC_PARTITION) += mac.o
- obj-$(CONFIG_LDM_PARTITION) += ldm.o
- obj-$(CONFIG_MSDOS_PARTITION) += msdos.o
-+obj-$(CONFIG_OF_PARTITION) += of.o
- obj-$(CONFIG_OSF_PARTITION) += osf.o
- obj-$(CONFIG_SGI_PARTITION) += sgi.o
- obj-$(CONFIG_SUN_PARTITION) += sun.o
---- a/block/partitions/check.h
-+++ b/block/partitions/check.h
-@@ -62,6 +62,7 @@ int karma_partition(struct parsed_partit
- int ldm_partition(struct parsed_partitions *state);
- int mac_partition(struct parsed_partitions *state);
- int msdos_partition(struct parsed_partitions *state);
-+int of_partition(struct parsed_partitions *state);
- int osf_partition(struct parsed_partitions *state);
- int sgi_partition(struct parsed_partitions *state);
- int sun_partition(struct parsed_partitions *state);
---- a/block/partitions/core.c
-+++ b/block/partitions/core.c
-@@ -43,6 +43,9 @@ static int (*const check_part[])(struct
- #ifdef CONFIG_CMDLINE_PARTITION
-       cmdline_partition,
- #endif
-+#ifdef CONFIG_OF_PARTITION
-+      of_partition,           /* cmdline have priority to OF */
-+#endif
- #ifdef CONFIG_EFI_PARTITION
-       efi_partition,          /* this must come before msdos */
- #endif
---- /dev/null
-+++ b/block/partitions/of.c
-@@ -0,0 +1,110 @@
-+// SPDX-License-Identifier: GPL-2.0
-+
-+#include <linux/blkdev.h>
-+#include <linux/major.h>
-+#include <linux/of.h>
-+#include <linux/string.h>
-+#include "check.h"
-+
-+static int validate_of_partition(struct device_node *np, int slot)
-+{
-+      u64 offset, size;
-+      int len;
-+
-+      const __be32 *reg = of_get_property(np, "reg", &len);
-+      int a_cells = of_n_addr_cells(np);
-+      int s_cells = of_n_size_cells(np);
-+
-+      /* Make sure reg len match the expected addr and size cells */
-+      if (len / sizeof(*reg) != a_cells + s_cells)
-+              return -EINVAL;
-+
-+      /* Validate offset conversion from bytes to sectors */
-+      offset = of_read_number(reg, a_cells);
-+      if (offset % SECTOR_SIZE)
-+              return -EINVAL;
-+
-+      /* Validate size conversion from bytes to sectors */
-+      size = of_read_number(reg + a_cells, s_cells);
-+      if (!size || size % SECTOR_SIZE)
-+              return -EINVAL;
-+
-+      return 0;
-+}
-+
-+static void add_of_partition(struct parsed_partitions *state, int slot,
-+                           struct device_node *np)
-+{
-+      struct partition_meta_info *info;
-+      char tmp[sizeof(info->volname) + 4];
-+      const char *partname;
-+      int len;
-+
-+      const __be32 *reg = of_get_property(np, "reg", &len);
-+      int a_cells = of_n_addr_cells(np);
-+      int s_cells = of_n_size_cells(np);
-+
-+      /* Convert bytes to sector size */
-+      u64 offset = of_read_number(reg, a_cells) / SECTOR_SIZE;
-+      u64 size = of_read_number(reg + a_cells, s_cells) / SECTOR_SIZE;
-+
-+      put_partition(state, slot, offset, size);
-+
-+      if (of_property_read_bool(np, "read-only"))
-+              state->parts[slot].flags |= ADDPART_FLAG_READONLY;
-+
-+      /*
-+       * Follow MTD label logic, search for label property,
-+       * fallback to node name if not found.
-+       */
-+      info = &state->parts[slot].info;
-+      partname = of_get_property(np, "label", &len);
-+      if (!partname)
-+              partname = of_get_property(np, "name", &len);
-+      strscpy(info->volname, partname, sizeof(info->volname));
-+
-+      snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
-+      strlcat(state->pp_buf, tmp, PAGE_SIZE);
-+}
-+
-+int of_partition(struct parsed_partitions *state)
-+{
-+      struct device *ddev = disk_to_dev(state->disk);
-+      struct device_node *np;
-+      int slot;
-+
-+      struct device_node *partitions_np = of_node_get(ddev->of_node);
-+
-+      if (!partitions_np ||
-+          !of_device_is_compatible(partitions_np, "fixed-partitions"))
-+              return 0;
-+
-+      slot = 1;
-+      /* Validate parition offset and size */
-+      for_each_child_of_node(partitions_np, np) {
-+              if (validate_of_partition(np, slot)) {
-+                      of_node_put(np);
-+                      of_node_put(partitions_np);
-+
-+                      return -1;
-+              }
-+
-+              slot++;
-+      }
-+
-+      slot = 1;
-+      for_each_child_of_node(partitions_np, np) {
-+              if (slot >= state->limit) {
-+                      of_node_put(np);
-+                      break;
-+              }
-+
-+              add_of_partition(state, slot, np);
-+
-+              slot++;
-+      }
-+
-+      strlcat(state->pp_buf, "\n", PAGE_SIZE);
-+
-+      return 1;
-+}
diff --git a/target/linux/generic/backport-6.18/600-01-v6.13-net-phylink-move-manual-flow-control-setting.patch b/target/linux/generic/backport-6.18/600-01-v6.13-net-phylink-move-manual-flow-control-setting.patch
deleted file mode 100644 (file)
index a9b86c2..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From 8cc5f4cb94c0b1c7c1ba8013c14fd02ffb1a25f3 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 8 Nov 2024 16:01:44 +0000
-Subject: [PATCH 1/5] net: phylink: move manual flow control setting
-
-Move the handling of manual flow control configuration to a common
-location during resolve. We currently evaluate this for all but
-fixed links.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1t9RQe-002Feh-T1@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1484,7 +1484,6 @@ static void phylink_resolve(struct work_
-               switch (pl->cur_link_an_mode) {
-               case MLO_AN_PHY:
-                       link_state = pl->phy_state;
--                      phylink_apply_manual_flow(pl, &link_state);
-                       mac_config = link_state.link;
-                       break;
-@@ -1545,11 +1544,13 @@ static void phylink_resolve(struct work_
-                               link_state.pause = pl->phy_state.pause;
-                               mac_config = true;
-                       }
--                      phylink_apply_manual_flow(pl, &link_state);
-                       break;
-               }
-       }
-+      if (pl->cur_link_an_mode != MLO_AN_FIXED)
-+              phylink_apply_manual_flow(pl, &link_state);
-+
-       if (mac_config) {
-               if (link_state.interface != pl->link_config.interface) {
-                       /* The interface has changed, force the link down and
diff --git a/target/linux/generic/backport-6.18/600-02-v6.13-net-phylink-move-MLO_AN_FIXED-resolve-handling-to-if.patch b/target/linux/generic/backport-6.18/600-02-v6.13-net-phylink-move-MLO_AN_FIXED-resolve-handling-to-if.patch
deleted file mode 100644 (file)
index 7ff091e..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From 92abfcb4ced482afbe65d18980e6734fe1e62a34 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 8 Nov 2024 16:01:50 +0000
-Subject: [PATCH 2/5] net: phylink: move MLO_AN_FIXED resolve handling to if()
- statement
-
-The switch() statement doesn't sit very well with the preceeding if()
-statements, and results in excessive indentation that spoils code
-readability. Begin cleaning this up by converting the MLO_AN_FIXED case
-to an if() statement.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1t9RQk-002Fen-1A@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 8 +++-----
- 1 file changed, 3 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1480,6 +1480,9 @@ static void phylink_resolve(struct work_
-       } else if (pl->link_failed) {
-               link_state.link = false;
-               retrigger = true;
-+      } else if (pl->cur_link_an_mode == MLO_AN_FIXED) {
-+              phylink_get_fixed_state(pl, &link_state);
-+              mac_config = link_state.link;
-       } else {
-               switch (pl->cur_link_an_mode) {
-               case MLO_AN_PHY:
-@@ -1487,11 +1490,6 @@ static void phylink_resolve(struct work_
-                       mac_config = link_state.link;
-                       break;
--              case MLO_AN_FIXED:
--                      phylink_get_fixed_state(pl, &link_state);
--                      mac_config = link_state.link;
--                      break;
--
-               case MLO_AN_INBAND:
-                       phylink_mac_pcs_get_state(pl, &link_state);
diff --git a/target/linux/generic/backport-6.18/600-03-v6.13-net-phylink-move-MLO_AN_PHY-resolve-handling-to-if-s.patch b/target/linux/generic/backport-6.18/600-03-v6.13-net-phylink-move-MLO_AN_PHY-resolve-handling-to-if-s.patch
deleted file mode 100644 (file)
index 76e76fb..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From f0f46c2a3d8ea9d1427298c8103a777d9e616c29 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 8 Nov 2024 16:01:55 +0000
-Subject: [PATCH 3/5] net: phylink: move MLO_AN_PHY resolve handling to if()
- statement
-
-The switch() statement doesn't sit very well with the preceeding if()
-statements, and results in excessive indentation that spoils code
-readability. Continue cleaning this up by converting the MLO_AN_PHY
-case to use an if() statmeent.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1t9RQp-002Fet-5W@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 8 +++-----
- 1 file changed, 3 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1483,13 +1483,11 @@ static void phylink_resolve(struct work_
-       } else if (pl->cur_link_an_mode == MLO_AN_FIXED) {
-               phylink_get_fixed_state(pl, &link_state);
-               mac_config = link_state.link;
-+      } else if (pl->cur_link_an_mode == MLO_AN_PHY) {
-+              link_state = pl->phy_state;
-+              mac_config = link_state.link;
-       } else {
-               switch (pl->cur_link_an_mode) {
--              case MLO_AN_PHY:
--                      link_state = pl->phy_state;
--                      mac_config = link_state.link;
--                      break;
--
-               case MLO_AN_INBAND:
-                       phylink_mac_pcs_get_state(pl, &link_state);
diff --git a/target/linux/generic/backport-6.18/600-04-v6.13-net-phylink-remove-switch-statement-in-resolve-handl.patch b/target/linux/generic/backport-6.18/600-04-v6.13-net-phylink-remove-switch-statement-in-resolve-handl.patch
deleted file mode 100644 (file)
index 989fc10..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-From d1a16dbbd84e02d2a6dcfcb8d5c4b8b2c0289f00 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 8 Nov 2024 16:02:00 +0000
-Subject: [PATCH 4/5] net: phylink: remove switch() statement in resolve
- handling
-
-The switch() statement doesn't sit very well with the preceeding if()
-statements, so let's just convert everything to if()s. As a result of
-the two preceding commits, there is now only one case in the switch()
-statement. Remove the switch statement and reduce the code indentation.
-Code reformatting will be in the following commit.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1t9RQu-002Fez-AA@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 94 +++++++++++++++++++--------------------
- 1 file changed, 45 insertions(+), 49 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1487,60 +1487,56 @@ static void phylink_resolve(struct work_
-               link_state = pl->phy_state;
-               mac_config = link_state.link;
-       } else {
--              switch (pl->cur_link_an_mode) {
--              case MLO_AN_INBAND:
--                      phylink_mac_pcs_get_state(pl, &link_state);
--
--                      /* The PCS may have a latching link-fail indicator.
--                       * If the link was up, bring the link down and
--                       * re-trigger the resolve. Otherwise, re-read the
--                       * PCS state to get the current status of the link.
-+              phylink_mac_pcs_get_state(pl, &link_state);
-+
-+              /* The PCS may have a latching link-fail indicator.
-+               * If the link was up, bring the link down and
-+               * re-trigger the resolve. Otherwise, re-read the
-+               * PCS state to get the current status of the link.
-+               */
-+              if (!link_state.link) {
-+                      if (cur_link_state)
-+                              retrigger = true;
-+                      else
-+                              phylink_mac_pcs_get_state(pl,
-+                                                        &link_state);
-+              }
-+
-+              /* If we have a phy, the "up" state is the union of
-+               * both the PHY and the MAC
-+               */
-+              if (pl->phydev)
-+                      link_state.link &= pl->phy_state.link;
-+
-+              /* Only update if the PHY link is up */
-+              if (pl->phydev && pl->phy_state.link) {
-+                      /* If the interface has changed, force a
-+                       * link down event if the link isn't already
-+                       * down, and re-resolve.
-                        */
--                      if (!link_state.link) {
--                              if (cur_link_state)
--                                      retrigger = true;
--                              else
--                                      phylink_mac_pcs_get_state(pl,
--                                                                &link_state);
-+                      if (link_state.interface !=
-+                          pl->phy_state.interface) {
-+                              retrigger = true;
-+                              link_state.link = false;
-                       }
-+                      link_state.interface = pl->phy_state.interface;
--                      /* If we have a phy, the "up" state is the union of
--                       * both the PHY and the MAC
-+                      /* If we are doing rate matching, then the
-+                       * link speed/duplex comes from the PHY
-                        */
--                      if (pl->phydev)
--                              link_state.link &= pl->phy_state.link;
--
--                      /* Only update if the PHY link is up */
--                      if (pl->phydev && pl->phy_state.link) {
--                              /* If the interface has changed, force a
--                               * link down event if the link isn't already
--                               * down, and re-resolve.
--                               */
--                              if (link_state.interface !=
--                                  pl->phy_state.interface) {
--                                      retrigger = true;
--                                      link_state.link = false;
--                              }
--                              link_state.interface = pl->phy_state.interface;
--
--                              /* If we are doing rate matching, then the
--                               * link speed/duplex comes from the PHY
--                               */
--                              if (pl->phy_state.rate_matching) {
--                                      link_state.rate_matching =
--                                              pl->phy_state.rate_matching;
--                                      link_state.speed = pl->phy_state.speed;
--                                      link_state.duplex =
--                                              pl->phy_state.duplex;
--                              }
--
--                              /* If we have a PHY, we need to update with
--                               * the PHY flow control bits.
--                               */
--                              link_state.pause = pl->phy_state.pause;
--                              mac_config = true;
-+                      if (pl->phy_state.rate_matching) {
-+                              link_state.rate_matching =
-+                                      pl->phy_state.rate_matching;
-+                              link_state.speed = pl->phy_state.speed;
-+                              link_state.duplex =
-+                                      pl->phy_state.duplex;
-                       }
--                      break;
-+
-+                      /* If we have a PHY, we need to update with
-+                       * the PHY flow control bits.
-+                       */
-+                      link_state.pause = pl->phy_state.pause;
-+                      mac_config = true;
-               }
-       }
diff --git a/target/linux/generic/backport-6.18/600-05-v6.13-net-phylink-clean-up-phylink_resolve.patch b/target/linux/generic/backport-6.18/600-05-v6.13-net-phylink-clean-up-phylink_resolve.patch
deleted file mode 100644 (file)
index 285eea8..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From bc08ce37d99a3992e975a0f397503cb23404f25a Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 8 Nov 2024 16:02:05 +0000
-Subject: [PATCH 5/5] net: phylink: clean up phylink_resolve()
-
-Now that we have reduced the indentation level, clean up the code
-formatting.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1t9RQz-002Ff5-EA@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 35 ++++++++++++++++-------------------
- 1 file changed, 16 insertions(+), 19 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1489,51 +1489,48 @@ static void phylink_resolve(struct work_
-       } else {
-               phylink_mac_pcs_get_state(pl, &link_state);
--              /* The PCS may have a latching link-fail indicator.
--               * If the link was up, bring the link down and
--               * re-trigger the resolve. Otherwise, re-read the
--               * PCS state to get the current status of the link.
-+              /* The PCS may have a latching link-fail indicator. If the link
-+               * was up, bring the link down and re-trigger the resolve.
-+               * Otherwise, re-read the PCS state to get the current status
-+               * of the link.
-                */
-               if (!link_state.link) {
-                       if (cur_link_state)
-                               retrigger = true;
-                       else
--                              phylink_mac_pcs_get_state(pl,
--                                                        &link_state);
-+                              phylink_mac_pcs_get_state(pl, &link_state);
-               }
--              /* If we have a phy, the "up" state is the union of
--               * both the PHY and the MAC
-+              /* If we have a phy, the "up" state is the union of both the
-+               * PHY and the MAC
-                */
-               if (pl->phydev)
-                       link_state.link &= pl->phy_state.link;
-               /* Only update if the PHY link is up */
-               if (pl->phydev && pl->phy_state.link) {
--                      /* If the interface has changed, force a
--                       * link down event if the link isn't already
--                       * down, and re-resolve.
-+                      /* If the interface has changed, force a link down
-+                       * event if the link isn't already down, and re-resolve.
-                        */
--                      if (link_state.interface !=
--                          pl->phy_state.interface) {
-+                      if (link_state.interface != pl->phy_state.interface) {
-                               retrigger = true;
-                               link_state.link = false;
-                       }
-+
-                       link_state.interface = pl->phy_state.interface;
--                      /* If we are doing rate matching, then the
--                       * link speed/duplex comes from the PHY
-+                      /* If we are doing rate matching, then the link
-+                       * speed/duplex comes from the PHY
-                        */
-                       if (pl->phy_state.rate_matching) {
-                               link_state.rate_matching =
-                                       pl->phy_state.rate_matching;
-                               link_state.speed = pl->phy_state.speed;
--                              link_state.duplex =
--                                      pl->phy_state.duplex;
-+                              link_state.duplex = pl->phy_state.duplex;
-                       }
--                      /* If we have a PHY, we need to update with
--                       * the PHY flow control bits.
-+                      /* If we have a PHY, we need to update with the PHY
-+                       * flow control bits.
-                        */
-                       link_state.pause = pl->phy_state.pause;
-                       mac_config = true;
diff --git a/target/linux/generic/backport-6.18/601-01-v6.14-net-phylink-pass-phylink-and-pcs-into-phylink_pcs_ne.patch b/target/linux/generic/backport-6.18/601-01-v6.14-net-phylink-pass-phylink-and-pcs-into-phylink_pcs_ne.patch
deleted file mode 100644 (file)
index 6868cd1..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-From 17ed1911f9c8d4f9af8e13b2c95103ee06dadc0f Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:30:47 +0000
-Subject: [PATCH 01/13] net: phylink: pass phylink and pcs into
- phylink_pcs_neg_mode()
-
-Move the call to phylink_pcs_neg_mode() in phylink_major_config() after
-we have selected the appropriate PCS to allow the PCS to be passed in.
-
-Add struct phylink and struct phylink_pcs pointers to
-phylink_pcs_neg_mode() and pass in the appropriate structures. Set
-pl->pcs_neg_mode before returning, and remove the return value.
-
-This will allow the capabilities of the PCS and any PHY to be used when
-deciding which pcs_neg_mode should be used.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUrP-006ITh-6u@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 26 +++++++++++++-------------
- 1 file changed, 13 insertions(+), 13 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1102,7 +1102,8 @@ static void phylink_pcs_an_restart(struc
- /**
-  * phylink_pcs_neg_mode() - helper to determine PCS inband mode
-- * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
-+ * @pl: a pointer to a &struct phylink returned from phylink_create()
-+ * @pcs: a pointer to &struct phylink_pcs
-  * @interface: interface mode to be used
-  * @advertising: adertisement ethtool link mode mask
-  *
-@@ -1119,11 +1120,13 @@ static void phylink_pcs_an_restart(struc
-  * Note: this is for cases where the PCS itself is involved in negotiation
-  * (e.g. Clause 37, SGMII and similar) not Clause 73.
-  */
--static unsigned int phylink_pcs_neg_mode(unsigned int mode,
--                                       phy_interface_t interface,
--                                       const unsigned long *advertising)
-+static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs,
-+                               phy_interface_t interface,
-+                               const unsigned long *advertising)
- {
--      unsigned int neg_mode;
-+      unsigned int neg_mode, mode;
-+
-+      mode = pl->cur_link_an_mode;
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-@@ -1164,7 +1167,7 @@ static unsigned int phylink_pcs_neg_mode
-               break;
-       }
--      return neg_mode;
-+      pl->pcs_neg_mode = neg_mode;
- }
- static void phylink_major_config(struct phylink *pl, bool restart,
-@@ -1178,10 +1181,6 @@ static void phylink_major_config(struct
-       phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
--      pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode,
--                                              state->interface,
--                                              state->advertising);
--
-       if (pl->using_mac_select_pcs) {
-               pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
-               if (IS_ERR(pcs)) {
-@@ -1194,6 +1193,8 @@ static void phylink_major_config(struct
-               pcs_changed = pcs && pl->pcs != pcs;
-       }
-+      phylink_pcs_neg_mode(pl, pcs, state->interface, state->advertising);
-+
-       phylink_pcs_poll_stop(pl);
-       if (pl->mac_ops->mac_prepare) {
-@@ -1284,9 +1285,8 @@ static int phylink_change_inband_advert(
-                   pl->link_config.pause);
-       /* Recompute the PCS neg mode */
--      pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode,
--                                      pl->link_config.interface,
--                                      pl->link_config.advertising);
-+      phylink_pcs_neg_mode(pl, pl->pcs, pl->link_config.interface,
-+                           pl->link_config.advertising);
-       neg_mode = pl->cur_link_an_mode;
-       if (pl->pcs->neg_mode)
diff --git a/target/linux/generic/backport-6.18/601-02-v6.14-net-phylink-split-cur_link_an_mode-into-requested-an.patch b/target/linux/generic/backport-6.18/601-02-v6.14-net-phylink-split-cur_link_an_mode-into-requested-an.patch
deleted file mode 100644 (file)
index 76f4d5a..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-From 1f92ead7e15003f632b5f138e8138095e0997d3d Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:30:52 +0000
-Subject: [PATCH 02/13] net: phylink: split cur_link_an_mode into requested and
- active
-
-There is an interdependence between the current link_an_mode and
-pcs_neg_mode that some drivers rely upon to know whether inband or PHY
-mode will be used.
-
-In order to support detection of PCS and PHY inband capabilities
-resulting in automatic selection of inband or PHY mode, we need to
-cater for this, and support changing the MAC link_an_mode. However, we
-end up with an inter-dependency between the current link_an_mode and
-pcs_neg_mode.
-
-To solve this, split the current link_an_mode into the requested
-link_an_mode and active link_an_mode. The requested link_an_mode will
-always be passed to phylink_pcs_neg_mode(), and the active link_an_mode
-will be used for everything else, and only updated during
-phylink_major_config(). This will ensure that phylink_pcs_neg_mode()'s
-link_an_mode will not depend on the active link_an_mode that will,
-in a future patch, depend on pcs_neg_mode.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUrU-006ITn-Ai@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 60 ++++++++++++++++++++-------------------
- 1 file changed, 31 insertions(+), 29 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -56,7 +56,8 @@ struct phylink {
-       struct phy_device *phydev;
-       phy_interface_t link_interface; /* PHY_INTERFACE_xxx */
-       u8 cfg_link_an_mode;            /* MLO_AN_xxx */
--      u8 cur_link_an_mode;
-+      u8 req_link_an_mode;            /* Requested MLO_AN_xxx mode */
-+      u8 act_link_an_mode;            /* Active MLO_AN_xxx mode */
-       u8 link_port;                   /* The current non-phy ethtool port */
-       __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
-@@ -1082,13 +1083,13 @@ static void phylink_mac_config(struct ph
-       phylink_dbg(pl,
-                   "%s: mode=%s/%s/%s adv=%*pb pause=%02x\n",
--                  __func__, phylink_an_mode_str(pl->cur_link_an_mode),
-+                  __func__, phylink_an_mode_str(pl->act_link_an_mode),
-                   phy_modes(st.interface),
-                   phy_rate_matching_to_str(st.rate_matching),
-                   __ETHTOOL_LINK_MODE_MASK_NBITS, st.advertising,
-                   st.pause);
--      pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, &st);
-+      pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st);
- }
- static void phylink_pcs_an_restart(struct phylink *pl)
-@@ -1096,7 +1097,7 @@ static void phylink_pcs_an_restart(struc
-       if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-                                        pl->link_config.advertising) &&
-           phy_interface_mode_is_8023z(pl->link_config.interface) &&
--          phylink_autoneg_inband(pl->cur_link_an_mode))
-+          phylink_autoneg_inband(pl->act_link_an_mode))
-               pl->pcs->ops->pcs_an_restart(pl->pcs);
- }
-@@ -1126,7 +1127,7 @@ static void phylink_pcs_neg_mode(struct
- {
-       unsigned int neg_mode, mode;
--      mode = pl->cur_link_an_mode;
-+      mode = pl->req_link_an_mode;
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-@@ -1168,6 +1169,7 @@ static void phylink_pcs_neg_mode(struct
-       }
-       pl->pcs_neg_mode = neg_mode;
-+      pl->act_link_an_mode = mode;
- }
- static void phylink_major_config(struct phylink *pl, bool restart,
-@@ -1198,7 +1200,7 @@ static void phylink_major_config(struct
-       phylink_pcs_poll_stop(pl);
-       if (pl->mac_ops->mac_prepare) {
--              err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
-+              err = pl->mac_ops->mac_prepare(pl->config, pl->act_link_an_mode,
-                                              state->interface);
-               if (err < 0) {
-                       phylink_err(pl, "mac_prepare failed: %pe\n",
-@@ -1232,7 +1234,7 @@ static void phylink_major_config(struct
-       if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
-               phylink_pcs_enable(pl->pcs);
--      neg_mode = pl->cur_link_an_mode;
-+      neg_mode = pl->act_link_an_mode;
-       if (pl->pcs && pl->pcs->neg_mode)
-               neg_mode = pl->pcs_neg_mode;
-@@ -1248,7 +1250,7 @@ static void phylink_major_config(struct
-               phylink_pcs_an_restart(pl);
-       if (pl->mac_ops->mac_finish) {
--              err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode,
-+              err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode,
-                                             state->interface);
-               if (err < 0)
-                       phylink_err(pl, "mac_finish failed: %pe\n",
-@@ -1279,7 +1281,7 @@ static int phylink_change_inband_advert(
-               return 0;
-       phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__,
--                  phylink_an_mode_str(pl->cur_link_an_mode),
-+                  phylink_an_mode_str(pl->req_link_an_mode),
-                   phy_modes(pl->link_config.interface),
-                   __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
-                   pl->link_config.pause);
-@@ -1288,7 +1290,7 @@ static int phylink_change_inband_advert(
-       phylink_pcs_neg_mode(pl, pl->pcs, pl->link_config.interface,
-                            pl->link_config.advertising);
--      neg_mode = pl->cur_link_an_mode;
-+      neg_mode = pl->act_link_an_mode;
-       if (pl->pcs->neg_mode)
-               neg_mode = pl->pcs_neg_mode;
-@@ -1353,7 +1355,7 @@ static void phylink_mac_initial_config(s
- {
-       struct phylink_link_state link_state;
--      switch (pl->cur_link_an_mode) {
-+      switch (pl->req_link_an_mode) {
-       case MLO_AN_PHY:
-               link_state = pl->phy_state;
-               break;
-@@ -1427,14 +1429,14 @@ static void phylink_link_up(struct phyli
-       pl->cur_interface = link_state.interface;
--      neg_mode = pl->cur_link_an_mode;
-+      neg_mode = pl->act_link_an_mode;
-       if (pl->pcs && pl->pcs->neg_mode)
-               neg_mode = pl->pcs_neg_mode;
-       phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed,
-                           duplex);
--      pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
-+      pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode,
-                                pl->cur_interface, speed, duplex,
-                                !!(link_state.pause & MLO_PAUSE_TX), rx_pause);
-@@ -1454,7 +1456,7 @@ static void phylink_link_down(struct phy
-       if (ndev)
-               netif_carrier_off(ndev);
--      pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode,
-+      pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode,
-                                  pl->cur_interface);
-       phylink_info(pl, "Link is Down\n");
- }
-@@ -1480,10 +1482,10 @@ static void phylink_resolve(struct work_
-       } else if (pl->link_failed) {
-               link_state.link = false;
-               retrigger = true;
--      } else if (pl->cur_link_an_mode == MLO_AN_FIXED) {
-+      } else if (pl->act_link_an_mode == MLO_AN_FIXED) {
-               phylink_get_fixed_state(pl, &link_state);
-               mac_config = link_state.link;
--      } else if (pl->cur_link_an_mode == MLO_AN_PHY) {
-+      } else if (pl->act_link_an_mode == MLO_AN_PHY) {
-               link_state = pl->phy_state;
-               mac_config = link_state.link;
-       } else {
-@@ -1537,7 +1539,7 @@ static void phylink_resolve(struct work_
-               }
-       }
--      if (pl->cur_link_an_mode != MLO_AN_FIXED)
-+      if (pl->act_link_an_mode != MLO_AN_FIXED)
-               phylink_apply_manual_flow(pl, &link_state);
-       if (mac_config) {
-@@ -1661,7 +1663,7 @@ int phylink_set_fixed_link(struct phylin
-       pl->link_config.an_complete = 1;
-       pl->cfg_link_an_mode = MLO_AN_FIXED;
--      pl->cur_link_an_mode = pl->cfg_link_an_mode;
-+      pl->req_link_an_mode = pl->cfg_link_an_mode;
-       return 0;
- }
-@@ -1756,7 +1758,7 @@ struct phylink *phylink_create(struct ph
-               }
-       }
--      pl->cur_link_an_mode = pl->cfg_link_an_mode;
-+      pl->req_link_an_mode = pl->cfg_link_an_mode;
-       ret = phylink_register_sfp(pl, fwnode);
-       if (ret < 0) {
-@@ -2213,7 +2215,7 @@ void phylink_start(struct phylink *pl)
-       ASSERT_RTNL();
-       phylink_info(pl, "configuring for %s/%s link mode\n",
--                   phylink_an_mode_str(pl->cur_link_an_mode),
-+                   phylink_an_mode_str(pl->req_link_an_mode),
-                    phy_modes(pl->link_config.interface));
-       /* Always set the carrier off */
-@@ -2472,7 +2474,7 @@ int phylink_ethtool_ksettings_get(struct
-       linkmode_copy(kset->link_modes.supported, pl->supported);
--      switch (pl->cur_link_an_mode) {
-+      switch (pl->act_link_an_mode) {
-       case MLO_AN_FIXED:
-               /* We are using fixed settings. Report these as the
-                * current link settings - and note that these also
-@@ -2564,7 +2566,7 @@ int phylink_ethtool_ksettings_set(struct
-               /* If we have a fixed link, refuse to change link parameters.
-                * If the link parameters match, accept them but do nothing.
-                */
--              if (pl->cur_link_an_mode == MLO_AN_FIXED) {
-+              if (pl->req_link_an_mode == MLO_AN_FIXED) {
-                       if (s->speed != pl->link_config.speed ||
-                           s->duplex != pl->link_config.duplex)
-                               return -EINVAL;
-@@ -2580,7 +2582,7 @@ int phylink_ethtool_ksettings_set(struct
-                * is our default case) but do not allow the advertisement to
-                * be changed. If the advertisement matches, simply return.
-                */
--              if (pl->cur_link_an_mode == MLO_AN_FIXED) {
-+              if (pl->req_link_an_mode == MLO_AN_FIXED) {
-                       if (!linkmode_equal(config.advertising,
-                                           pl->link_config.advertising))
-                               return -EINVAL;
-@@ -2620,7 +2622,7 @@ int phylink_ethtool_ksettings_set(struct
-               linkmode_copy(support, pl->supported);
-               if (phylink_validate(pl, support, &config)) {
-                       phylink_err(pl, "validation of %s/%s with support %*pb failed\n",
--                                  phylink_an_mode_str(pl->cur_link_an_mode),
-+                                  phylink_an_mode_str(pl->req_link_an_mode),
-                                   phy_modes(config.interface),
-                                   __ETHTOOL_LINK_MODE_MASK_NBITS, support);
-                       return -EINVAL;
-@@ -2720,7 +2722,7 @@ int phylink_ethtool_set_pauseparam(struc
-       ASSERT_RTNL();
--      if (pl->cur_link_an_mode == MLO_AN_FIXED)
-+      if (pl->req_link_an_mode == MLO_AN_FIXED)
-               return -EOPNOTSUPP;
-       if (!phylink_test(pl->supported, Pause) &&
-@@ -2984,7 +2986,7 @@ static int phylink_mii_read(struct phyli
-       struct phylink_link_state state;
-       int val = 0xffff;
--      switch (pl->cur_link_an_mode) {
-+      switch (pl->act_link_an_mode) {
-       case MLO_AN_FIXED:
-               if (phy_id == 0) {
-                       phylink_get_fixed_state(pl, &state);
-@@ -3009,7 +3011,7 @@ static int phylink_mii_read(struct phyli
- static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
-                            unsigned int reg, unsigned int val)
- {
--      switch (pl->cur_link_an_mode) {
-+      switch (pl->act_link_an_mode) {
-       case MLO_AN_FIXED:
-               break;
-@@ -3199,9 +3201,9 @@ static void phylink_sfp_set_config(struc
-               changed = true;
-       }
--      if (pl->cur_link_an_mode != mode ||
-+      if (pl->req_link_an_mode != mode ||
-           pl->link_config.interface != state->interface) {
--              pl->cur_link_an_mode = mode;
-+              pl->req_link_an_mode = mode;
-               pl->link_config.interface = state->interface;
-               changed = true;
diff --git a/target/linux/generic/backport-6.18/601-03-v6.14-net-phylink-add-debug-for-phylink_major_config.patch b/target/linux/generic/backport-6.18/601-03-v6.14-net-phylink-add-debug-for-phylink_major_config.patch
deleted file mode 100644 (file)
index ee625c7..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-From 4e7d000286fe8e12f2d88032711ffab3ab658b12 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:30:57 +0000
-Subject: [PATCH 03/13] net: phylink: add debug for phylink_major_config()
-
-Now that we have a more complexity in phylink_major_config(), augment
-the debugging so we can see what's going on there.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUrZ-006ITt-Fa@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 27 ++++++++++++++++++++++++++-
- 1 file changed, 26 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -176,6 +176,24 @@ static const char *phylink_an_mode_str(u
-       return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
- }
-+static const char *phylink_pcs_mode_str(unsigned int mode)
-+{
-+      if (!mode)
-+              return "none";
-+
-+      if (mode & PHYLINK_PCS_NEG_OUTBAND)
-+              return "outband";
-+
-+      if (mode & PHYLINK_PCS_NEG_INBAND) {
-+              if (mode & PHYLINK_PCS_NEG_ENABLED)
-+                      return "inband,an-enabled";
-+              else
-+                      return "inband,an-disabled";
-+      }
-+
-+      return "unknown";
-+}
-+
- static unsigned int phylink_interface_signal_rate(phy_interface_t interface)
- {
-       switch (interface) {
-@@ -1181,7 +1199,9 @@ static void phylink_major_config(struct
-       unsigned int neg_mode;
-       int err;
--      phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
-+      phylink_dbg(pl, "major config, requested %s/%s\n",
-+                  phylink_an_mode_str(pl->req_link_an_mode),
-+                  phy_modes(state->interface));
-       if (pl->using_mac_select_pcs) {
-               pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
-@@ -1197,6 +1217,11 @@ static void phylink_major_config(struct
-       phylink_pcs_neg_mode(pl, pcs, state->interface, state->advertising);
-+      phylink_dbg(pl, "major config, active %s/%s/%s\n",
-+                  phylink_an_mode_str(pl->act_link_an_mode),
-+                  phylink_pcs_mode_str(pl->pcs_neg_mode),
-+                  phy_modes(state->interface));
-+
-       phylink_pcs_poll_stop(pl);
-       if (pl->mac_ops->mac_prepare) {
diff --git a/target/linux/generic/backport-6.18/601-04-v6.14-net-phy-add-phy_inband_caps.patch b/target/linux/generic/backport-6.18/601-04-v6.14-net-phy-add-phy_inband_caps.patch
deleted file mode 100644 (file)
index 0cd38f0..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-From b4c7698dd95f253c6958d8c6ac219098009bf28a Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:02 +0000
-Subject: [PATCH 04/13] net: phy: add phy_inband_caps()
-
-Add a method to query the PHY's in-band capabilities for a PHY
-interface mode.
-
-Where the interface mode does not have in-band capability, or the PHY
-driver has not been updated to return this information, then
-phy_inband_caps() should return zero. Otherwise, PHY drivers will
-return a value consisting of the following flags:
-
-LINK_INBAND_DISABLE indicates that the hardware does not support
-in-band signalling, or can have in-band signalling configured via
-software to be disabled.
-
-LINK_INBAND_ENABLE indicates that the hardware will use in-band
-signalling, or can have in-band signalling configured via software
-to be enabled.
-
-LINK_INBAND_BYPASS indicates that the hardware has the ability to
-bypass in-band signalling when enabled after a timeout if the link
-partner does not respond to its in-band signalling.
-
-This reports the PHY capabilities for the particular interface mode,
-not the current configuration.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUre-006ITz-KF@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phy.c | 21 +++++++++++++++++++++
- include/linux/phy.h   | 28 ++++++++++++++++++++++++++++
- 2 files changed, 49 insertions(+)
-
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -1049,6 +1049,27 @@ static int phy_check_link_status(struct
- }
- /**
-+ * phy_inband_caps - query which in-band signalling modes are supported
-+ * @phydev: a pointer to a &struct phy_device
-+ * @interface: the interface mode for the PHY
-+ *
-+ * Returns zero if it is unknown what in-band signalling is supported by the
-+ * PHY (e.g. because the PHY driver doesn't implement the method.) Otherwise,
-+ * returns a bit mask of the LINK_INBAND_* values from
-+ * &enum link_inband_signalling to describe which inband modes are supported
-+ * by the PHY for this interface mode.
-+ */
-+unsigned int phy_inband_caps(struct phy_device *phydev,
-+                           phy_interface_t interface)
-+{
-+      if (phydev->drv && phydev->drv->inband_caps)
-+              return phydev->drv->inband_caps(phydev, interface);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(phy_inband_caps);
-+
-+/**
-  * _phy_start_aneg - start auto-negotiation for this PHY device
-  * @phydev: the phy_device struct
-  *
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -826,6 +826,24 @@ struct phy_tdr_config {
- #define PHY_PAIR_ALL -1
- /**
-+ * enum link_inband_signalling - in-band signalling modes that are supported
-+ *
-+ * @LINK_INBAND_DISABLE: in-band signalling can be disabled
-+ * @LINK_INBAND_ENABLE: in-band signalling can be enabled without bypass
-+ * @LINK_INBAND_BYPASS: in-band signalling can be enabled with bypass
-+ *
-+ * The possible and required bits can only be used if the valid bit is set.
-+ * If possible is clear, that means inband signalling can not be used.
-+ * Required is only valid when possible is set, and means that inband
-+ * signalling must be used.
-+ */
-+enum link_inband_signalling {
-+      LINK_INBAND_DISABLE             = BIT(0),
-+      LINK_INBAND_ENABLE              = BIT(1),
-+      LINK_INBAND_BYPASS              = BIT(2),
-+};
-+
-+/**
-  * struct phy_plca_cfg - Configuration of the PLCA (Physical Layer Collision
-  * Avoidance) Reconciliation Sublayer.
-  *
-@@ -964,6 +982,14 @@ struct phy_driver {
-       int (*get_features)(struct phy_device *phydev);
-       /**
-+       * @inband_caps: query whether in-band is supported for the given PHY
-+       * interface mode. Returns a bitmask of bits defined by enum
-+       * link_inband_signalling.
-+       */
-+      unsigned int (*inband_caps)(struct phy_device *phydev,
-+                                  phy_interface_t interface);
-+
-+      /**
-        * @get_rate_matching: Get the supported type of rate matching for a
-        * particular phy interface. This is used by phy consumers to determine
-        * whether to advertise lower-speed modes for that interface. It is
-@@ -1842,6 +1868,8 @@ int phy_config_aneg(struct phy_device *p
- int _phy_start_aneg(struct phy_device *phydev);
- int phy_start_aneg(struct phy_device *phydev);
- int phy_aneg_done(struct phy_device *phydev);
-+unsigned int phy_inband_caps(struct phy_device *phydev,
-+                           phy_interface_t interface);
- int phy_speed_down(struct phy_device *phydev, bool sync);
- int phy_speed_up(struct phy_device *phydev);
- bool phy_check_valid(int speed, int duplex, unsigned long *features);
diff --git a/target/linux/generic/backport-6.18/601-05-v6.14-net-phy-bcm84881-implement-phy_inband_caps-method.patch b/target/linux/generic/backport-6.18/601-05-v6.14-net-phy-bcm84881-implement-phy_inband_caps-method.patch
deleted file mode 100644 (file)
index 0ba3cd2..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From c64c7fa0a774d9da72071a8517e359992baac982 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:07 +0000
-Subject: [PATCH 05/13] net: phy: bcm84881: implement phy_inband_caps() method
-
-BCM84881 has no support for inband signalling, so this is a trivial
-implementation that returns no support for inband.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Acked-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/E1tIUrj-006IU6-ON@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/bcm84881.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/net/phy/bcm84881.c
-+++ b/drivers/net/phy/bcm84881.c
-@@ -235,11 +235,21 @@ static int bcm84881_read_status(struct p
-       return genphy_c45_read_mdix(phydev);
- }
-+/* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII
-+ * or 802.3z control word, so inband will not work.
-+ */
-+static unsigned int bcm84881_inband_caps(struct phy_device *phydev,
-+                                       phy_interface_t interface)
-+{
-+      return LINK_INBAND_DISABLE;
-+}
-+
- static struct phy_driver bcm84881_drivers[] = {
-       {
-               .phy_id         = 0xae025150,
-               .phy_id_mask    = 0xfffffff0,
-               .name           = "Broadcom BCM84881",
-+              .inband_caps    = bcm84881_inband_caps,
-               .config_init    = bcm84881_config_init,
-               .probe          = bcm84881_probe,
-               .get_features   = bcm84881_get_features,
diff --git a/target/linux/generic/backport-6.18/601-06-v6.14-net-phy-marvell-implement-phy_inband_caps-method.patch b/target/linux/generic/backport-6.18/601-06-v6.14-net-phy-marvell-implement-phy_inband_caps-method.patch
deleted file mode 100644 (file)
index e2dfeba..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-From 1c86828dff88e28b8ade6bddeee0163a023faf91 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:12 +0000
-Subject: [PATCH 06/13] net: phy: marvell: implement phy_inband_caps() method
-
-Provide an implementation for phy_inband_caps() for Marvell PHYs used
-on SFP modules, so that phylink knows the PHYs capabilities.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUro-006IUC-Rq@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/marvell.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -716,6 +716,20 @@ static int marvell_config_aneg_fiber(str
-       return genphy_check_and_restart_aneg(phydev, changed);
- }
-+static unsigned int m88e1111_inband_caps(struct phy_device *phydev,
-+                                       phy_interface_t interface)
-+{
-+      /* In 1000base-X and SGMII modes, the inband mode can be changed
-+       * through the Fibre page BMCR ANENABLE bit.
-+       */
-+      if (interface == PHY_INTERFACE_MODE_1000BASEX ||
-+          interface == PHY_INTERFACE_MODE_SGMII)
-+              return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE |
-+                     LINK_INBAND_BYPASS;
-+
-+      return 0;
-+}
-+
- static int m88e1111_config_aneg(struct phy_device *phydev)
- {
-       int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR);
-@@ -3704,6 +3718,7 @@ static struct phy_driver marvell_drivers
-               .name = "Marvell 88E1112",
-               /* PHY_GBIT_FEATURES */
-               .probe = marvell_probe,
-+              .inband_caps = m88e1111_inband_caps,
-               .config_init = m88e1112_config_init,
-               .config_aneg = marvell_config_aneg,
-               .config_intr = marvell_config_intr,
-@@ -3725,6 +3740,7 @@ static struct phy_driver marvell_drivers
-               /* PHY_GBIT_FEATURES */
-               .flags = PHY_POLL_CABLE_TEST,
-               .probe = marvell_probe,
-+              .inband_caps = m88e1111_inband_caps,
-               .config_init = m88e1111gbe_config_init,
-               .config_aneg = m88e1111_config_aneg,
-               .read_status = marvell_read_status,
-@@ -3748,6 +3764,7 @@ static struct phy_driver marvell_drivers
-               .name = "Marvell 88E1111 (Finisar)",
-               /* PHY_GBIT_FEATURES */
-               .probe = marvell_probe,
-+              .inband_caps = m88e1111_inband_caps,
-               .config_init = m88e1111gbe_config_init,
-               .config_aneg = m88e1111_config_aneg,
-               .read_status = marvell_read_status,
diff --git a/target/linux/generic/backport-6.18/601-07-v6.14-net-phy-add-phy_config_inband.patch b/target/linux/generic/backport-6.18/601-07-v6.14-net-phy-add-phy_config_inband.patch
deleted file mode 100644 (file)
index d667bcb..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 5d58a890c02770ba8d790b1f3c6e8c0e20514dc2 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:18 +0000
-Subject: [PATCH 07/13] net: phy: add phy_config_inband()
-
-Add a method to configure the PHY's in-band mode.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUru-006IUI-08@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phy.c | 32 ++++++++++++++++++++++++++++++++
- include/linux/phy.h   |  6 ++++++
- 2 files changed, 38 insertions(+)
-
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -1070,6 +1070,38 @@ unsigned int phy_inband_caps(struct phy_
- EXPORT_SYMBOL_GPL(phy_inband_caps);
- /**
-+ * phy_config_inband - configure the desired PHY in-band mode
-+ * @phydev: the phy_device struct
-+ * @modes: in-band modes to configure
-+ *
-+ * Description: disables, enables or enables-with-bypass in-band signalling
-+ *   between the PHY and host system.
-+ *
-+ * Returns: zero on success, or negative errno value.
-+ */
-+int phy_config_inband(struct phy_device *phydev, unsigned int modes)
-+{
-+      int err;
-+
-+      if (!!(modes & LINK_INBAND_DISABLE) +
-+          !!(modes & LINK_INBAND_ENABLE) +
-+          !!(modes & LINK_INBAND_BYPASS) != 1)
-+              return -EINVAL;
-+
-+      mutex_lock(&phydev->lock);
-+      if (!phydev->drv)
-+              err = -EIO;
-+      else if (!phydev->drv->config_inband)
-+              err = -EOPNOTSUPP;
-+      else
-+              err = phydev->drv->config_inband(phydev, modes);
-+      mutex_unlock(&phydev->lock);
-+
-+      return err;
-+}
-+EXPORT_SYMBOL(phy_config_inband);
-+
-+/**
-  * _phy_start_aneg - start auto-negotiation for this PHY device
-  * @phydev: the phy_device struct
-  *
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -990,6 +990,11 @@ struct phy_driver {
-                                   phy_interface_t interface);
-       /**
-+       * @config_inband: configure in-band mode for the PHY
-+       */
-+      int (*config_inband)(struct phy_device *phydev, unsigned int modes);
-+
-+      /**
-        * @get_rate_matching: Get the supported type of rate matching for a
-        * particular phy interface. This is used by phy consumers to determine
-        * whether to advertise lower-speed modes for that interface. It is
-@@ -1870,6 +1875,7 @@ int phy_start_aneg(struct phy_device *ph
- int phy_aneg_done(struct phy_device *phydev);
- unsigned int phy_inband_caps(struct phy_device *phydev,
-                            phy_interface_t interface);
-+int phy_config_inband(struct phy_device *phydev, unsigned int modes);
- int phy_speed_down(struct phy_device *phydev, bool sync);
- int phy_speed_up(struct phy_device *phydev);
- bool phy_check_valid(int speed, int duplex, unsigned long *features);
diff --git a/target/linux/generic/backport-6.18/601-08-v6.14-net-phy-marvell-implement-config_inband-method.patch b/target/linux/generic/backport-6.18/601-08-v6.14-net-phy-marvell-implement-config_inband-method.patch
deleted file mode 100644 (file)
index 4531c50..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From a219912e0fec73c346e64ef47013cb2e152f88fc Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:23 +0000
-Subject: [PATCH 08/13] net: phy: marvell: implement config_inband() method
-
-Implement the config_inband() method for Marvell 88E1112, 88E1111,
-and Finisar's 88E1111 variant.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUrz-006IUO-3r@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/marvell.c | 31 +++++++++++++++++++++++++++++++
- 1 file changed, 31 insertions(+)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -730,6 +730,34 @@ static unsigned int m88e1111_inband_caps
-       return 0;
- }
-+static int m88e1111_config_inband(struct phy_device *phydev, unsigned int modes)
-+{
-+      u16 extsr, bmcr;
-+      int err;
-+
-+      if (phydev->interface != PHY_INTERFACE_MODE_1000BASEX &&
-+          phydev->interface != PHY_INTERFACE_MODE_SGMII)
-+              return -EINVAL;
-+
-+      if (modes == LINK_INBAND_BYPASS)
-+              extsr = MII_M1111_HWCFG_SERIAL_AN_BYPASS;
-+      else
-+              extsr = 0;
-+
-+      if (modes == LINK_INBAND_DISABLE)
-+              bmcr = 0;
-+      else
-+              bmcr = BMCR_ANENABLE;
-+
-+      err = phy_modify(phydev, MII_M1111_PHY_EXT_SR,
-+                       MII_M1111_HWCFG_SERIAL_AN_BYPASS, extsr);
-+      if (err < 0)
-+              return extsr;
-+
-+      return phy_modify_paged(phydev, MII_MARVELL_FIBER_PAGE, MII_BMCR,
-+                              BMCR_ANENABLE, bmcr);
-+}
-+
- static int m88e1111_config_aneg(struct phy_device *phydev)
- {
-       int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR);
-@@ -3719,6 +3747,7 @@ static struct phy_driver marvell_drivers
-               /* PHY_GBIT_FEATURES */
-               .probe = marvell_probe,
-               .inband_caps = m88e1111_inband_caps,
-+              .config_inband = m88e1111_config_inband,
-               .config_init = m88e1112_config_init,
-               .config_aneg = marvell_config_aneg,
-               .config_intr = marvell_config_intr,
-@@ -3741,6 +3770,7 @@ static struct phy_driver marvell_drivers
-               .flags = PHY_POLL_CABLE_TEST,
-               .probe = marvell_probe,
-               .inband_caps = m88e1111_inband_caps,
-+              .config_inband = m88e1111_config_inband,
-               .config_init = m88e1111gbe_config_init,
-               .config_aneg = m88e1111_config_aneg,
-               .read_status = marvell_read_status,
-@@ -3765,6 +3795,7 @@ static struct phy_driver marvell_drivers
-               /* PHY_GBIT_FEATURES */
-               .probe = marvell_probe,
-               .inband_caps = m88e1111_inband_caps,
-+              .config_inband = m88e1111_config_inband,
-               .config_init = m88e1111gbe_config_init,
-               .config_aneg = m88e1111_config_aneg,
-               .read_status = marvell_read_status,
diff --git a/target/linux/generic/backport-6.18/601-09-v6.14-net-phylink-add-pcs_inband_caps-method.patch b/target/linux/generic/backport-6.18/601-09-v6.14-net-phylink-add-pcs_inband_caps-method.patch
deleted file mode 100644 (file)
index 4228024..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-From df874f9e52c340cc6f0a0014a97b778f67d46849 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:28 +0000
-Subject: [PATCH 09/13] net: phylink: add pcs_inband_caps() method
-
-Add a pcs_inband_caps() method to query the PCS for its inband link
-capabilities, and use this to determine whether link modes used with
-optical SFPs can be supported.
-
-When a PCS does not provide a method, we allow inband negotiation to
-be either on or off, making this a no-op until the pcs_inband_caps()
-method is implemented by a PCS driver.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUs4-006IUU-7K@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 60 +++++++++++++++++++++++++++++++++++++++
- include/linux/phylink.h   | 17 +++++++++++
- 2 files changed, 77 insertions(+)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1007,6 +1007,15 @@ static void phylink_resolve_an_pause(str
-       }
- }
-+static unsigned int phylink_pcs_inband_caps(struct phylink_pcs *pcs,
-+                                  phy_interface_t interface)
-+{
-+      if (pcs && pcs->ops->pcs_inband_caps)
-+              return pcs->ops->pcs_inband_caps(pcs, interface);
-+
-+      return 0;
-+}
-+
- static void phylink_pcs_pre_config(struct phylink_pcs *pcs,
-                                  phy_interface_t interface)
- {
-@@ -1060,6 +1069,24 @@ static void phylink_pcs_link_up(struct p
-               pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex);
- }
-+/* Query inband for a specific interface mode, asking the MAC for the
-+ * PCS which will be used to handle the interface mode.
-+ */
-+static unsigned int phylink_inband_caps(struct phylink *pl,
-+                                       phy_interface_t interface)
-+{
-+      struct phylink_pcs *pcs;
-+
-+      if (!pl->mac_ops->mac_select_pcs)
-+              return 0;
-+
-+      pcs = pl->mac_ops->mac_select_pcs(pl->config, interface);
-+      if (!pcs)
-+              return 0;
-+
-+      return phylink_pcs_inband_caps(pcs, interface);
-+}
-+
- static void phylink_pcs_poll_stop(struct phylink *pl)
- {
-       if (pl->cfg_link_an_mode == MLO_AN_INBAND)
-@@ -2530,6 +2557,26 @@ int phylink_ethtool_ksettings_get(struct
- }
- EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get);
-+static bool phylink_validate_pcs_inband_autoneg(struct phylink *pl,
-+                                              phy_interface_t interface,
-+                                              unsigned long *adv)
-+{
-+      unsigned int inband = phylink_inband_caps(pl, interface);
-+      unsigned int mask;
-+
-+      /* If the PCS doesn't implement inband support, be permissive. */
-+      if (!inband)
-+              return true;
-+
-+      if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, adv))
-+              mask = LINK_INBAND_ENABLE;
-+      else
-+              mask = LINK_INBAND_DISABLE;
-+
-+      /* Check whether the PCS implements the required mode */
-+      return !!(inband & mask);
-+}
-+
- /**
-  * phylink_ethtool_ksettings_set() - set the link settings
-  * @pl: a pointer to a &struct phylink returned from phylink_create()
-@@ -2665,6 +2712,13 @@ int phylink_ethtool_ksettings_set(struct
-           phylink_is_empty_linkmode(config.advertising))
-               return -EINVAL;
-+      /* Validate the autonegotiation state. We don't have a PHY in this
-+       * situation, so the PCS is the media-facing entity.
-+       */
-+      if (!phylink_validate_pcs_inband_autoneg(pl, config.interface,
-+                                               config.advertising))
-+              return -EINVAL;
-+
-       mutex_lock(&pl->state_mutex);
-       pl->link_config.speed = config.speed;
-       pl->link_config.duplex = config.duplex;
-@@ -3349,6 +3403,12 @@ static int phylink_sfp_config_optical(st
-       phylink_dbg(pl, "optical SFP: chosen %s interface\n",
-                   phy_modes(interface));
-+      if (!phylink_validate_pcs_inband_autoneg(pl, interface,
-+                                               config.advertising)) {
-+              phylink_err(pl, "autoneg setting not compatible with PCS");
-+              return -EINVAL;
-+      }
-+
-       config.interface = interface;
-       /* Ignore errors if we're expecting a PHY to attach later */
---- a/include/linux/phylink.h
-+++ b/include/linux/phylink.h
-@@ -419,6 +419,7 @@ struct phylink_pcs {
- /**
-  * struct phylink_pcs_ops - MAC PCS operations structure.
-  * @pcs_validate: validate the link configuration.
-+ * @pcs_inband_caps: query inband support for interface mode.
-  * @pcs_enable: enable the PCS.
-  * @pcs_disable: disable the PCS.
-  * @pcs_pre_config: pre-mac_config method (for errata)
-@@ -434,6 +435,8 @@ struct phylink_pcs {
- struct phylink_pcs_ops {
-       int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
-                           const struct phylink_link_state *state);
-+      unsigned int (*pcs_inband_caps)(struct phylink_pcs *pcs,
-+                                      phy_interface_t interface);
-       int (*pcs_enable)(struct phylink_pcs *pcs);
-       void (*pcs_disable)(struct phylink_pcs *pcs);
-       void (*pcs_pre_config)(struct phylink_pcs *pcs,
-@@ -471,6 +474,20 @@ int pcs_validate(struct phylink_pcs *pcs
-                const struct phylink_link_state *state);
- /**
-+ * pcs_inband_caps - query PCS in-band capabilities for interface mode.
-+ * @pcs: a pointer to a &struct phylink_pcs.
-+ * @interface: interface mode to be queried
-+ *
-+ * Returns zero if it is unknown what in-band signalling is supported by the
-+ * PHY (e.g. because the PHY driver doesn't implement the method.) Otherwise,
-+ * returns a bit mask of the LINK_INBAND_* values from
-+ * &enum link_inband_signalling to describe which inband modes are supported
-+ * for this interface mode.
-+ */
-+unsigned int pcs_inband_caps(struct phylink_pcs *pcs,
-+                           phy_interface_t interface);
-+
-+/**
-  * pcs_enable() - enable the PCS.
-  * @pcs: a pointer to a &struct phylink_pcs.
-  */
diff --git a/target/linux/generic/backport-6.18/601-10-v6.14-net-mvneta-implement-pcs_inband_caps-method.patch b/target/linux/generic/backport-6.18/601-10-v6.14-net-mvneta-implement-pcs_inband_caps-method.patch
deleted file mode 100644 (file)
index 0937ad1..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-From 513e8fb8fa32035b3325e2e14fb9598f8cb545e9 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:33 +0000
-Subject: [PATCH 10/13] net: mvneta: implement pcs_inband_caps() method
-
-Report the PCS in-band capabilities to phylink for Marvell NETA
-interfaces.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUs9-006IUb-Au@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/marvell/mvneta.c | 27 +++++++++++++++++----------
- 1 file changed, 17 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -3960,20 +3960,27 @@ static struct mvneta_port *mvneta_pcs_to
-       return container_of(pcs, struct mvneta_port, phylink_pcs);
- }
--static int mvneta_pcs_validate(struct phylink_pcs *pcs,
--                             unsigned long *supported,
--                             const struct phylink_link_state *state)
-+static unsigned int mvneta_pcs_inband_caps(struct phylink_pcs *pcs,
-+                                         phy_interface_t interface)
- {
--      /* We only support QSGMII, SGMII, 802.3z and RGMII modes.
--       * When in 802.3z mode, we must have AN enabled:
-+      /* When operating in an 802.3z mode, we must have AN enabled:
-        * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ...
-        * When <PortType> = 1 (1000BASE-X) this field must be set to 1."
-+       * Therefore, inband is "required".
-        */
--      if (phy_interface_mode_is_8023z(state->interface) &&
--          !phylink_test(state->advertising, Autoneg))
--              return -EINVAL;
-+      if (phy_interface_mode_is_8023z(interface))
-+              return LINK_INBAND_ENABLE;
--      return 0;
-+      /* QSGMII, SGMII and RGMII can be configured to use inband
-+       * signalling of the AN result. Indicate these as "possible".
-+       */
-+      if (interface == PHY_INTERFACE_MODE_SGMII ||
-+          interface == PHY_INTERFACE_MODE_QSGMII ||
-+          phy_interface_mode_is_rgmii(interface))
-+              return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-+
-+      /* For any other modes, indicate that inband is not supported. */
-+      return LINK_INBAND_DISABLE;
- }
- static void mvneta_pcs_get_state(struct phylink_pcs *pcs,
-@@ -4071,7 +4078,7 @@ static void mvneta_pcs_an_restart(struct
- }
- static const struct phylink_pcs_ops mvneta_phylink_pcs_ops = {
--      .pcs_validate = mvneta_pcs_validate,
-+      .pcs_inband_caps = mvneta_pcs_inband_caps,
-       .pcs_get_state = mvneta_pcs_get_state,
-       .pcs_config = mvneta_pcs_config,
-       .pcs_an_restart = mvneta_pcs_an_restart,
diff --git a/target/linux/generic/backport-6.18/601-11-v6.14-net-mvpp2-implement-pcs_inband_caps-method.patch b/target/linux/generic/backport-6.18/601-11-v6.14-net-mvpp2-implement-pcs_inband_caps-method.patch
deleted file mode 100644 (file)
index 846d9df..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From d4169f0c7665afb8d8adb5e1b1df3db88517d0ad Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:38 +0000
-Subject: [PATCH 11/13] net: mvpp2: implement pcs_inband_caps() method
-
-Report the PCS in-band capabilities to phylink for Marvell PP2
-interfaces.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUsE-006IUh-E7@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 25 ++++++++++++-------
- 1 file changed, 16 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
-@@ -6237,19 +6237,26 @@ static const struct phylink_pcs_ops mvpp
-       .pcs_config = mvpp2_xlg_pcs_config,
- };
--static int mvpp2_gmac_pcs_validate(struct phylink_pcs *pcs,
--                                 unsigned long *supported,
--                                 const struct phylink_link_state *state)
-+static unsigned int mvpp2_gmac_pcs_inband_caps(struct phylink_pcs *pcs,
-+                                             phy_interface_t interface)
- {
--      /* When in 802.3z mode, we must have AN enabled:
-+      /* When operating in an 802.3z mode, we must have AN enabled:
-        * Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ...
-        * When <PortType> = 1 (1000BASE-X) this field must be set to 1.
-+       * Therefore, inband is "required".
-        */
--      if (phy_interface_mode_is_8023z(state->interface) &&
--          !phylink_test(state->advertising, Autoneg))
--              return -EINVAL;
-+      if (phy_interface_mode_is_8023z(interface))
-+              return LINK_INBAND_ENABLE;
--      return 0;
-+      /* SGMII and RGMII can be configured to use inband signalling of the
-+       * AN result. Indicate these as "possible".
-+       */
-+      if (interface == PHY_INTERFACE_MODE_SGMII ||
-+          phy_interface_mode_is_rgmii(interface))
-+              return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-+
-+      /* For any other modes, indicate that inband is not supported. */
-+      return LINK_INBAND_DISABLE;
- }
- static void mvpp2_gmac_pcs_get_state(struct phylink_pcs *pcs,
-@@ -6356,7 +6363,7 @@ static void mvpp2_gmac_pcs_an_restart(st
- }
- static const struct phylink_pcs_ops mvpp2_phylink_gmac_pcs_ops = {
--      .pcs_validate = mvpp2_gmac_pcs_validate,
-+      .pcs_inband_caps = mvpp2_gmac_pcs_inband_caps,
-       .pcs_get_state = mvpp2_gmac_pcs_get_state,
-       .pcs_config = mvpp2_gmac_pcs_config,
-       .pcs_an_restart = mvpp2_gmac_pcs_an_restart,
diff --git a/target/linux/generic/backport-6.18/601-12-v6.14-net-phylink-add-negotiation-of-in-band-capabilities.patch b/target/linux/generic/backport-6.18/601-12-v6.14-net-phylink-add-negotiation-of-in-band-capabilities.patch
deleted file mode 100644 (file)
index f629133..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-From 5fd0f1a02e750e2db4038dee60edea669ce5aab1 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:43 +0000
-Subject: [PATCH 12/13] net: phylink: add negotiation of in-band capabilities
-
-Support for in-band signalling with Serdes links is uncertain. Some
-PHYs do not support in-band for e.g. SGMII. Some PCS do not support
-in-band for 2500Base-X. Some PCS require in-band for Base-X protocols.
-
-Simply using what is in DT is insufficient when we have hot-pluggable
-PHYs e.g. in the form of SFP modules, which may not provide the
-in-band signalling.
-
-In order to address this, we have introduced phy_inband_caps() and
-pcs_inband_caps() functions to allow phylink to retrieve the
-capabilities from each end of the PCS/PHY link. This commit adds code
-to resolve whether in-band will be used in the various scenarios that
-we have: In-band not being used, PHY present using SGMII or Base-X,
-PHY not present. We also deal with no capabilties provided.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUsJ-006IUn-H3@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 154 +++++++++++++++++++++++++++++++++++---
- 1 file changed, 144 insertions(+), 10 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -75,6 +75,7 @@ struct phylink {
-       struct mutex state_mutex;
-       struct phylink_link_state phy_state;
-+      unsigned int phy_ib_mode;
-       struct work_struct resolve;
-       unsigned int pcs_neg_mode;
-       unsigned int pcs_state;
-@@ -1170,10 +1171,18 @@ static void phylink_pcs_neg_mode(struct
-                                phy_interface_t interface,
-                                const unsigned long *advertising)
- {
-+      unsigned int pcs_ib_caps = 0;
-+      unsigned int phy_ib_caps = 0;
-       unsigned int neg_mode, mode;
-+      enum {
-+              INBAND_CISCO_SGMII,
-+              INBAND_BASEX,
-+      } type;
-       mode = pl->req_link_an_mode;
-+      pl->phy_ib_mode = 0;
-+
-       switch (interface) {
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_QSGMII:
-@@ -1185,10 +1194,7 @@ static void phylink_pcs_neg_mode(struct
-                * inband communication. Note: there exist PHYs that run
-                * with SGMII but do not send the inband data.
-                */
--              if (!phylink_autoneg_inband(mode))
--                      neg_mode = PHYLINK_PCS_NEG_OUTBAND;
--              else
--                      neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
-+              type = INBAND_CISCO_SGMII;
-               break;
-       case PHY_INTERFACE_MODE_1000BASEX:
-@@ -1199,18 +1205,139 @@ static void phylink_pcs_neg_mode(struct
-                * as well, but drivers may not support this, so may
-                * need to override this.
-                */
--              if (!phylink_autoneg_inband(mode))
-+              type = INBAND_BASEX;
-+              break;
-+
-+      default:
-+              pl->pcs_neg_mode = PHYLINK_PCS_NEG_NONE;
-+              pl->act_link_an_mode = mode;
-+              return;
-+      }
-+
-+      if (pcs)
-+              pcs_ib_caps = phylink_pcs_inband_caps(pcs, interface);
-+
-+      if (pl->phydev)
-+              phy_ib_caps = phy_inband_caps(pl->phydev, interface);
-+
-+      phylink_dbg(pl, "interface %s inband modes: pcs=%02x phy=%02x\n",
-+                  phy_modes(interface), pcs_ib_caps, phy_ib_caps);
-+
-+      if (!phylink_autoneg_inband(mode)) {
-+              bool pcs_ib_only = false;
-+              bool phy_ib_only = false;
-+
-+              if (pcs_ib_caps && pcs_ib_caps != LINK_INBAND_DISABLE) {
-+                      /* PCS supports reporting in-band capabilities, and
-+                       * supports more than disable mode.
-+                       */
-+                      if (pcs_ib_caps & LINK_INBAND_DISABLE)
-+                              neg_mode = PHYLINK_PCS_NEG_OUTBAND;
-+                      else if (pcs_ib_caps & LINK_INBAND_ENABLE)
-+                              pcs_ib_only = true;
-+              }
-+
-+              if (phy_ib_caps && phy_ib_caps != LINK_INBAND_DISABLE) {
-+                      /* PHY supports in-band capabilities, and supports
-+                       * more than disable mode.
-+                       */
-+                      if (phy_ib_caps & LINK_INBAND_DISABLE)
-+                              pl->phy_ib_mode = LINK_INBAND_DISABLE;
-+                      else if (phy_ib_caps & LINK_INBAND_BYPASS)
-+                              pl->phy_ib_mode = LINK_INBAND_BYPASS;
-+                      else if (phy_ib_caps & LINK_INBAND_ENABLE)
-+                              phy_ib_only = true;
-+              }
-+
-+              /* If either the PCS or PHY requires inband to be enabled,
-+               * this is an invalid configuration. Provide a diagnostic
-+               * message for this case, but don't try to force the issue.
-+               */
-+              if (pcs_ib_only || phy_ib_only)
-+                      phylink_warn(pl,
-+                                   "firmware wants %s mode, but %s%s%s requires inband\n",
-+                                   phylink_an_mode_str(mode),
-+                                   pcs_ib_only ? "PCS" : "",
-+                                   pcs_ib_only && phy_ib_only ? " and " : "",
-+                                   phy_ib_only ? "PHY" : "");
-+
-+              neg_mode = PHYLINK_PCS_NEG_OUTBAND;
-+      } else if (type == INBAND_CISCO_SGMII || pl->phydev) {
-+              /* For SGMII modes which are designed to be used with PHYs, or
-+               * Base-X with a PHY, we try to use in-band mode where-ever
-+               * possible. However, there are some PHYs e.g. BCM84881 which
-+               * do not support in-band.
-+               */
-+              const unsigned int inband_ok = LINK_INBAND_ENABLE |
-+                                             LINK_INBAND_BYPASS;
-+              const unsigned int outband_ok = LINK_INBAND_DISABLE |
-+                                              LINK_INBAND_BYPASS;
-+              /* PCS  PHY
-+               * D E  D E
-+               * 0 0  0 0     no information                  inband enabled
-+               * 1 0  0 0     pcs doesn't support             outband
-+               * 0 1  0 0     pcs required                    inband enabled
-+               * 1 1  0 0     pcs optional                    inband enabled
-+               * 0 0  1 0     phy doesn't support             outband
-+               * 1 0  1 0     pcs+phy doesn't support         outband
-+               * 0 1  1 0     pcs required, phy doesn't support, invalid
-+               * 1 1  1 0     pcs optional, phy doesn't support, outband
-+               * 0 0  0 1     phy required                    inband enabled
-+               * 1 0  0 1     pcs doesn't support, phy required, invalid
-+               * 0 1  0 1     pcs+phy required                inband enabled
-+               * 1 1  0 1     pcs optional, phy required      inband enabled
-+               * 0 0  1 1     phy optional                    inband enabled
-+               * 1 0  1 1     pcs doesn't support, phy optional, outband
-+               * 0 1  1 1     pcs required, phy optional      inband enabled
-+               * 1 1  1 1     pcs+phy optional                inband enabled
-+               */
-+              if ((!pcs_ib_caps || pcs_ib_caps & inband_ok) &&
-+                  (!phy_ib_caps || phy_ib_caps & inband_ok)) {
-+                      /* In-band supported or unknown at both ends. Enable
-+                       * in-band mode with or without bypass at the PHY.
-+                       */
-+                      if (phy_ib_caps & LINK_INBAND_ENABLE)
-+                              pl->phy_ib_mode = LINK_INBAND_ENABLE;
-+                      else if (phy_ib_caps & LINK_INBAND_BYPASS)
-+                              pl->phy_ib_mode = LINK_INBAND_BYPASS;
-+
-+                      neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
-+              } else if ((!pcs_ib_caps || pcs_ib_caps & outband_ok) &&
-+                         (!phy_ib_caps || phy_ib_caps & outband_ok)) {
-+                      /* Either in-band not supported at at least one end.
-+                       * In-band bypass at the other end is possible.
-+                       */
-+                      if (phy_ib_caps & LINK_INBAND_DISABLE)
-+                              pl->phy_ib_mode = LINK_INBAND_DISABLE;
-+                      else if (phy_ib_caps & LINK_INBAND_BYPASS)
-+                              pl->phy_ib_mode = LINK_INBAND_BYPASS;
-+
-                       neg_mode = PHYLINK_PCS_NEG_OUTBAND;
-+                      if (pl->phydev)
-+                              mode = MLO_AN_PHY;
-+              } else {
-+                      /* invalid */
-+                      phylink_warn(pl, "%s: incompatible in-band capabilities, trying in-band",
-+                                   phy_modes(interface));
-+                      neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
-+              }
-+      } else {
-+              /* For Base-X without a PHY */
-+              if (pcs_ib_caps == LINK_INBAND_DISABLE)
-+                      /* If the PCS doesn't support inband, then inband must
-+                       * be disabled.
-+                       */
-+                      neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED;
-+              else if (pcs_ib_caps == LINK_INBAND_ENABLE)
-+                      /* If the PCS requires inband, then inband must always
-+                       * be enabled.
-+                       */
-+                      neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
-               else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-                                          advertising))
-                       neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
-               else
-                       neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED;
--              break;
--
--      default:
--              neg_mode = PHYLINK_PCS_NEG_NONE;
--              break;
-       }
-       pl->pcs_neg_mode = neg_mode;
-@@ -1309,6 +1436,13 @@ static void phylink_major_config(struct
-                                   ERR_PTR(err));
-       }
-+      if (pl->phydev && pl->phy_ib_mode) {
-+              err = phy_config_inband(pl->phydev, pl->phy_ib_mode);
-+              if (err < 0)
-+                      phylink_err(pl, "phy_config_inband: %pe\n",
-+                                  ERR_PTR(err));
-+      }
-+
-       if (pl->sfp_bus) {
-               rate_kbd = phylink_interface_signal_rate(state->interface);
-               if (rate_kbd)
diff --git a/target/linux/generic/backport-6.18/601-13-v6.14-net-phylink-remove-phylink_phy_no_inband.patch b/target/linux/generic/backport-6.18/601-13-v6.14-net-phylink-remove-phylink_phy_no_inband.patch
deleted file mode 100644 (file)
index 8be74a2..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-From 77ac9a8b2536e0eaca6c6f21070068458bf55981 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Tue, 3 Dec 2024 15:31:48 +0000
-Subject: [PATCH 13/13] net: phylink: remove phylink_phy_no_inband()
-
-Remove phylink_phy_no_inband() now that we are handling the lack of
-inband negotiation by querying the capabilities of the PHY and PCS,
-and the BCM84881 PHY driver provides us the information necessary to
-make the decision.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tIUsO-006IUt-KN@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 27 ++++++---------------------
- 1 file changed, 6 insertions(+), 21 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -3394,10 +3394,11 @@ static phy_interface_t phylink_choose_sf
-       return interface;
- }
--static void phylink_sfp_set_config(struct phylink *pl, u8 mode,
-+static void phylink_sfp_set_config(struct phylink *pl,
-                                  unsigned long *supported,
-                                  struct phylink_link_state *state)
- {
-+      u8 mode = MLO_AN_INBAND;
-       bool changed = false;
-       phylink_dbg(pl, "requesting link mode %s/%s with support %*pb\n",
-@@ -3431,8 +3432,7 @@ static void phylink_sfp_set_config(struc
-               phylink_mac_initial_config(pl, false);
- }
--static int phylink_sfp_config_phy(struct phylink *pl, u8 mode,
--                                struct phy_device *phy)
-+static int phylink_sfp_config_phy(struct phylink *pl, struct phy_device *phy)
- {
-       __ETHTOOL_DECLARE_LINK_MODE_MASK(support1);
-       __ETHTOOL_DECLARE_LINK_MODE_MASK(support);
-@@ -3472,7 +3472,7 @@ static int phylink_sfp_config_phy(struct
-       if (ret) {
-               phylink_err(pl,
-                           "validation of %s/%s with support %*pb failed: %pe\n",
--                          phylink_an_mode_str(mode),
-+                          phylink_an_mode_str(pl->req_link_an_mode),
-                           phy_modes(config.interface),
-                           __ETHTOOL_LINK_MODE_MASK_NBITS, support,
-                           ERR_PTR(ret));
-@@ -3481,7 +3481,7 @@ static int phylink_sfp_config_phy(struct
-       pl->link_port = pl->sfp_port;
--      phylink_sfp_set_config(pl, mode, support, &config);
-+      phylink_sfp_set_config(pl, support, &config);
-       return 0;
- }
-@@ -3556,7 +3556,7 @@ static int phylink_sfp_config_optical(st
-       pl->link_port = pl->sfp_port;
--      phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config);
-+      phylink_sfp_set_config(pl, pl->sfp_support, &config);
-       return 0;
- }
-@@ -3627,20 +3627,10 @@ static void phylink_sfp_link_up(void *up
-       phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_LINK);
- }
--/* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII
-- * or 802.3z control word, so inband will not work.
-- */
--static bool phylink_phy_no_inband(struct phy_device *phy)
--{
--      return phy->is_c45 && phy_id_compare(phy->c45_ids.device_ids[1],
--                                           0xae025150, 0xfffffff0);
--}
--
- static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
- {
-       struct phylink *pl = upstream;
-       phy_interface_t interface;
--      u8 mode;
-       int ret;
-       /*
-@@ -3652,17 +3642,12 @@ static int phylink_sfp_connect_phy(void
-        */
-       phy_support_asym_pause(phy);
--      if (phylink_phy_no_inband(phy))
--              mode = MLO_AN_PHY;
--      else
--              mode = MLO_AN_INBAND;
--
-       /* Set the PHY's host supported interfaces */
-       phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces,
-                         pl->config->supported_interfaces);
-       /* Do the initial configuration */
--      ret = phylink_sfp_config_phy(pl, mode, phy);
-+      ret = phylink_sfp_config_phy(pl, phy);
-       if (ret < 0)
-               return ret;
diff --git a/target/linux/generic/backport-6.18/602-01-v6.14-net-pcs-pcs-lynx-implement-pcs_inband_caps-method.patch b/target/linux/generic/backport-6.18/602-01-v6.14-net-pcs-pcs-lynx-implement-pcs_inband_caps-method.patch
deleted file mode 100644 (file)
index 32ba605..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From 6561f0e547be221f411fda5eddfcc5bd8bb058a5 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 5 Dec 2024 09:42:24 +0000
-Subject: [PATCH 1/3] net: pcs: pcs-lynx: implement pcs_inband_caps() method
-
-Report the PCS in-band capabilities to phylink for the Lynx PCS.
-
-Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tJ8NM-006L5J-AH@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/pcs/pcs-lynx.c | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
---- a/drivers/net/pcs/pcs-lynx.c
-+++ b/drivers/net/pcs/pcs-lynx.c
-@@ -35,6 +35,27 @@ enum sgmii_speed {
- #define phylink_pcs_to_lynx(pl_pcs) container_of((pl_pcs), struct lynx_pcs, pcs)
- #define lynx_to_phylink_pcs(lynx) (&(lynx)->pcs)
-+static unsigned int lynx_pcs_inband_caps(struct phylink_pcs *pcs,
-+                                       phy_interface_t interface)
-+{
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_1000BASEX:
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+              return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-+
-+      case PHY_INTERFACE_MODE_10GBASER:
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              return LINK_INBAND_DISABLE;
-+
-+      case PHY_INTERFACE_MODE_USXGMII:
-+              return LINK_INBAND_ENABLE;
-+
-+      default:
-+              return 0;
-+      }
-+}
-+
- static void lynx_pcs_get_state_usxgmii(struct mdio_device *pcs,
-                                      struct phylink_link_state *state)
- {
-@@ -306,6 +327,7 @@ static void lynx_pcs_link_up(struct phyl
- }
- static const struct phylink_pcs_ops lynx_pcs_phylink_ops = {
-+      .pcs_inband_caps = lynx_pcs_inband_caps,
-       .pcs_get_state = lynx_pcs_get_state,
-       .pcs_config = lynx_pcs_config,
-       .pcs_an_restart = lynx_pcs_an_restart,
diff --git a/target/linux/generic/backport-6.18/602-02-v6.14-net-pcs-pcs-mtk-lynxi-implement-pcs_inband_caps-meth.patch b/target/linux/generic/backport-6.18/602-02-v6.14-net-pcs-pcs-mtk-lynxi-implement-pcs_inband_caps-meth.patch
deleted file mode 100644 (file)
index 1cfd3ba..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From 520d29bdda86915b3caf8c72825a574bff212553 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 5 Dec 2024 09:42:29 +0000
-Subject: [PATCH 2/3] net: pcs: pcs-mtk-lynxi: implement pcs_inband_caps()
- method
-
-Report the PCS in-band capabilities to phylink for the LynxI PCS.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tJ8NR-006L5P-E3@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/pcs/pcs-mtk-lynxi.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/drivers/net/pcs/pcs-mtk-lynxi.c
-+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
-@@ -88,6 +88,21 @@ static struct mtk_pcs_lynxi *pcs_to_mtk_
-       return container_of(pcs, struct mtk_pcs_lynxi, pcs);
- }
-+static unsigned int mtk_pcs_lynxi_inband_caps(struct phylink_pcs *pcs,
-+                                            phy_interface_t interface)
-+{
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_1000BASEX:
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+              return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-+
-+      default:
-+              return 0;
-+      }
-+}
-+
- static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
-                                   struct phylink_link_state *state)
- {
-@@ -241,6 +256,7 @@ static void mtk_pcs_lynxi_disable(struct
- }
- static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
-+      .pcs_inband_caps = mtk_pcs_lynxi_inband_caps,
-       .pcs_get_state = mtk_pcs_lynxi_get_state,
-       .pcs_config = mtk_pcs_lynxi_config,
-       .pcs_an_restart = mtk_pcs_lynxi_restart_an,
diff --git a/target/linux/generic/backport-6.18/602-03-v6.14-net-pcs-xpcs-implement-pcs_inband_caps-method.patch b/target/linux/generic/backport-6.18/602-03-v6.14-net-pcs-xpcs-implement-pcs_inband_caps-method.patch
deleted file mode 100644 (file)
index 8dc495b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-From 484d0170d6c6bbb5213d037664e9a551f793bacd Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Thu, 5 Dec 2024 09:42:34 +0000
-Subject: [PATCH 3/3] net: pcs: xpcs: implement pcs_inband_caps() method
-
-Report the PCS inband capabilities to phylink for XPCS.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/E1tJ8NW-006L5V-I9@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/pcs/pcs-xpcs.c | 28 ++++++++++++++++++++++++++++
- 1 file changed, 28 insertions(+)
-
---- a/drivers/net/pcs/pcs-xpcs.c
-+++ b/drivers/net/pcs/pcs-xpcs.c
-@@ -608,6 +608,33 @@ static int xpcs_validate(struct phylink_
-       return 0;
- }
-+static unsigned int xpcs_inband_caps(struct phylink_pcs *pcs,
-+                                   phy_interface_t interface)
-+{
-+      struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
-+      const struct dw_xpcs_compat *compat;
-+
-+      compat = xpcs_find_compat(xpcs->desc, interface);
-+      if (!compat)
-+              return 0;
-+
-+      switch (compat->an_mode) {
-+      case DW_AN_C73:
-+              return LINK_INBAND_ENABLE;
-+
-+      case DW_AN_C37_SGMII:
-+      case DW_AN_C37_1000BASEX:
-+              return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
-+
-+      case DW_10GBASER:
-+      case DW_2500BASEX:
-+              return LINK_INBAND_DISABLE;
-+
-+      default:
-+              return 0;
-+      }
-+}
-+
- void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
- {
-       int i, j;
-@@ -1365,6 +1392,7 @@ static const struct dw_xpcs_desc xpcs_de
- static const struct phylink_pcs_ops xpcs_phylink_ops = {
-       .pcs_validate = xpcs_validate,
-+      .pcs_inband_caps = xpcs_inband_caps,
-       .pcs_config = xpcs_config,
-       .pcs_get_state = xpcs_get_state,
-       .pcs_an_restart = xpcs_an_restart,
diff --git a/target/linux/generic/backport-6.18/605-02-v6.17-net-phylink-provide-phylink_get_inband_type.patch b/target/linux/generic/backport-6.18/605-02-v6.17-net-phylink-provide-phylink_get_inband_type.patch
deleted file mode 100644 (file)
index e944f57..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-From 1bd905dfea9897eafef532000702e63a66849f54 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sun, 31 Aug 2025 18:34:38 +0100
-Subject: net: phylink: provide phylink_get_inband_type()
-
-Provide a function to get the type of the inband signalling used for
-a PHY interface type. This will be used in the subsequent patch to
-address problems with 10G optical modules.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/E1uslws-00000001SP5-1R2R@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 79 ++++++++++++++++++++++-----------------
- 1 file changed, 44 insertions(+), 35 deletions(-)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1147,6 +1147,42 @@ static void phylink_pcs_an_restart(struc
-               pl->pcs->ops->pcs_an_restart(pl->pcs);
- }
-+enum inband_type {
-+      INBAND_NONE,
-+      INBAND_CISCO_SGMII,
-+      INBAND_BASEX,
-+};
-+
-+static enum inband_type phylink_get_inband_type(phy_interface_t interface)
-+{
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_SGMII:
-+      case PHY_INTERFACE_MODE_QSGMII:
-+      case PHY_INTERFACE_MODE_QUSGMII:
-+      case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10G_QXGMII:
-+              /* These protocols are designed for use with a PHY which
-+               * communicates its negotiation result back to the MAC via
-+               * inband communication. Note: there exist PHYs that run
-+               * with SGMII but do not send the inband data.
-+               */
-+              return INBAND_CISCO_SGMII;
-+
-+      case PHY_INTERFACE_MODE_1000BASEX:
-+      case PHY_INTERFACE_MODE_2500BASEX:
-+              /* 1000base-X is designed for use media-side for Fibre
-+               * connections, and thus the Autoneg bit needs to be
-+               * taken into account. We also do this for 2500base-X
-+               * as well, but drivers may not support this, so may
-+               * need to override this.
-+               */
-+              return INBAND_BASEX;
-+
-+      default:
-+              return INBAND_NONE;
-+      }
-+}
-+
- /**
-  * phylink_pcs_neg_mode() - helper to determine PCS inband mode
-  * @pl: a pointer to a &struct phylink returned from phylink_create()
-@@ -1174,46 +1210,19 @@ static void phylink_pcs_neg_mode(struct
-       unsigned int pcs_ib_caps = 0;
-       unsigned int phy_ib_caps = 0;
-       unsigned int neg_mode, mode;
--      enum {
--              INBAND_CISCO_SGMII,
--              INBAND_BASEX,
--      } type;
--
--      mode = pl->req_link_an_mode;
-+      enum inband_type type;
--      pl->phy_ib_mode = 0;
--
--      switch (interface) {
--      case PHY_INTERFACE_MODE_SGMII:
--      case PHY_INTERFACE_MODE_QSGMII:
--      case PHY_INTERFACE_MODE_QUSGMII:
--      case PHY_INTERFACE_MODE_USXGMII:
--      case PHY_INTERFACE_MODE_10G_QXGMII:
--              /* These protocols are designed for use with a PHY which
--               * communicates its negotiation result back to the MAC via
--               * inband communication. Note: there exist PHYs that run
--               * with SGMII but do not send the inband data.
--               */
--              type = INBAND_CISCO_SGMII;
--              break;
--
--      case PHY_INTERFACE_MODE_1000BASEX:
--      case PHY_INTERFACE_MODE_2500BASEX:
--              /* 1000base-X is designed for use media-side for Fibre
--               * connections, and thus the Autoneg bit needs to be
--               * taken into account. We also do this for 2500base-X
--               * as well, but drivers may not support this, so may
--               * need to override this.
--               */
--              type = INBAND_BASEX;
--              break;
--
--      default:
-+      type = phylink_get_inband_type(interface);
-+      if (type == INBAND_NONE) {
-               pl->pcs_neg_mode = PHYLINK_PCS_NEG_NONE;
--              pl->act_link_an_mode = mode;
-+              pl->act_link_an_mode = pl->req_link_an_mode;
-               return;
-       }
-+      mode = pl->req_link_an_mode;
-+
-+      pl->phy_ib_mode = 0;
-+
-       if (pcs)
-               pcs_ib_caps = phylink_pcs_inband_caps(pcs, interface);
diff --git a/target/linux/generic/backport-6.18/605-03-v6.17-net-phylink-disable-autoneg-for-interfaces-that-have.patch b/target/linux/generic/backport-6.18/605-03-v6.17-net-phylink-disable-autoneg-for-interfaces-that-have.patch
deleted file mode 100644 (file)
index 0861bb8..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From a21202743f9ce4063e86b99cccaef48ef9813379 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sun, 31 Aug 2025 18:34:43 +0100
-Subject: net: phylink: disable autoneg for interfaces that have no inband
-
-Mathew reports that as a result of commit 6561f0e547be ("net: pcs:
-pcs-lynx: implement pcs_inband_caps() method"), 10G SFP modules no
-longer work with the Lynx PCS.
-
-This problem is not specific to the Lynx PCS, but is caused by commit
-df874f9e52c3 ("net: phylink: add pcs_inband_caps() method") which added
-validation of the autoneg state to the optical SFP configuration path.
-
-Fix this by handling interface modes that fundamentally have no
-inband negotiation more correctly - if we only have a single interface
-mode, clear the Autoneg support bit and the advertising mask. If the
-module can operate with several different interface modes, autoneg may
-be supported for other modes, so leave the support mask alone and just
-clear the Autoneg bit in the advertising mask.
-
-This restores 10G optical module functionality with PCS that supply
-their inband support, and makes ethtool output look sane.
-
-Reported-by: Mathew McBride <matt@traverse.com.au>
-Closes: https://lore.kernel.org/r/025c0ebe-5537-4fa3-b05a-8b835e5ad317@app.fastmail.com
-Fixes: df874f9e52c3 ("net: phylink: add pcs_inband_caps() method")
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Link: https://patch.msgid.link/E1uslwx-00000001SPB-2kiM@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phylink.c | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -3500,6 +3500,7 @@ static int phylink_sfp_config_optical(st
-       __ETHTOOL_DECLARE_LINK_MODE_MASK(support);
-       DECLARE_PHY_INTERFACE_MASK(interfaces);
-       struct phylink_link_state config;
-+      enum inband_type inband_type;
-       phy_interface_t interface;
-       int ret;
-@@ -3546,6 +3547,23 @@ static int phylink_sfp_config_optical(st
-       phylink_dbg(pl, "optical SFP: chosen %s interface\n",
-                   phy_modes(interface));
-+      inband_type = phylink_get_inband_type(interface);
-+      if (inband_type == INBAND_NONE) {
-+              /* If this is the sole interface, and there is no inband
-+               * support, clear the advertising mask and Autoneg bit in
-+               * the support mask. Otherwise, just clear the Autoneg bit
-+               * in the advertising mask.
-+               */
-+              if (phy_interface_weight(pl->sfp_interfaces) == 1) {
-+                      linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+                                         pl->sfp_support);
-+                      linkmode_zero(config.advertising);
-+              } else {
-+                      linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-+                                         config.advertising);
-+              }
-+      }
-+
-       if (!phylink_validate_pcs_inband_autoneg(pl, interface,
-                                                config.advertising)) {
-               phylink_err(pl, "autoneg setting not compatible with PCS");
diff --git a/target/linux/generic/backport-6.18/610-01-v6.13-net-dsa-use-ethtool-string-helpers.patch b/target/linux/generic/backport-6.18/610-01-v6.13-net-dsa-use-ethtool-string-helpers.patch
deleted file mode 100644 (file)
index a435e29..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From f12b363887c706c40611fba645265527a8415832 Mon Sep 17 00:00:00 2001
-From: Rosen Penev <rosenp@gmail.com>
-Date: Sun, 27 Oct 2024 21:48:28 -0700
-Subject: [PATCH] net: dsa: use ethtool string helpers
-
-These are the preferred way to copy ethtool strings.
-
-Avoids incrementing pointers all over the place.
-
-Signed-off-by: Rosen Penev <rosenp@gmail.com>
-(for hellcreek driver)
-Reviewed-by: Kurt Kanzenbach <kurt@linutronix.de>
-Link: https://patch.msgid.link/20241028044828.1639668-1-rosenp@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1086,8 +1086,7 @@ void b53_get_strings(struct dsa_switch *
-       if (stringset == ETH_SS_STATS) {
-               for (i = 0; i < mib_size; i++)
--                      strscpy(data + i * ETH_GSTRING_LEN,
--                              mibs[i].name, ETH_GSTRING_LEN);
-+                      ethtool_puts(&data, mibs[i].name);
-       } else if (stringset == ETH_SS_PHY_STATS) {
-               phydev = b53_get_phy_device(ds, port);
-               if (!phydev)
diff --git a/target/linux/generic/backport-6.18/610-02-v6.15-net-dsa-b53-mdio-add-support-for-BCM53101.patch b/target/linux/generic/backport-6.18/610-02-v6.15-net-dsa-b53-mdio-add-support-for-BCM53101.patch
deleted file mode 100644 (file)
index 6cbe547..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-From c4f873c2b65c839ff5e7c996bd9ef5a1e7eae11a Mon Sep 17 00:00:00 2001
-From: Torben Nielsen <torben.nielsen@prevas.dk>
-Date: Mon, 17 Feb 2025 09:05:01 +0100
-Subject: [PATCH] net: dsa: b53: mdio: add support for BCM53101
-
-BCM53101 is a ethernet switch, very similar to the BCM53115.
-Enable support for it, in the existing b53 dsa driver.
-
-Signed-off-by: Torben Nielsen <torben.nielsen@prevas.dk>
-Signed-off-by: Claus Stovgaard <claus.stovgaard@prevas.dk>
-Link: https://patch.msgid.link/20250217080503.1390282-1-claus.stovgaard@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 14 ++++++++++++++
- drivers/net/dsa/b53/b53_mdio.c   |  1 +
- drivers/net/dsa/b53/b53_priv.h   |  2 ++
- 3 files changed, 17 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2606,6 +2606,19 @@ static const struct b53_chip_data b53_sw
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-       },
-       {
-+              .chip_id = BCM53101_DEVICE_ID,
-+              .dev_name = "BCM53101",
-+              .vlans = 4096,
-+              .enabled_ports = 0x11f,
-+              .arl_bins = 4,
-+              .arl_buckets = 512,
-+              .vta_regs = B53_VTA_REGS,
-+              .imp_port = 8,
-+              .duplex_reg = B53_DUPLEX_STAT_GE,
-+              .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-+              .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+      },
-+      {
-               .chip_id = BCM53115_DEVICE_ID,
-               .dev_name = "BCM53115",
-               .vlans = 4096,
-@@ -2986,6 +2999,7 @@ int b53_switch_detect(struct b53_device
-                       return ret;
-               switch (id32) {
-+              case BCM53101_DEVICE_ID:
-               case BCM53115_DEVICE_ID:
-               case BCM53125_DEVICE_ID:
-               case BCM53128_DEVICE_ID:
---- a/drivers/net/dsa/b53/b53_mdio.c
-+++ b/drivers/net/dsa/b53/b53_mdio.c
-@@ -374,6 +374,7 @@ static void b53_mdio_shutdown(struct mdi
- static const struct of_device_id b53_of_match[] = {
-       { .compatible = "brcm,bcm5325" },
-+      { .compatible = "brcm,bcm53101" },
-       { .compatible = "brcm,bcm53115" },
-       { .compatible = "brcm,bcm53125" },
-       { .compatible = "brcm,bcm53128" },
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -66,6 +66,7 @@ enum {
-       BCM5395_DEVICE_ID = 0x95,
-       BCM5397_DEVICE_ID = 0x97,
-       BCM5398_DEVICE_ID = 0x98,
-+      BCM53101_DEVICE_ID = 0x53101,
-       BCM53115_DEVICE_ID = 0x53115,
-       BCM53125_DEVICE_ID = 0x53125,
-       BCM53128_DEVICE_ID = 0x53128,
-@@ -190,6 +191,7 @@ static inline int is531x5(struct b53_dev
- {
-       return dev->chip_id == BCM53115_DEVICE_ID ||
-               dev->chip_id == BCM53125_DEVICE_ID ||
-+              dev->chip_id == BCM53101_DEVICE_ID ||
-               dev->chip_id == BCM53128_DEVICE_ID ||
-               dev->chip_id == BCM53134_DEVICE_ID;
- }
diff --git a/target/linux/generic/backport-6.18/610-03-v6.16-net-dsa-b53-implement-setting-ageing-time.patch b/target/linux/generic/backport-6.18/610-03-v6.16-net-dsa-b53-implement-setting-ageing-time.patch
deleted file mode 100644 (file)
index 196e70c..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-From e39d14a760c039af0653e3df967e7525413924a0 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Sat, 10 May 2025 11:22:11 +0200
-Subject: [PATCH] net: dsa: b53: implement setting ageing time
-
-b53 supported switches support configuring ageing time between 1 and
-1,048,575 seconds, so add an appropriate setter.
-
-This allows b53 to pass the FDB learning test for both vlan aware and
-vlan unaware bridges.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250510092211.276541-1-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 28 ++++++++++++++++++++++++++++
- drivers/net/dsa/b53/b53_priv.h   |  1 +
- drivers/net/dsa/b53/b53_regs.h   |  7 +++++++
- 3 files changed, 36 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -21,6 +21,7 @@
- #include <linux/export.h>
- #include <linux/gpio.h>
- #include <linux/kernel.h>
-+#include <linux/math.h>
- #include <linux/module.h>
- #include <linux/platform_data/b53.h>
- #include <linux/phy.h>
-@@ -1227,6 +1228,10 @@ static int b53_setup(struct dsa_switch *
-        */
-       ds->untag_vlan_aware_bridge_pvid = true;
-+      /* Ageing time is set in seconds */
-+      ds->ageing_time_min = 1 * 1000;
-+      ds->ageing_time_max = AGE_TIME_MAX * 1000;
-+
-       ret = b53_reset_switch(dev);
-       if (ret) {
-               dev_err(ds->dev, "failed to reset switch\n");
-@@ -2466,6 +2471,28 @@ static int b53_get_max_mtu(struct dsa_sw
-       return B53_MAX_MTU;
- }
-+int b53_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
-+{
-+      struct b53_device *dev = ds->priv;
-+      u32 atc;
-+      int reg;
-+
-+      if (is63xx(dev))
-+              reg = B53_AGING_TIME_CONTROL_63XX;
-+      else
-+              reg = B53_AGING_TIME_CONTROL;
-+
-+      atc = DIV_ROUND_CLOSEST(msecs, 1000);
-+
-+      if (!is5325(dev) && !is5365(dev))
-+              atc |= AGE_CHANGE;
-+
-+      b53_write32(dev, B53_MGMT_PAGE, reg, atc);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(b53_set_ageing_time);
-+
- static const struct phylink_mac_ops b53_phylink_mac_ops = {
-       .mac_select_pcs = b53_phylink_mac_select_pcs,
-       .mac_config     = b53_phylink_mac_config,
-@@ -2490,6 +2517,7 @@ static const struct dsa_switch_ops b53_s
-       .support_eee            = b53_support_eee,
-       .get_mac_eee            = b53_get_mac_eee,
-       .set_mac_eee            = b53_set_mac_eee,
-+      .set_ageing_time        = b53_set_ageing_time,
-       .port_bridge_join       = b53_br_join,
-       .port_bridge_leave      = b53_br_leave,
-       .port_pre_bridge_flags  = b53_br_flags_pre,
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -343,6 +343,7 @@ void b53_get_strings(struct dsa_switch *
- void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
- int b53_get_sset_count(struct dsa_switch *ds, int port, int sset);
- void b53_get_ethtool_phy_stats(struct dsa_switch *ds, int port, uint64_t *data);
-+int b53_set_ageing_time(struct dsa_switch *ds, unsigned int msecs);
- int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
-               bool *tx_fwd_offload, struct netlink_ext_ack *extack);
- void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -224,6 +224,13 @@
- #define   BRCM_HDR_P5_EN              BIT(1) /* Enable tagging on port 5 */
- #define   BRCM_HDR_P7_EN              BIT(2) /* Enable tagging on port 7 */
-+/* Aging Time control register (32 bit) */
-+#define B53_AGING_TIME_CONTROL                0x06
-+#define B53_AGING_TIME_CONTROL_63XX   0x08
-+#define  AGE_CHANGE                   BIT(20)
-+#define  AGE_TIME_MASK                        0x7ffff
-+#define  AGE_TIME_MAX                 1048575
-+
- /* Mirror capture control register (16 bit) */
- #define B53_MIR_CAP_CTL                       0x10
- #define  CAP_PORT_MASK                        0xf
diff --git a/target/linux/generic/backport-6.18/610-04-v6.16-net-dsa-b53-do-not-configure-bcm63xx-s-IMP-port-inte.patch b/target/linux/generic/backport-6.18/610-04-v6.16-net-dsa-b53-do-not-configure-bcm63xx-s-IMP-port-inte.patch
deleted file mode 100644 (file)
index e70f09e..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From 75f4f7b2b13008803f84768ff90396f9d7553221 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Mon, 2 Jun 2025 21:39:51 +0200
-Subject: [PATCH] net: dsa: b53: do not configure bcm63xx's IMP port interface
-
-The IMP port is not a valid RGMII interface, but hard wired to internal,
-so we shouldn't touch the undefined register B53_RGMII_CTRL_IMP.
-
-While this does not seem to have any side effects, let's not touch it at
-all, so limit RGMII configuration on bcm63xx to the actual RGMII ports.
-
-Fixes: ce3bf94871f7 ("net: dsa: b53: add support for BCM63xx RGMIIs")
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250602193953.1010487-4-jonas.gorski@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/b53/b53_common.c | 22 ++++++++--------------
- 1 file changed, 8 insertions(+), 14 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -22,6 +22,7 @@
- #include <linux/gpio.h>
- #include <linux/kernel.h>
- #include <linux/math.h>
-+#include <linux/minmax.h>
- #include <linux/module.h>
- #include <linux/platform_data/b53.h>
- #include <linux/phy.h>
-@@ -1369,24 +1370,17 @@ static void b53_adjust_63xx_rgmii(struct
-                                 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);
-+      u8 rgmii_ctrl = 0;
--      b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl);
-+      b53_read8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_P(port), &rgmii_ctrl);
-       rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
--      if (port != dev->imp_port) {
--              if (is63268(dev))
--                      rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE;
-+      if (is63268(dev))
-+              rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE;
--              rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
--      }
-+      rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
--      b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl);
-+      b53_write8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_P(port), rgmii_ctrl);
-       dev_dbg(ds->dev, "Configured port %d for %s\n", port,
-               phy_modes(interface));
-@@ -1537,7 +1531,7 @@ static void b53_phylink_mac_config(struc
-       struct b53_device *dev = ds->priv;
-       int port = dp->index;
--      if (is63xx(dev) && port >= B53_63XX_RGMII0)
-+      if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4))
-               b53_adjust_63xx_rgmii(ds, port, interface);
-       if (mode == MLO_AN_FIXED) {
diff --git a/target/linux/generic/backport-6.18/611-01-v6.17-net-dsa-tag_brcm-add-support-for-legacy-FCS-tags.patch b/target/linux/generic/backport-6.18/611-01-v6.17-net-dsa-tag_brcm-add-support-for-legacy-FCS-tags.patch
deleted file mode 100644 (file)
index 88f10be..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-From ef07df397a621707903ef0d294a7df11f80cf206 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 14 Jun 2025 09:59:48 +0200
-Subject: [PATCH] net: dsa: tag_brcm: add support for legacy FCS tags
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add support for legacy Broadcom FCS tags, which are similar to
-DSA_TAG_PROTO_BRCM_LEGACY.
-BCM5325 and BCM5365 switches require including the original FCS value and
-length, as opposed to BCM63xx switches.
-Adding the original FCS value and length to DSA_TAG_PROTO_BRCM_LEGACY would
-impact performance of BCM63xx switches, so it's better to create a new tag.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250614080000.1884236-3-noltari@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/net/dsa.h  |  2 ++
- net/dsa/Kconfig    | 16 ++++++++--
- net/dsa/tag_brcm.c | 73 +++++++++++++++++++++++++++++++++++++++++++++-
- 3 files changed, 88 insertions(+), 3 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -54,11 +54,13 @@ struct tc_action;
- #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE                26
- #define DSA_TAG_PROTO_LAN937X_VALUE           27
- #define DSA_TAG_PROTO_VSC73XX_8021Q_VALUE     28
-+#define DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE   29
- enum dsa_tag_protocol {
-       DSA_TAG_PROTO_NONE              = DSA_TAG_PROTO_NONE_VALUE,
-       DSA_TAG_PROTO_BRCM              = DSA_TAG_PROTO_BRCM_VALUE,
-       DSA_TAG_PROTO_BRCM_LEGACY       = DSA_TAG_PROTO_BRCM_LEGACY_VALUE,
-+      DSA_TAG_PROTO_BRCM_LEGACY_FCS   = DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE,
-       DSA_TAG_PROTO_BRCM_PREPEND      = DSA_TAG_PROTO_BRCM_PREPEND_VALUE,
-       DSA_TAG_PROTO_DSA               = DSA_TAG_PROTO_DSA_VALUE,
-       DSA_TAG_PROTO_EDSA              = DSA_TAG_PROTO_EDSA_VALUE,
---- a/net/dsa/Kconfig
-+++ b/net/dsa/Kconfig
-@@ -42,12 +42,24 @@ config NET_DSA_TAG_BRCM
-         Broadcom switches which place the tag after the MAC source address.
- config NET_DSA_TAG_BRCM_LEGACY
--      tristate "Tag driver for Broadcom legacy switches using in-frame headers"
-+      tristate "Tag driver for BCM63xx legacy switches using in-frame headers"
-       select NET_DSA_TAG_BRCM_COMMON
-       help
-         Say Y if you want to enable support for tagging frames for the
--        Broadcom legacy switches which place the tag after the MAC source
-+        BCM63xx legacy switches which place the tag after the MAC source
-         address.
-+        This tag is used in BCM63xx legacy switches which work without the
-+        original FCS and length before the tag insertion.
-+
-+config NET_DSA_TAG_BRCM_LEGACY_FCS
-+      tristate "Tag driver for BCM53xx legacy switches using in-frame headers"
-+      select NET_DSA_TAG_BRCM_COMMON
-+      help
-+        Say Y if you want to enable support for tagging frames for the
-+        BCM53xx legacy switches which place the tag after the MAC source
-+        address.
-+        This tag is used in BCM53xx legacy switches which expect original
-+        FCS and length before the tag insertion to be present.
- config NET_DSA_TAG_BRCM_PREPEND
-       tristate "Tag driver for Broadcom switches using prepended headers"
---- a/net/dsa/tag_brcm.c
-+++ b/net/dsa/tag_brcm.c
-@@ -15,6 +15,7 @@
- #define BRCM_NAME             "brcm"
- #define BRCM_LEGACY_NAME      "brcm-legacy"
-+#define BRCM_LEGACY_FCS_NAME  "brcm-legacy-fcs"
- #define BRCM_PREPEND_NAME     "brcm-prepend"
- /* Legacy Broadcom tag (6 bytes) */
-@@ -32,6 +33,10 @@
- #define BRCM_LEG_MULTICAST    (1 << 5)
- #define BRCM_LEG_EGRESS               (2 << 5)
- #define BRCM_LEG_INGRESS      (3 << 5)
-+#define BRCM_LEG_LEN_HI(x)    (((x) >> 8) & 0x7)
-+
-+/* 4th byte in the tag */
-+#define BRCM_LEG_LEN_LO(x)    ((x) & 0xff)
- /* 6th byte in the tag */
- #define BRCM_LEG_PORT_ID      (0xf)
-@@ -212,7 +217,8 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
- MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM, BRCM_NAME);
- #endif
--#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
-+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY) || \
-+      IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS)
- static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
-                                       struct net_device *dev)
- {
-@@ -250,7 +256,9 @@ static struct sk_buff *brcm_leg_tag_rcv(
-       return skb;
- }
-+#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY || CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS */
-+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
- static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
-                                        struct net_device *dev)
- {
-@@ -300,6 +308,66 @@ DSA_TAG_DRIVER(brcm_legacy_netdev_ops);
- MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY, BRCM_LEGACY_NAME);
- #endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */
-+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS)
-+static struct sk_buff *brcm_leg_fcs_tag_xmit(struct sk_buff *skb,
-+                                           struct net_device *dev)
-+{
-+      struct dsa_port *dp = dsa_user_to_port(dev);
-+      unsigned int fcs_len;
-+      __le32 fcs_val;
-+      u8 *brcm_tag;
-+
-+      /* The Ethernet switch we are interfaced with needs packets to be at
-+       * least 64 bytes (including FCS) otherwise they will be discarded when
-+       * they enter the switch port logic. When Broadcom tags are enabled, we
-+       * need to make sure that packets are at least 70 bytes (including FCS
-+       * and tag) because the length verification is done after the Broadcom
-+       * tag is stripped off the ingress packet.
-+       *
-+       * Let dsa_user_xmit() free the SKB.
-+       */
-+      if (__skb_put_padto(skb, ETH_ZLEN + BRCM_LEG_TAG_LEN, false))
-+              return NULL;
-+
-+      fcs_len = skb->len;
-+      fcs_val = cpu_to_le32(crc32_le(~0, skb->data, fcs_len) ^ ~0);
-+
-+      skb_push(skb, BRCM_LEG_TAG_LEN);
-+
-+      dsa_alloc_etype_header(skb, BRCM_LEG_TAG_LEN);
-+
-+      brcm_tag = skb->data + 2 * ETH_ALEN;
-+
-+      /* Broadcom tag type */
-+      brcm_tag[0] = BRCM_LEG_TYPE_HI;
-+      brcm_tag[1] = BRCM_LEG_TYPE_LO;
-+
-+      /* Broadcom tag value */
-+      brcm_tag[2] = BRCM_LEG_EGRESS | BRCM_LEG_LEN_HI(fcs_len);
-+      brcm_tag[3] = BRCM_LEG_LEN_LO(fcs_len);
-+      brcm_tag[4] = 0;
-+      brcm_tag[5] = dp->index & BRCM_LEG_PORT_ID;
-+
-+      /* Original FCS value */
-+      if (__skb_pad(skb, ETH_FCS_LEN, false))
-+              return NULL;
-+      skb_put_data(skb, &fcs_val, ETH_FCS_LEN);
-+
-+      return skb;
-+}
-+
-+static const struct dsa_device_ops brcm_legacy_fcs_netdev_ops = {
-+      .name = BRCM_LEGACY_FCS_NAME,
-+      .proto = DSA_TAG_PROTO_BRCM_LEGACY_FCS,
-+      .xmit = brcm_leg_fcs_tag_xmit,
-+      .rcv = brcm_leg_tag_rcv,
-+      .needed_headroom = BRCM_LEG_TAG_LEN,
-+};
-+
-+DSA_TAG_DRIVER(brcm_legacy_fcs_netdev_ops);
-+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY_FCS, BRCM_LEGACY_FCS_NAME);
-+#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS */
-+
- #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
- static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb,
-                                            struct net_device *dev)
-@@ -334,6 +402,9 @@ static struct dsa_tag_driver *dsa_tag_dr
- #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
-       &DSA_TAG_DRIVER_NAME(brcm_legacy_netdev_ops),
- #endif
-+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS)
-+      &DSA_TAG_DRIVER_NAME(brcm_legacy_fcs_netdev_ops),
-+#endif
- #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
-       &DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops),
- #endif
diff --git a/target/linux/generic/backport-6.18/611-02-v6.17-net-dsa-b53-support-legacy-FCS-tags.patch b/target/linux/generic/backport-6.18/611-02-v6.17-net-dsa-b53-support-legacy-FCS-tags.patch
deleted file mode 100644 (file)
index b04c8ea..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From c3cf059a4d419b9c888ce7e9952fa13ba7569b61 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 14 Jun 2025 09:59:49 +0200
-Subject: [PATCH] net: dsa: b53: support legacy FCS tags
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Commit 46c5176c586c ("net: dsa: b53: support legacy tags") introduced
-support for legacy tags, but it turns out that BCM5325 and BCM5365
-switches require the original FCS value and length, so they have to be
-treated differently.
-
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Link: https://patch.msgid.link/20250614080000.1884236-4-noltari@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/Kconfig      | 1 +
- drivers/net/dsa/b53/b53_common.c | 7 +++++--
- 2 files changed, 6 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/b53/Kconfig
-+++ b/drivers/net/dsa/b53/Kconfig
-@@ -5,6 +5,7 @@ menuconfig B53
-       select NET_DSA_TAG_NONE
-       select NET_DSA_TAG_BRCM
-       select NET_DSA_TAG_BRCM_LEGACY
-+      select NET_DSA_TAG_BRCM_LEGACY_FCS
-       select NET_DSA_TAG_BRCM_PREPEND
-       help
-         This driver adds support for Broadcom managed switch chips. It supports
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2307,8 +2307,11 @@ enum dsa_tag_protocol b53_get_tag_protoc
-               goto out;
-       }
--      /* Older models require a different 6 byte tag */
--      if (is5325(dev) || is5365(dev) || is63xx(dev)) {
-+      /* Older models require different 6 byte tags */
-+      if (is5325(dev) || is5365(dev)) {
-+              dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY_FCS;
-+              goto out;
-+      } else if (is63xx(dev)) {
-               dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY;
-               goto out;
-       }
diff --git a/target/linux/generic/backport-6.18/611-03-v6.17-net-dsa-b53-detect-BCM5325-variants.patch b/target/linux/generic/backport-6.18/611-03-v6.17-net-dsa-b53-detect-BCM5325-variants.patch
deleted file mode 100644 (file)
index 3c2fa2d..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-From 0cbec9aef5a86194117a956546dc1aec95031f37 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 14 Jun 2025 09:59:50 +0200
-Subject: [PATCH] net: dsa: b53: detect BCM5325 variants
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-We need to be able to differentiate the BCM5325 variants because:
-- BCM5325M switches lack the ARLIO_PAGE->VLAN_ID_IDX register.
-- BCM5325E have less 512 ARL buckets instead of 1024.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250614080000.1884236-5-noltari@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 24 +++++++++++++++++++++---
- drivers/net/dsa/b53/b53_priv.h   | 19 +++++++++++++++++++
- 2 files changed, 40 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1835,7 +1835,8 @@ static int b53_arl_op(struct b53_device
-       /* Perform a read for the given MAC and VID */
-       b53_write48(dev, B53_ARLIO_PAGE, B53_MAC_ADDR_IDX, mac);
--      b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
-+      if (!is5325m(dev))
-+              b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
-       /* Issue a read operation for this MAC */
-       ret = b53_arl_rw_op(dev, 1);
-@@ -2906,6 +2907,9 @@ static int b53_switch_init(struct b53_de
-               }
-       }
-+      if (is5325e(dev))
-+              dev->num_arl_buckets = 512;
-+
-       dev->num_ports = fls(dev->enabled_ports);
-       dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS);
-@@ -3007,10 +3011,24 @@ int b53_switch_detect(struct b53_device
-               b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, 0xf);
-               b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, &tmp);
--              if (tmp == 0xf)
-+              if (tmp == 0xf) {
-+                      u32 phy_id;
-+                      int val;
-+
-                       dev->chip_id = BCM5325_DEVICE_ID;
--              else
-+
-+                      val = b53_phy_read16(dev->ds, 0, MII_PHYSID1);
-+                      phy_id = (val & 0xffff) << 16;
-+                      val = b53_phy_read16(dev->ds, 0, MII_PHYSID2);
-+                      phy_id |= (val & 0xfff0);
-+
-+                      if (phy_id == 0x00406330)
-+                              dev->variant_id = B53_VARIANT_5325M;
-+                      else if (phy_id == 0x0143bc30)
-+                              dev->variant_id = B53_VARIANT_5325E;
-+              } else {
-                       dev->chip_id = BCM5365_DEVICE_ID;
-+              }
-               break;
-       case BCM5389_DEVICE_ID:
-       case BCM5395_DEVICE_ID:
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -84,6 +84,12 @@ enum {
-       BCM53134_DEVICE_ID = 0x5075,
- };
-+enum b53_variant_id {
-+      B53_VARIANT_NONE = 0,
-+      B53_VARIANT_5325E,
-+      B53_VARIANT_5325M,
-+};
-+
- struct b53_pcs {
-       struct phylink_pcs pcs;
-       struct b53_device *dev;
-@@ -118,6 +124,7 @@ struct b53_device {
-       /* chip specific data */
-       u32 chip_id;
-+      enum b53_variant_id variant_id;
-       u8 core_rev;
-       u8 vta_regs[3];
-       u8 duplex_reg;
-@@ -165,6 +172,18 @@ static inline int is5325(struct b53_devi
-       return dev->chip_id == BCM5325_DEVICE_ID;
- }
-+static inline int is5325e(struct b53_device *dev)
-+{
-+      return is5325(dev) &&
-+              dev->variant_id == B53_VARIANT_5325E;
-+}
-+
-+static inline int is5325m(struct b53_device *dev)
-+{
-+      return is5325(dev) &&
-+              dev->variant_id == B53_VARIANT_5325M;
-+}
-+
- static inline int is5365(struct b53_device *dev)
- {
- #ifdef CONFIG_BCM47XX
diff --git a/target/linux/generic/backport-6.18/611-04-v6.17-net-dsa-b53-add-support-for-FDB-operations-on-5325-5365.patch b/target/linux/generic/backport-6.18/611-04-v6.17-net-dsa-b53-add-support-for-FDB-operations-on-5325-5365.patch
deleted file mode 100644 (file)
index 9de7381..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-From c45655386e532c85ff1d679fc2aa40b3aaff9916 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Sat, 14 Jun 2025 09:59:51 +0200
-Subject: [PATCH] net: dsa: b53: add support for FDB operations on 5325/5365
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM5325 and BCM5365 are part of a much older generation of switches which,
-due to their limited number of ports and VLAN entries (up to 256) allowed
-a single 64-bit register to hold a full ARL entry.
-This requires a little bit of massaging when reading, writing and
-converting ARL entries in both directions.
-
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Link: https://patch.msgid.link/20250614080000.1884236-6-noltari@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 101 +++++++++++++++++++++++++------
- drivers/net/dsa/b53/b53_priv.h   |  29 +++++++++
- drivers/net/dsa/b53/b53_regs.h   |   7 ++-
- 3 files changed, 115 insertions(+), 22 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1821,6 +1821,45 @@ static int b53_arl_read(struct b53_devic
-       return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT;
- }
-+static int b53_arl_read_25(struct b53_device *dev, u64 mac,
-+                         u16 vid, struct b53_arl_entry *ent, u8 *idx)
-+{
-+      DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
-+      unsigned int i;
-+      int ret;
-+
-+      ret = b53_arl_op_wait(dev);
-+      if (ret)
-+              return ret;
-+
-+      bitmap_zero(free_bins, dev->num_arl_bins);
-+
-+      /* Read the bins */
-+      for (i = 0; i < dev->num_arl_bins; i++) {
-+              u64 mac_vid;
-+
-+              b53_read64(dev, B53_ARLIO_PAGE,
-+                         B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid);
-+
-+              b53_arl_to_entry_25(ent, mac_vid);
-+
-+              if (!(mac_vid & ARLTBL_VALID_25)) {
-+                      set_bit(i, free_bins);
-+                      continue;
-+              }
-+              if ((mac_vid & ARLTBL_MAC_MASK) != mac)
-+                      continue;
-+              if (dev->vlan_enabled &&
-+                  ((mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25) != vid)
-+                      continue;
-+              *idx = i;
-+              return 0;
-+      }
-+
-+      *idx = find_first_bit(free_bins, dev->num_arl_bins);
-+      return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT;
-+}
-+
- static int b53_arl_op(struct b53_device *dev, int op, int port,
-                     const unsigned char *addr, u16 vid, bool is_valid)
- {
-@@ -1843,7 +1882,10 @@ static int b53_arl_op(struct b53_device
-       if (ret)
-               return ret;
--      ret = b53_arl_read(dev, mac, vid, &ent, &idx);
-+      if (is5325(dev) || is5365(dev))
-+              ret = b53_arl_read_25(dev, mac, vid, &ent, &idx);
-+      else
-+              ret = b53_arl_read(dev, mac, vid, &ent, &idx);
-       /* If this is a read, just finish now */
-       if (op)
-@@ -1887,12 +1929,17 @@ static int b53_arl_op(struct b53_device
-       ent.is_static = true;
-       ent.is_age = false;
-       memcpy(ent.mac, addr, ETH_ALEN);
--      b53_arl_from_entry(&mac_vid, &fwd_entry, &ent);
-+      if (is5325(dev) || is5365(dev))
-+              b53_arl_from_entry_25(&mac_vid, &ent);
-+      else
-+              b53_arl_from_entry(&mac_vid, &fwd_entry, &ent);
-       b53_write64(dev, B53_ARLIO_PAGE,
-                   B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid);
--      b53_write32(dev, B53_ARLIO_PAGE,
--                  B53_ARLTBL_DATA_ENTRY(idx), fwd_entry);
-+
-+      if (!is5325(dev) && !is5365(dev))
-+              b53_write32(dev, B53_ARLIO_PAGE,
-+                          B53_ARLTBL_DATA_ENTRY(idx), fwd_entry);
-       return b53_arl_rw_op(dev, 0);
- }
-@@ -1904,12 +1951,6 @@ int b53_fdb_add(struct dsa_switch *ds, i
-       struct b53_device *priv = ds->priv;
-       int ret;
--      /* 5325 and 5365 require some more massaging, but could
--       * be supported eventually
--       */
--      if (is5325(priv) || is5365(priv))
--              return -EOPNOTSUPP;
--
-       mutex_lock(&priv->arl_mutex);
-       ret = b53_arl_op(priv, 0, port, addr, vid, true);
-       mutex_unlock(&priv->arl_mutex);
-@@ -1936,10 +1977,15 @@ EXPORT_SYMBOL(b53_fdb_del);
- static int b53_arl_search_wait(struct b53_device *dev)
- {
-       unsigned int timeout = 1000;
--      u8 reg;
-+      u8 reg, offset;
-+
-+      if (is5325(dev) || is5365(dev))
-+              offset = B53_ARL_SRCH_CTL_25;
-+      else
-+              offset = B53_ARL_SRCH_CTL;
-       do {
--              b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, &reg);
-+              b53_read8(dev, B53_ARLIO_PAGE, offset, &reg);
-               if (!(reg & ARL_SRCH_STDN))
-                       return -ENOENT;
-@@ -1956,13 +2002,24 @@ static void b53_arl_search_rd(struct b53
-                             struct b53_arl_entry *ent)
- {
-       u64 mac_vid;
--      u32 fwd_entry;
--      b53_read64(dev, B53_ARLIO_PAGE,
--                 B53_ARL_SRCH_RSTL_MACVID(idx), &mac_vid);
--      b53_read32(dev, B53_ARLIO_PAGE,
--                 B53_ARL_SRCH_RSTL(idx), &fwd_entry);
--      b53_arl_to_entry(ent, mac_vid, fwd_entry);
-+      if (is5325(dev)) {
-+              b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
-+                         &mac_vid);
-+              b53_arl_to_entry_25(ent, mac_vid);
-+      } else if (is5365(dev)) {
-+              b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65,
-+                         &mac_vid);
-+              b53_arl_to_entry_25(ent, mac_vid);
-+      } else {
-+              u32 fwd_entry;
-+
-+              b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx),
-+                         &mac_vid);
-+              b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx),
-+                         &fwd_entry);
-+              b53_arl_to_entry(ent, mac_vid, fwd_entry);
-+      }
- }
- static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
-@@ -1986,14 +2043,20 @@ int b53_fdb_dump(struct dsa_switch *ds,
-       struct b53_device *priv = ds->priv;
-       struct b53_arl_entry results[2];
-       unsigned int count = 0;
-+      u8 offset;
-       int ret;
-       u8 reg;
-       mutex_lock(&priv->arl_mutex);
-+      if (is5325(priv) || is5365(priv))
-+              offset = B53_ARL_SRCH_CTL_25;
-+      else
-+              offset = B53_ARL_SRCH_CTL;
-+
-       /* Start search operation */
-       reg = ARL_SRCH_STDN;
--      b53_write8(priv, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, reg);
-+      b53_write8(priv, offset, B53_ARL_SRCH_CTL, reg);
-       do {
-               ret = b53_arl_search_wait(priv);
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -317,6 +317,19 @@ static inline void b53_arl_to_entry(stru
-       ent->vid = mac_vid >> ARLTBL_VID_S;
- }
-+static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent,
-+                                     u64 mac_vid)
-+{
-+      memset(ent, 0, sizeof(*ent));
-+      ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) &
-+                   ARLTBL_DATA_PORT_ID_MASK_25;
-+      ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
-+      ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
-+      ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
-+      u64_to_ether_addr(mac_vid, ent->mac);
-+      ent->vid = mac_vid >> ARLTBL_VID_S_65;
-+}
-+
- static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry,
-                                     const struct b53_arl_entry *ent)
- {
-@@ -331,6 +344,22 @@ static inline void b53_arl_from_entry(u6
-               *fwd_entry |= ARLTBL_AGE;
- }
-+static inline void b53_arl_from_entry_25(u64 *mac_vid,
-+                                       const struct b53_arl_entry *ent)
-+{
-+      *mac_vid = ether_addr_to_u64(ent->mac);
-+      *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) <<
-+                        ARLTBL_DATA_PORT_ID_S_25;
-+      *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) <<
-+                        ARLTBL_VID_S_65;
-+      if (ent->is_valid)
-+              *mac_vid |= ARLTBL_VALID_25;
-+      if (ent->is_static)
-+              *mac_vid |= ARLTBL_STATIC_25;
-+      if (ent->is_age)
-+              *mac_vid |= ARLTBL_AGE_25;
-+}
-+
- #ifdef CONFIG_BCM47XX
- #include <linux/bcm47xx_nvram.h>
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -328,9 +328,10 @@
- #define   ARLTBL_VID_MASK             0xfff
- #define   ARLTBL_DATA_PORT_ID_S_25    48
- #define   ARLTBL_DATA_PORT_ID_MASK_25 0xf
--#define   ARLTBL_AGE_25                       BIT(61)
--#define   ARLTBL_STATIC_25            BIT(62)
--#define   ARLTBL_VALID_25             BIT(63)
-+#define   ARLTBL_VID_S_65             53
-+#define   ARLTBL_AGE_25                       BIT_ULL(61)
-+#define   ARLTBL_STATIC_25            BIT_ULL(62)
-+#define   ARLTBL_VALID_25             BIT_ULL(63)
- /* ARL Table Data Entry N Registers (32 bit) */
- #define B53_ARLTBL_DATA_ENTRY(n)      ((0x10 * (n)) + 0x18)
diff --git a/target/linux/generic/backport-6.18/611-05-v6.17-net-dsa-b53-prevent-FAST_AGE-access-on-BCM5325.patch b/target/linux/generic/backport-6.18/611-05-v6.17-net-dsa-b53-prevent-FAST_AGE-access-on-BCM5325.patch
deleted file mode 100644 (file)
index 7397e33..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From 9b6c767c312b4709e9aeb2314a6b47863e7fb72d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 14 Jun 2025 09:59:52 +0200
-Subject: [PATCH] net: dsa: b53: prevent FAST_AGE access on BCM5325
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM5325 doesn't implement FAST_AGE registers so we should avoid reading or
-writing them.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250614080000.1884236-7-noltari@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -492,6 +492,9 @@ static int b53_flush_arl(struct b53_devi
- {
-       unsigned int i;
-+      if (is5325(dev))
-+              return 0;
-+
-       b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL,
-                  FAST_AGE_DONE | FAST_AGE_DYNAMIC | mask);
-@@ -516,6 +519,9 @@ out:
- static int b53_fast_age_port(struct b53_device *dev, int port)
- {
-+      if (is5325(dev))
-+              return 0;
-+
-       b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_PORT_CTRL, port);
-       return b53_flush_arl(dev, FAST_AGE_PORT);
-@@ -523,6 +529,9 @@ static int b53_fast_age_port(struct b53_
- static int b53_fast_age_vlan(struct b53_device *dev, u16 vid)
- {
-+      if (is5325(dev))
-+              return 0;
-+
-       b53_write16(dev, B53_CTRL_PAGE, B53_FAST_AGE_VID_CTRL, vid);
-       return b53_flush_arl(dev, FAST_AGE_VLAN);
diff --git a/target/linux/generic/backport-6.18/611-06-v6.17-net-dsa-b53-prevent-BRCM_HDR-access-on-older-devices.patch b/target/linux/generic/backport-6.18/611-06-v6.17-net-dsa-b53-prevent-BRCM_HDR-access-on-older-devices.patch
deleted file mode 100644 (file)
index 6ea8367..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From e17813968b08b1b09bf80699223dea48851cbd07 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 14 Jun 2025 09:59:56 +0200
-Subject: [PATCH] net: dsa: b53: prevent BRCM_HDR access on older devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Older switches don't implement BRCM_HDR register so we should avoid
-reading or writing it.
-
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Link: https://patch.msgid.link/20250614080000.1884236-11-noltari@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -747,6 +747,11 @@ void b53_brcm_hdr_setup(struct dsa_switc
-               hdr_ctl |= GC_FRM_MGMT_PORT_M;
-       b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl);
-+      /* B53_BRCM_HDR not present on devices with legacy tags */
-+      if (dev->tag_protocol == DSA_TAG_PROTO_BRCM_LEGACY ||
-+          dev->tag_protocol == DSA_TAG_PROTO_BRCM_LEGACY_FCS)
-+              return;
-+
-       /* Enable Broadcom tags for IMP port */
-       b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl);
-       if (tag_en)
diff --git a/target/linux/generic/backport-6.18/611-07-v6.17-net-dsa-b53-fix-unicast-multicast-flooding-on-BCM5325.patch b/target/linux/generic/backport-6.18/611-07-v6.17-net-dsa-b53-fix-unicast-multicast-flooding-on-BCM5325.patch
deleted file mode 100644 (file)
index 6b9c86e..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-From 651c9e71ffe44e99b5a9b011271c2117f0353b32 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Sat, 14 Jun 2025 09:59:58 +0200
-Subject: [PATCH] net: dsa: b53: fix unicast/multicast flooding on BCM5325
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK
-registers.
-This has to be handled differently with other pages and registers.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250614080000.1884236-13-noltari@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 60 ++++++++++++++++++++++----------
- drivers/net/dsa/b53/b53_regs.h   | 13 +++++++
- 2 files changed, 55 insertions(+), 18 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -564,12 +564,24 @@ static void b53_port_set_ucast_flood(str
- {
-       u16 uc;
--      b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc);
--      if (unicast)
--              uc |= BIT(port);
--      else
--              uc &= ~BIT(port);
--      b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc);
-+      if (is5325(dev)) {
-+              if (port == B53_CPU_PORT_25)
-+                      port = B53_CPU_PORT;
-+
-+              b53_read16(dev, B53_IEEE_PAGE, B53_IEEE_UCAST_DLF, &uc);
-+              if (unicast)
-+                      uc |= BIT(port) | B53_IEEE_UCAST_DROP_EN;
-+              else
-+                      uc &= ~BIT(port);
-+              b53_write16(dev, B53_IEEE_PAGE, B53_IEEE_UCAST_DLF, uc);
-+      } else {
-+              b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc);
-+              if (unicast)
-+                      uc |= BIT(port);
-+              else
-+                      uc &= ~BIT(port);
-+              b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc);
-+      }
- }
- static void b53_port_set_mcast_flood(struct b53_device *dev, int port,
-@@ -577,19 +589,31 @@ static void b53_port_set_mcast_flood(str
- {
-       u16 mc;
--      b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc);
--      if (multicast)
--              mc |= BIT(port);
--      else
--              mc &= ~BIT(port);
--      b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc);
--
--      b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc);
--      if (multicast)
--              mc |= BIT(port);
--      else
--              mc &= ~BIT(port);
--      b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc);
-+      if (is5325(dev)) {
-+              if (port == B53_CPU_PORT_25)
-+                      port = B53_CPU_PORT;
-+
-+              b53_read16(dev, B53_IEEE_PAGE, B53_IEEE_MCAST_DLF, &mc);
-+              if (multicast)
-+                      mc |= BIT(port) | B53_IEEE_MCAST_DROP_EN;
-+              else
-+                      mc &= ~BIT(port);
-+              b53_write16(dev, B53_IEEE_PAGE, B53_IEEE_MCAST_DLF, mc);
-+      } else {
-+              b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc);
-+              if (multicast)
-+                      mc |= BIT(port);
-+              else
-+                      mc &= ~BIT(port);
-+              b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc);
-+
-+              b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc);
-+              if (multicast)
-+                      mc |= BIT(port);
-+              else
-+                      mc &= ~BIT(port);
-+              b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc);
-+      }
- }
- static void b53_port_set_learning(struct b53_device *dev, int port,
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -29,6 +29,7 @@
- #define B53_ARLIO_PAGE                        0x05 /* ARL Access */
- #define B53_FRAMEBUF_PAGE             0x06 /* Management frame access */
- #define B53_MEM_ACCESS_PAGE           0x08 /* Memory access */
-+#define B53_IEEE_PAGE                 0x0a /* IEEE 802.1X */
- /* PHY Registers */
- #define B53_PORT_MII_PAGE(i)          (0x10 + (i)) /* Port i MII Registers */
-@@ -371,6 +372,18 @@
- #define B53_ARL_SRCH_RSTL(x)          (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10))
- /*************************************************************************
-+ * IEEE 802.1X Registers
-+ *************************************************************************/
-+
-+/* Multicast DLF Drop Control register (16 bit) */
-+#define B53_IEEE_MCAST_DLF            0x94
-+#define B53_IEEE_MCAST_DROP_EN                BIT(11)
-+
-+/* Unicast DLF Drop Control register (16 bit) */
-+#define B53_IEEE_UCAST_DLF            0x96
-+#define B53_IEEE_UCAST_DROP_EN                BIT(11)
-+
-+/*************************************************************************
-  * Port VLAN Registers
-  *************************************************************************/
diff --git a/target/linux/generic/backport-6.18/611-08-v6.18-net-dsa-b53-Add-phy_enable-phy_disable-methods.patch b/target/linux/generic/backport-6.18/611-08-v6.18-net-dsa-b53-Add-phy_enable-phy_disable-methods.patch
deleted file mode 100644 (file)
index 14106e3..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-From be7a79145d85af1a9d65a45560b9243b13a67782 Mon Sep 17 00:00:00 2001
-From: Kyle Hendry <kylehendrydev@gmail.com>
-Date: Wed, 23 Jul 2025 20:52:40 -0700
-Subject: [PATCH] net: dsa: b53: Add phy_enable(), phy_disable() methods
-
-Add phy enable/disable to b53 ops to be called when
-enabling/disabling ports.
-
-Signed-off-by: Kyle Hendry <kylehendrydev@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250724035300.20497-2-kylehendrydev@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 6 ++++++
- drivers/net/dsa/b53/b53_priv.h   | 2 ++
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -689,6 +689,9 @@ int b53_enable_port(struct dsa_switch *d
-       cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+      if (dev->ops->phy_enable)
-+              dev->ops->phy_enable(dev, port);
-+
-       if (dev->ops->irq_enable)
-               ret = dev->ops->irq_enable(dev, port);
-       if (ret)
-@@ -727,6 +730,9 @@ void b53_disable_port(struct dsa_switch
-       reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE;
-       b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg);
-+      if (dev->ops->phy_disable)
-+              dev->ops->phy_disable(dev, port);
-+
-       if (dev->ops->irq_disable)
-               dev->ops->irq_disable(dev, port);
- }
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -45,6 +45,8 @@ struct b53_io_ops {
-       int (*phy_write16)(struct b53_device *dev, int addr, int reg, u16 value);
-       int (*irq_enable)(struct b53_device *dev, int port);
-       void (*irq_disable)(struct b53_device *dev, int port);
-+      void (*phy_enable)(struct b53_device *dev, int port);
-+      void (*phy_disable)(struct b53_device *dev, int port);
-       void (*phylink_get_caps)(struct b53_device *dev, int port,
-                                struct phylink_config *config);
-       struct phylink_pcs *(*phylink_mac_select_pcs)(struct b53_device *dev,
diff --git a/target/linux/generic/backport-6.18/611-09-v6.18-net-dsa-b53-Define-chip-IDs-for-more-bcm63xx-SoCs.patch b/target/linux/generic/backport-6.18/611-09-v6.18-net-dsa-b53-Define-chip-IDs-for-more-bcm63xx-SoCs.patch
deleted file mode 100644 (file)
index 0e03916..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-From fcf02a462fab52fbfcb24e617dd940745afd0dff Mon Sep 17 00:00:00 2001
-From: Kyle Hendry <kylehendrydev@gmail.com>
-Date: Wed, 23 Jul 2025 20:52:42 -0700
-Subject: [PATCH] net: dsa: b53: Define chip IDs for more bcm63xx SoCs
-
-Add defines for bcm6318, bcm6328, bcm6362, bcm6368 chip IDs,
-update tables and switch init.
-
-Signed-off-by: Kyle Hendry <kylehendrydev@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250724035300.20497-4-kylehendrydev@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 21 ++++++---------------
- drivers/net/dsa/b53/b53_mmap.c   |  8 ++++----
- drivers/net/dsa/b53/b53_priv.h   | 13 +++++++++++--
- 3 files changed, 21 insertions(+), 21 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1419,7 +1419,7 @@ static void b53_adjust_63xx_rgmii(struct
-       b53_read8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_P(port), &rgmii_ctrl);
-       rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
--      if (is63268(dev))
-+      if (is6318_268(dev))
-               rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE;
-       rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
-@@ -2804,19 +2804,6 @@ 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,
-@@ -2965,13 +2952,17 @@ static const struct b53_chip_data b53_sw
- static int b53_switch_init(struct b53_device *dev)
- {
-+      u32 chip_id = dev->chip_id;
-       unsigned int i;
-       int ret;
-+      if (is63xx(dev))
-+              chip_id = BCM63XX_DEVICE_ID;
-+
-       for (i = 0; i < ARRAY_SIZE(b53_switch_chips); i++) {
-               const struct b53_chip_data *chip = &b53_switch_chips[i];
--              if (chip->chip_id == dev->chip_id) {
-+              if (chip->chip_id == chip_id) {
-                       if (!dev->enabled_ports)
-                               dev->enabled_ports = chip->enabled_ports;
-                       dev->name = chip->dev_name;
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -348,16 +348,16 @@ static const struct of_device_id b53_mma
-               .data = (void *)BCM63XX_DEVICE_ID,
-       }, {
-               .compatible = "brcm,bcm6318-switch",
--              .data = (void *)BCM63268_DEVICE_ID,
-+              .data = (void *)BCM6318_DEVICE_ID,
-       }, {
-               .compatible = "brcm,bcm6328-switch",
--              .data = (void *)BCM63XX_DEVICE_ID,
-+              .data = (void *)BCM6328_DEVICE_ID,
-       }, {
-               .compatible = "brcm,bcm6362-switch",
--              .data = (void *)BCM63XX_DEVICE_ID,
-+              .data = (void *)BCM6362_DEVICE_ID,
-       }, {
-               .compatible = "brcm,bcm6368-switch",
--              .data = (void *)BCM63XX_DEVICE_ID,
-+              .data = (void *)BCM6368_DEVICE_ID,
-       }, {
-               .compatible = "brcm,bcm63268-switch",
-               .data = (void *)BCM63268_DEVICE_ID,
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -73,6 +73,10 @@ enum {
-       BCM53125_DEVICE_ID = 0x53125,
-       BCM53128_DEVICE_ID = 0x53128,
-       BCM63XX_DEVICE_ID = 0x6300,
-+      BCM6318_DEVICE_ID = 0x6318,
-+      BCM6328_DEVICE_ID = 0x6328,
-+      BCM6362_DEVICE_ID = 0x6362,
-+      BCM6368_DEVICE_ID = 0x6368,
-       BCM63268_DEVICE_ID = 0x63268,
-       BCM53010_DEVICE_ID = 0x53010,
-       BCM53011_DEVICE_ID = 0x53011,
-@@ -220,12 +224,17 @@ static inline int is531x5(struct b53_dev
- static inline int is63xx(struct b53_device *dev)
- {
-       return dev->chip_id == BCM63XX_DEVICE_ID ||
-+              dev->chip_id == BCM6318_DEVICE_ID ||
-+              dev->chip_id == BCM6328_DEVICE_ID ||
-+              dev->chip_id == BCM6362_DEVICE_ID ||
-+              dev->chip_id == BCM6368_DEVICE_ID ||
-               dev->chip_id == BCM63268_DEVICE_ID;
- }
--static inline int is63268(struct b53_device *dev)
-+static inline int is6318_268(struct b53_device *dev)
- {
--      return dev->chip_id == BCM63268_DEVICE_ID;
-+      return dev->chip_id == BCM6318_DEVICE_ID ||
-+              dev->chip_id == BCM63268_DEVICE_ID;
- }
- static inline int is5301x(struct b53_device *dev)
diff --git a/target/linux/generic/backport-6.18/611-10-v6.18-net-dsa-b53-mmap-Add-syscon-reference-and-register-layout-for-bcm63268.patch b/target/linux/generic/backport-6.18/611-10-v6.18-net-dsa-b53-mmap-Add-syscon-reference-and-register-layout-for-bcm63268.patch
deleted file mode 100644 (file)
index 92e540d..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-From aed2aaa3c963f8aabbfa061a177022fee826ebfb Mon Sep 17 00:00:00 2001
-From: Kyle Hendry <kylehendrydev@gmail.com>
-Date: Wed, 23 Jul 2025 20:52:43 -0700
-Subject: [PATCH] net: dsa: b53: mmap: Add syscon reference and register layout
- for bcm63268
-
-On bcm63xx SoCs there are registers that control the PHYs in
-the GPIO controller. Allow the b53 driver to access them
-by passing in the syscon through the device tree.
-
-Add a structure to describe the ephy control register
-and add register info for bcm63268.
-
-Signed-off-by: Kyle Hendry <kylehendrydev@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250724035300.20497-5-kylehendrydev@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_mmap.c | 25 +++++++++++++++++++++++++
- 1 file changed, 25 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -21,13 +21,32 @@
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/io.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/platform_device.h>
- #include <linux/platform_data/b53.h>
- #include "b53_priv.h"
-+struct b53_phy_info {
-+      u32 ephy_enable_mask;
-+      u32 ephy_port_mask;
-+      u32 ephy_bias_bit;
-+      const u32 *ephy_offset;
-+};
-+
- struct b53_mmap_priv {
-       void __iomem *regs;
-+      struct regmap *gpio_ctrl;
-+      const struct b53_phy_info *phy_info;
-+};
-+
-+static const u32 bcm63268_ephy_offsets[] = {4, 9, 14};
-+
-+static const struct b53_phy_info bcm63268_ephy_info = {
-+      .ephy_enable_mask = GENMASK(4, 0),
-+      .ephy_port_mask = GENMASK((ARRAY_SIZE(bcm63268_ephy_offsets) - 1), 0),
-+      .ephy_bias_bit = 24,
-+      .ephy_offset = bcm63268_ephy_offsets,
- };
- static int b53_mmap_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val)
-@@ -313,6 +332,12 @@ static int b53_mmap_probe(struct platfor
-       priv->regs = pdata->regs;
-+      priv->gpio_ctrl = syscon_regmap_lookup_by_phandle(np, "brcm,gpio-ctrl");
-+      if (!IS_ERR(priv->gpio_ctrl)) {
-+              if (pdata->chip_id == BCM63268_DEVICE_ID)
-+                      priv->phy_info = &bcm63268_ephy_info;
-+      }
-+
-       dev = b53_switch_alloc(&pdev->dev, &b53_mmap_ops, priv);
-       if (!dev)
-               return -ENOMEM;
diff --git a/target/linux/generic/backport-6.18/611-11-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6318.patch b/target/linux/generic/backport-6.18/611-11-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6318.patch
deleted file mode 100644 (file)
index f6c1cba..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From c251304ab021ff21c77e83e0babcb9eb76f8787a Mon Sep 17 00:00:00 2001
-From: Kyle Hendry <kylehendrydev@gmail.com>
-Date: Wed, 23 Jul 2025 20:52:44 -0700
-Subject: [PATCH] net: dsa: b53: mmap: Add register layout for bcm6318
-
-Add ephy register info for bcm6318, which also applies to
-bcm6328 and bcm6362.
-
-Signed-off-by: Kyle Hendry <kylehendrydev@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250724035300.20497-6-kylehendrydev@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_mmap.c | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -40,6 +40,15 @@ struct b53_mmap_priv {
-       const struct b53_phy_info *phy_info;
- };
-+static const u32 bcm6318_ephy_offsets[] = {4, 5, 6, 7};
-+
-+static const struct b53_phy_info bcm6318_ephy_info = {
-+      .ephy_enable_mask = BIT(0) | BIT(4) | BIT(8) | BIT(12) | BIT(16),
-+      .ephy_port_mask = GENMASK((ARRAY_SIZE(bcm6318_ephy_offsets) - 1), 0),
-+      .ephy_bias_bit = 24,
-+      .ephy_offset = bcm6318_ephy_offsets,
-+};
-+
- static const u32 bcm63268_ephy_offsets[] = {4, 9, 14};
- static const struct b53_phy_info bcm63268_ephy_info = {
-@@ -334,7 +343,11 @@ static int b53_mmap_probe(struct platfor
-       priv->gpio_ctrl = syscon_regmap_lookup_by_phandle(np, "brcm,gpio-ctrl");
-       if (!IS_ERR(priv->gpio_ctrl)) {
--              if (pdata->chip_id == BCM63268_DEVICE_ID)
-+              if (pdata->chip_id == BCM6318_DEVICE_ID ||
-+                  pdata->chip_id == BCM6328_DEVICE_ID ||
-+                  pdata->chip_id == BCM6362_DEVICE_ID)
-+                      priv->phy_info = &bcm6318_ephy_info;
-+              else if (pdata->chip_id == BCM63268_DEVICE_ID)
-                       priv->phy_info = &bcm63268_ephy_info;
-       }
diff --git a/target/linux/generic/backport-6.18/611-12-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6368.patch b/target/linux/generic/backport-6.18/611-12-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6368.patch
deleted file mode 100644 (file)
index f703804..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From e8e13073dff7052b144d002bae2cfe9ddfa27e2a Mon Sep 17 00:00:00 2001
-From: Kyle Hendry <kylehendrydev@gmail.com>
-Date: Wed, 23 Jul 2025 20:52:45 -0700
-Subject: [PATCH] net: dsa: b53: mmap: Add register layout for bcm6368
-
-Add ephy register info for bcm6368.
-
-Signed-off-by: Kyle Hendry <kylehendrydev@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250724035300.20497-7-kylehendrydev@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_mmap.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -49,6 +49,15 @@ static const struct b53_phy_info bcm6318
-       .ephy_offset = bcm6318_ephy_offsets,
- };
-+static const u32 bcm6368_ephy_offsets[] = {2, 3, 4, 5};
-+
-+static const struct b53_phy_info bcm6368_ephy_info = {
-+      .ephy_enable_mask = BIT(0),
-+      .ephy_port_mask = GENMASK((ARRAY_SIZE(bcm6368_ephy_offsets) - 1), 0),
-+      .ephy_bias_bit = 0,
-+      .ephy_offset = bcm6368_ephy_offsets,
-+};
-+
- static const u32 bcm63268_ephy_offsets[] = {4, 9, 14};
- static const struct b53_phy_info bcm63268_ephy_info = {
-@@ -347,6 +356,8 @@ static int b53_mmap_probe(struct platfor
-                   pdata->chip_id == BCM6328_DEVICE_ID ||
-                   pdata->chip_id == BCM6362_DEVICE_ID)
-                       priv->phy_info = &bcm6318_ephy_info;
-+              else if (pdata->chip_id == BCM6368_DEVICE_ID)
-+                      priv->phy_info = &bcm6368_ephy_info;
-               else if (pdata->chip_id == BCM63268_DEVICE_ID)
-                       priv->phy_info = &bcm63268_ephy_info;
-       }
diff --git a/target/linux/generic/backport-6.18/611-13-v6.18-net-dsa-b53-mmap-Implement-bcm63xx-ephy-power-control.patch b/target/linux/generic/backport-6.18/611-13-v6.18-net-dsa-b53-mmap-Implement-bcm63xx-ephy-power-control.patch
deleted file mode 100644 (file)
index bf3aeb7..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-From 5ac00023852d960528a0c1d10ae6c17893fc4113 Mon Sep 17 00:00:00 2001
-From: Kyle Hendry <kylehendrydev@gmail.com>
-Date: Wed, 23 Jul 2025 20:52:46 -0700
-Subject: [PATCH] net: dsa: b53: mmap: Implement bcm63xx ephy power control
-
-Implement the phy enable/disable calls for b53 mmap, and
-set the power down registers in the ephy control register
-appropriately.
-
-Signed-off-by: Kyle Hendry <kylehendrydev@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250724035300.20497-8-kylehendrydev@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_mmap.c | 50 ++++++++++++++++++++++++++++++++++
- 1 file changed, 50 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -24,9 +24,12 @@
- #include <linux/mfd/syscon.h>
- #include <linux/platform_device.h>
- #include <linux/platform_data/b53.h>
-+#include <linux/regmap.h>
- #include "b53_priv.h"
-+#define BCM63XX_EPHY_REG 0x3C
-+
- struct b53_phy_info {
-       u32 ephy_enable_mask;
-       u32 ephy_port_mask;
-@@ -38,6 +41,7 @@ struct b53_mmap_priv {
-       void __iomem *regs;
-       struct regmap *gpio_ctrl;
-       const struct b53_phy_info *phy_info;
-+      u32 phys_enabled;
- };
- static const u32 bcm6318_ephy_offsets[] = {4, 5, 6, 7};
-@@ -266,6 +270,50 @@ static int b53_mmap_phy_write16(struct b
-       return -EIO;
- }
-+static int bcm63xx_ephy_set(struct b53_device *dev, int port, bool enable)
-+{
-+      struct b53_mmap_priv *priv = dev->priv;
-+      const struct b53_phy_info *info = priv->phy_info;
-+      struct regmap *gpio_ctrl = priv->gpio_ctrl;
-+      u32 mask, val;
-+
-+      if (enable) {
-+              mask = (info->ephy_enable_mask << info->ephy_offset[port])
-+                              | BIT(info->ephy_bias_bit);
-+              val = 0;
-+      } else {
-+              mask = (info->ephy_enable_mask << info->ephy_offset[port]);
-+              if (!((priv->phys_enabled & ~BIT(port)) & info->ephy_port_mask))
-+                      mask |= BIT(info->ephy_bias_bit);
-+              val = mask;
-+      }
-+      return regmap_update_bits(gpio_ctrl, BCM63XX_EPHY_REG, mask, val);
-+}
-+
-+static void b53_mmap_phy_enable(struct b53_device *dev, int port)
-+{
-+      struct b53_mmap_priv *priv = dev->priv;
-+      int ret = 0;
-+
-+      if (priv->phy_info && (BIT(port) & priv->phy_info->ephy_port_mask))
-+              ret = bcm63xx_ephy_set(dev, port, true);
-+
-+      if (!ret)
-+              priv->phys_enabled |= BIT(port);
-+}
-+
-+static void b53_mmap_phy_disable(struct b53_device *dev, int port)
-+{
-+      struct b53_mmap_priv *priv = dev->priv;
-+      int ret = 0;
-+
-+      if (priv->phy_info && (BIT(port) & priv->phy_info->ephy_port_mask))
-+              ret = bcm63xx_ephy_set(dev, port, false);
-+
-+      if (!ret)
-+              priv->phys_enabled &= ~BIT(port);
-+}
-+
- static const struct b53_io_ops b53_mmap_ops = {
-       .read8 = b53_mmap_read8,
-       .read16 = b53_mmap_read16,
-@@ -279,6 +327,8 @@ static const struct b53_io_ops b53_mmap_
-       .write64 = b53_mmap_write64,
-       .phy_read16 = b53_mmap_phy_read16,
-       .phy_write16 = b53_mmap_phy_write16,
-+      .phy_enable = b53_mmap_phy_enable,
-+      .phy_disable = b53_mmap_phy_disable,
- };
- static int b53_mmap_probe_of(struct platform_device *pdev,
diff --git a/target/linux/generic/backport-6.18/611-14-v6.18-net-dsa-b53-mmap-Add-gphy-port-to-phy-info-for-bcm63268.patch b/target/linux/generic/backport-6.18/611-14-v6.18-net-dsa-b53-mmap-Add-gphy-port-to-phy-info-for-bcm63268.patch
deleted file mode 100644 (file)
index 9aa99d2..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From 7f95f04fe1903a31b61085e3ab1b4730f9d72941 Mon Sep 17 00:00:00 2001
-From: Kyle Hendry <kylehendrydev@gmail.com>
-Date: Wed, 13 Aug 2025 17:25:27 -0700
-Subject: [PATCH] net: dsa: b53: mmap: Add gphy port to phy info for bcm63268
-
-Add gphy mask to bcm63xx phy info struct and add data for bcm63268
-
-Signed-off-by: Kyle Hendry <kylehendrydev@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250814002530.5866-2-kylehendrydev@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_mmap.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -31,6 +31,7 @@
- #define BCM63XX_EPHY_REG 0x3C
- struct b53_phy_info {
-+      u32 gphy_port_mask;
-       u32 ephy_enable_mask;
-       u32 ephy_port_mask;
-       u32 ephy_bias_bit;
-@@ -65,6 +66,7 @@ static const struct b53_phy_info bcm6368
- static const u32 bcm63268_ephy_offsets[] = {4, 9, 14};
- static const struct b53_phy_info bcm63268_ephy_info = {
-+      .gphy_port_mask = BIT(3),
-       .ephy_enable_mask = GENMASK(4, 0),
-       .ephy_port_mask = GENMASK((ARRAY_SIZE(bcm63268_ephy_offsets) - 1), 0),
-       .ephy_bias_bit = 24,
diff --git a/target/linux/generic/backport-6.18/611-15-v6.18-net-dsa-b53-mmap-Implement-bcm63268-gphy-power-control.patch b/target/linux/generic/backport-6.18/611-15-v6.18-net-dsa-b53-mmap-Implement-bcm63268-gphy-power-control.patch
deleted file mode 100644 (file)
index 8dda51e..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From 61730ac10ba90c52563861a0119504f6a9be9868 Mon Sep 17 00:00:00 2001
-From: Kyle Hendry <kylehendrydev@gmail.com>
-Date: Wed, 13 Aug 2025 17:25:28 -0700
-Subject: [PATCH] net: dsa: b53: mmap: Implement bcm63268 gphy power control
-
-Add check for gphy in enable/disable phy calls and set power bits
-in gphy control register.
-
-Signed-off-by: Kyle Hendry <kylehendrydev@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250814002530.5866-3-kylehendrydev@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_mmap.c | 33 +++++++++++++++++++++++++++++----
- 1 file changed, 29 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -29,6 +29,10 @@
- #include "b53_priv.h"
- #define BCM63XX_EPHY_REG 0x3C
-+#define BCM63268_GPHY_REG 0x54
-+
-+#define GPHY_CTRL_LOW_PWR     BIT(3)
-+#define GPHY_CTRL_IDDQ_BIAS   BIT(0)
- struct b53_phy_info {
-       u32 gphy_port_mask;
-@@ -292,13 +296,30 @@ static int bcm63xx_ephy_set(struct b53_d
-       return regmap_update_bits(gpio_ctrl, BCM63XX_EPHY_REG, mask, val);
- }
-+static int bcm63268_gphy_set(struct b53_device *dev, bool enable)
-+{
-+      struct b53_mmap_priv *priv = dev->priv;
-+      struct regmap *gpio_ctrl = priv->gpio_ctrl;
-+      u32 mask = GPHY_CTRL_IDDQ_BIAS | GPHY_CTRL_LOW_PWR;
-+      u32 val = 0;
-+
-+      if (!enable)
-+              val = mask;
-+
-+      return regmap_update_bits(gpio_ctrl, BCM63268_GPHY_REG, mask, val);
-+}
-+
- static void b53_mmap_phy_enable(struct b53_device *dev, int port)
- {
-       struct b53_mmap_priv *priv = dev->priv;
-       int ret = 0;
--      if (priv->phy_info && (BIT(port) & priv->phy_info->ephy_port_mask))
--              ret = bcm63xx_ephy_set(dev, port, true);
-+      if (priv->phy_info) {
-+              if (BIT(port) & priv->phy_info->ephy_port_mask)
-+                      ret = bcm63xx_ephy_set(dev, port, true);
-+              else if (BIT(port) & priv->phy_info->gphy_port_mask)
-+                      ret = bcm63268_gphy_set(dev, true);
-+      }
-       if (!ret)
-               priv->phys_enabled |= BIT(port);
-@@ -309,8 +330,12 @@ static void b53_mmap_phy_disable(struct
-       struct b53_mmap_priv *priv = dev->priv;
-       int ret = 0;
--      if (priv->phy_info && (BIT(port) & priv->phy_info->ephy_port_mask))
--              ret = bcm63xx_ephy_set(dev, port, false);
-+      if (priv->phy_info) {
-+              if (BIT(port) & priv->phy_info->ephy_port_mask)
-+                      ret = bcm63xx_ephy_set(dev, port, false);
-+              else if (BIT(port) & priv->phy_info->gphy_port_mask)
-+                      ret = bcm63268_gphy_set(dev, false);
-+      }
-       if (!ret)
-               priv->phys_enabled &= ~BIT(port);
diff --git a/target/linux/generic/backport-6.18/611-16-v6.18-net-dsa-b53-fix-reserved-register-access-in-b53_fdb_dump.patch b/target/linux/generic/backport-6.18/611-16-v6.18-net-dsa-b53-fix-reserved-register-access-in-b53_fdb_dump.patch
deleted file mode 100644 (file)
index 5190cf9..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-From 89eb9a62aed77b409663ba1eac152e8f758815b7 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 15 Aug 2025 22:18:09 +0200
-Subject: [PATCH] net: dsa: b53: fix reserved register access in b53_fdb_dump()
-
-When BCM5325 support was added in c45655386e53 ("net: dsa: b53: add
-support for FDB operations on 5325/5365"), the register used for ARL access
-was made conditional on the chip.
-
-But in b53_fdb_dump(), instead of the register argument the page
-argument was replaced, causing it to write to a reserved page 0x50 on
-!BCM5325*. Writing to this page seems to completely lock the switch up:
-
-[   89.680000] b53-switch spi0.1 lan2: Link is Down
-[   89.680000] WARNING: CPU: 1 PID: 26 at drivers/net/phy/phy.c:1350 _phy_state_machine+0x1bc/0x454
-[   89.720000] phy_check_link_status+0x0/0x114: returned: -5
-[   89.730000] Modules linked in: nft_fib_inet nf_flow_table_inet nft_reject_ipv6 nft_reject_ipv4 nft_reject_inet nft_reject nft_redir nft_quota nft_numgen nft_nat nft_masq nft_log nft_limit nft_hash nft_flow_offload nft_fib_ipv6 nft_fib_ipv4 nft_fib nft_ct nft_chain_nat nf_tables nf_nat nf_flow_table nf_conntrack nfnetlink nf_reject_ipv6 nf_reject_ipv4 nf_log_syslog nf_defrag_ipv6 nf_defrag_ipv4 cls_flower sch_tbf sch_ingress sch_htb sch_hfsc em_u32 cls_u32 cls_route cls_matchall cls_fw cls_flow cls_basic act_skbedit act_mirred act_gact vrf md5 crc32c_cryptoapi
-[   89.780000] CPU: 1 UID: 0 PID: 26 Comm: kworker/u10:0 Tainted: G        W           6.16.0-rc1+ #0 NONE
-[   89.780000] Tainted: [W]=WARN
-[   89.780000] Hardware name: Netgear DGND3700 v1
-[   89.780000] Workqueue: events_power_efficient phy_state_machine
-[   89.780000] Stack : 809c762c 8006b050 00000001 820a9ce3 0000114c 000affff 805d22d0 8200ba00
-[   89.780000]         82005000 6576656e 74735f70 6f776572 5f656666 10008b00 820a9cb8 82088700
-[   89.780000]         00000000 00000000 809c762c 820a9a98 00000000 00000000 ffffefff 80a7a76c
-[   89.780000]         80a70000 820a9af8 80a70000 80a70000 80a70000 00000000 809c762c 820a9dd4
-[   89.780000]         00000000 805d1494 80a029e4 80a70000 00000003 00000000 00000004 81a60004
-[   89.780000]         ...
-[   89.780000] Call Trace:
-[   89.780000] [<800228b8>] show_stack+0x38/0x118
-[   89.780000] [<8001afc4>] dump_stack_lvl+0x6c/0xac
-[   89.780000] [<80046b90>] __warn+0x9c/0x114
-[   89.780000] [<80046da8>] warn_slowpath_fmt+0x1a0/0x1b0
-[   89.780000] [<805d1494>] _phy_state_machine+0x1bc/0x454
-[   89.780000] [<805d22fc>] phy_state_machine+0x2c/0x70
-[   89.780000] [<80066b08>] process_one_work+0x1e8/0x3e0
-[   89.780000] [<80067a1c>] worker_thread+0x354/0x4e4
-[   89.780000] [<800706cc>] kthread+0x130/0x274
-[   89.780000] [<8001d808>] ret_from_kernel_thread+0x14/0x1c
-
-And any further accesses fail:
-
-[  120.790000] b53-switch spi0.1: timeout waiting for ARL to finish: 0x81
-[  120.800000] b53-switch spi0.1: port 2 failed to add 2c:b0:5d:27:9a:bd vid 3 to fdb: -145
-[  121.010000] b53-switch spi0.1: timeout waiting for ARL to finish: 0xbf
-[  121.020000] b53-switch spi0.1: port 3 failed to add 2c:b0:5d:27:9a:bd vid 3 to fdb: -145
-
-Restore the correct page B53_ARLIO_PAGE again, and move the offset
-argument to the correct place.
-
-*On BCM5325, this became a write to the MIB page of Port 1. Still
-a reserved offset, but likely less brokenness from that write.
-
-Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250815201809.549195-1-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2100,7 +2100,7 @@ int b53_fdb_dump(struct dsa_switch *ds,
-       /* Start search operation */
-       reg = ARL_SRCH_STDN;
--      b53_write8(priv, offset, B53_ARL_SRCH_CTL, reg);
-+      b53_write8(priv, B53_ARLIO_PAGE, offset, reg);
-       do {
-               ret = b53_arl_search_wait(priv);
diff --git a/target/linux/generic/backport-6.18/611-17-v6.18-net-dsa-b53-fix-ageing-time-for-BCM53101.patch b/target/linux/generic/backport-6.18/611-17-v6.18-net-dsa-b53-fix-ageing-time-for-BCM53101.patch
deleted file mode 100644 (file)
index 0eb0870..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From 674b34c4c770551e916ae707829c7faea4782d3a Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 5 Sep 2025 14:45:07 +0200
-Subject: [PATCH] net: dsa: b53: fix ageing time for BCM53101
-
-For some reason Broadcom decided that BCM53101 uses 0.5s increments for
-the ageing time register, but kept the field width the same [1]. Due to
-this, the actual ageing time was always half of what was configured.
-
-Fix this by adapting the limits and value calculation for BCM53101.
-
-So far it looks like this is the only chip with the increased tick
-speed:
-
-$ grep -l -r "Specifies the aging time in 0.5 seconds" cdk/PKG/chip | sort
-cdk/PKG/chip/bcm53101/bcm53101_a0_defs.h
-
-$ grep -l -r "Specifies the aging time in seconds" cdk/PKG/chip | sort
-cdk/PKG/chip/bcm53010/bcm53010_a0_defs.h
-cdk/PKG/chip/bcm53020/bcm53020_a0_defs.h
-cdk/PKG/chip/bcm53084/bcm53084_a0_defs.h
-cdk/PKG/chip/bcm53115/bcm53115_a0_defs.h
-cdk/PKG/chip/bcm53118/bcm53118_a0_defs.h
-cdk/PKG/chip/bcm53125/bcm53125_a0_defs.h
-cdk/PKG/chip/bcm53128/bcm53128_a0_defs.h
-cdk/PKG/chip/bcm53134/bcm53134_a0_defs.h
-cdk/PKG/chip/bcm53242/bcm53242_a0_defs.h
-cdk/PKG/chip/bcm53262/bcm53262_a0_defs.h
-cdk/PKG/chip/bcm53280/bcm53280_a0_defs.h
-cdk/PKG/chip/bcm53280/bcm53280_b0_defs.h
-cdk/PKG/chip/bcm53600/bcm53600_a0_defs.h
-cdk/PKG/chip/bcm89500/bcm89500_a0_defs.h
-
-[1] https://github.com/Broadcom/OpenMDK/blob/a5d3fc9b12af3eeb68f2ca0ce7ec4056cd14d6c2/cdk/PKG/chip/bcm53101/bcm53101_a0_defs.h#L28966
-
-Fixes: e39d14a760c0 ("net: dsa: b53: implement setting ageing time")
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20250905124507.59186-1-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 17 +++++++++++++----
- 1 file changed, 13 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1273,9 +1273,15 @@ static int b53_setup(struct dsa_switch *
-        */
-       ds->untag_vlan_aware_bridge_pvid = true;
--      /* Ageing time is set in seconds */
--      ds->ageing_time_min = 1 * 1000;
--      ds->ageing_time_max = AGE_TIME_MAX * 1000;
-+      if (dev->chip_id == BCM53101_DEVICE_ID) {
-+              /* BCM53101 uses 0.5 second increments */
-+              ds->ageing_time_min = 1 * 500;
-+              ds->ageing_time_max = AGE_TIME_MAX * 500;
-+      } else {
-+              /* Everything else uses 1 second increments */
-+              ds->ageing_time_min = 1 * 1000;
-+              ds->ageing_time_max = AGE_TIME_MAX * 1000;
-+      }
-       ret = b53_reset_switch(dev);
-       if (ret) {
-@@ -2587,7 +2593,10 @@ int b53_set_ageing_time(struct dsa_switc
-       else
-               reg = B53_AGING_TIME_CONTROL;
--      atc = DIV_ROUND_CLOSEST(msecs, 1000);
-+      if (dev->chip_id == BCM53101_DEVICE_ID)
-+              atc = DIV_ROUND_CLOSEST(msecs, 500);
-+      else
-+              atc = DIV_ROUND_CLOSEST(msecs, 1000);
-       if (!is5325(dev) && !is5365(dev))
-               atc |= AGE_CHANGE;
diff --git a/target/linux/generic/backport-6.18/611-18-v6.18-net-dsa-b53-properly-bound-ARL-searches-for-4-ARL-bin-chips.patch b/target/linux/generic/backport-6.18/611-18-v6.18-net-dsa-b53-properly-bound-ARL-searches-for-4-ARL-bin-chips.patch
deleted file mode 100644 (file)
index 50ddcf9..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From e57723fe536f040cc2635ec1545dd0a7919a321e Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Sun, 2 Nov 2025 11:07:58 +0100
-Subject: [PATCH] net: dsa: b53: properly bound ARL searches for < 4 ARL bin
- chips
-
-When iterating over the ARL table we stop at max ARL entries / 2, but
-this is only valid if the chip actually returns 2 results at once. For
-chips with only one result register we will stop before reaching the end
-of the table if it is more than half full.
-
-Fix this by only dividing the maximum results by two if we have a chip
-with more than one result register (i.e. those with 4 ARL bins).
-
-Fixes: cd169d799bee ("net: dsa: b53: Bound check ARL searches")
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251102100758.28352-4-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2090,13 +2090,16 @@ static int b53_fdb_copy(int port, const
- int b53_fdb_dump(struct dsa_switch *ds, int port,
-                dsa_fdb_dump_cb_t *cb, void *data)
- {
-+      unsigned int count = 0, results_per_hit = 1;
-       struct b53_device *priv = ds->priv;
-       struct b53_arl_entry results[2];
--      unsigned int count = 0;
-       u8 offset;
-       int ret;
-       u8 reg;
-+      if (priv->num_arl_bins > 2)
-+              results_per_hit = 2;
-+
-       mutex_lock(&priv->arl_mutex);
-       if (is5325(priv) || is5365(priv))
-@@ -2118,7 +2121,7 @@ int b53_fdb_dump(struct dsa_switch *ds,
-               if (ret)
-                       break;
--              if (priv->num_arl_bins > 2) {
-+              if (results_per_hit == 2) {
-                       b53_arl_search_rd(priv, 1, &results[1]);
-                       ret = b53_fdb_copy(port, &results[1], cb, data);
-                       if (ret)
-@@ -2128,7 +2131,7 @@ int b53_fdb_dump(struct dsa_switch *ds,
-                               break;
-               }
--      } while (count++ < b53_max_arl_entries(priv) / 2);
-+      } while (count++ < b53_max_arl_entries(priv) / results_per_hit);
-       mutex_unlock(&priv->arl_mutex);
diff --git a/target/linux/generic/backport-6.18/611-19-v6.18-net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-offloaded.patch b/target/linux/generic/backport-6.18/611-19-v6.18-net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-offloaded.patch
deleted file mode 100644 (file)
index 7c3d062..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-From 762e7e174da91cf4babfe77e45bc6b67334b1503 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Sun, 9 Nov 2025 14:46:35 +0100
-Subject: [PATCH] net: dsa: tag_brcm: do not mark link local traffic as
- offloaded
-
-Broadcom switches locally terminate link local traffic and do not
-forward it, so we should not mark it as offloaded.
-
-In some situations we still want/need to flood this traffic, e.g. if STP
-is disabled, or it is explicitly enabled via the group_fwd_mask. But if
-the skb is marked as offloaded, the kernel will assume this was already
-done in hardware, and the packets never reach other bridge ports.
-
-So ensure that link local traffic is never marked as offloaded, so that
-the kernel can forward/flood these packets in software if needed.
-
-Since the local termination in not configurable, check the destination
-MAC, and never mark packets as offloaded if it is a link local ether
-address.
-
-While modern switches set the tag reason code to BRCM_EG_RC_PROT_TERM
-for trapped link local traffic, they also set it for link local traffic
-that is flooded (01:80:c2:00:00:10 to 01:80:c2:00:00:2f), so we cannot
-use it and need to look at the destination address for them as well.
-
-Fixes: 964dbf186eaa ("net: dsa: tag_brcm: add support for legacy tags")
-Fixes: 0e62f543bed0 ("net: dsa: Fix duplicate frames flooded by learning")
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251109134635.243951-1-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/dsa/tag_brcm.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/net/dsa/tag_brcm.c
-+++ b/net/dsa/tag_brcm.c
-@@ -176,7 +176,8 @@ static struct sk_buff *brcm_tag_rcv_ll(s
-       /* Remove Broadcom tag and update checksum */
-       skb_pull_rcsum(skb, BRCM_TAG_LEN);
--      dsa_default_offload_fwd_mark(skb);
-+      if (likely(!is_link_local_ether_addr(eth_hdr(skb)->h_dest)))
-+              dsa_default_offload_fwd_mark(skb);
-       return skb;
- }
-@@ -250,7 +251,8 @@ static struct sk_buff *brcm_leg_tag_rcv(
-       /* Remove Broadcom tag and update checksum */
-       skb_pull_rcsum(skb, len);
--      dsa_default_offload_fwd_mark(skb);
-+      if (likely(!is_link_local_ether_addr(eth_hdr(skb)->h_dest)))
-+              dsa_default_offload_fwd_mark(skb);
-       dsa_strip_etype_header(skb, len);
diff --git a/target/linux/generic/backport-6.18/612-01-v6.19-net-dsa-b53-b53_arl_read-25-use-the-entry-for-comparision.patch b/target/linux/generic/backport-6.18/612-01-v6.19-net-dsa-b53-b53_arl_read-25-use-the-entry-for-comparision.patch
deleted file mode 100644 (file)
index 2b6cff7..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From a6e4fd38bf2f2e2363b61c27f4e6c49b14e4bb07 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 7 Nov 2025 09:07:42 +0100
-Subject: [PATCH] net: dsa: b53: b53_arl_read{,25}(): use the entry for
- comparision
-
-Align the b53_arl_read{,25}() functions by consistently using the
-parsed arl entry instead of parsing the raw registers again.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251107080749.26936-2-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 22 ++++++++++------------
- 1 file changed, 10 insertions(+), 12 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1830,7 +1830,7 @@ static int b53_arl_rw_op(struct b53_devi
-       return b53_arl_op_wait(dev);
- }
--static int b53_arl_read(struct b53_device *dev, u64 mac,
-+static int b53_arl_read(struct b53_device *dev, const u8 *mac,
-                       u16 vid, struct b53_arl_entry *ent, u8 *idx)
- {
-       DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
-@@ -1854,14 +1854,13 @@ static int b53_arl_read(struct b53_devic
-                          B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
-               b53_arl_to_entry(ent, mac_vid, fwd_entry);
--              if (!(fwd_entry & ARLTBL_VALID)) {
-+              if (!ent->is_valid) {
-                       set_bit(i, free_bins);
-                       continue;
-               }
--              if ((mac_vid & ARLTBL_MAC_MASK) != mac)
-+              if (!ether_addr_equal(ent->mac, mac))
-                       continue;
--              if (dev->vlan_enabled &&
--                  ((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid)
-+              if (dev->vlan_enabled && ent->vid != vid)
-                       continue;
-               *idx = i;
-               return 0;
-@@ -1871,7 +1870,7 @@ static int b53_arl_read(struct b53_devic
-       return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT;
- }
--static int b53_arl_read_25(struct b53_device *dev, u64 mac,
-+static int b53_arl_read_25(struct b53_device *dev, const u8 *mac,
-                          u16 vid, struct b53_arl_entry *ent, u8 *idx)
- {
-       DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
-@@ -1893,14 +1892,13 @@ static int b53_arl_read_25(struct b53_de
-               b53_arl_to_entry_25(ent, mac_vid);
--              if (!(mac_vid & ARLTBL_VALID_25)) {
-+              if (!ent->is_valid) {
-                       set_bit(i, free_bins);
-                       continue;
-               }
--              if ((mac_vid & ARLTBL_MAC_MASK) != mac)
-+              if (!ether_addr_equal(ent->mac, mac))
-                       continue;
--              if (dev->vlan_enabled &&
--                  ((mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25) != vid)
-+              if (dev->vlan_enabled && ent->vid != vid)
-                       continue;
-               *idx = i;
-               return 0;
-@@ -1933,9 +1931,9 @@ static int b53_arl_op(struct b53_device
-               return ret;
-       if (is5325(dev) || is5365(dev))
--              ret = b53_arl_read_25(dev, mac, vid, &ent, &idx);
-+              ret = b53_arl_read_25(dev, addr, vid, &ent, &idx);
-       else
--              ret = b53_arl_read(dev, mac, vid, &ent, &idx);
-+              ret = b53_arl_read(dev, addr, vid, &ent, &idx);
-       /* If this is a read, just finish now */
-       if (op)
diff --git a/target/linux/generic/backport-6.18/612-02-v6.19-net-dsa-b53-move-reading-ARL-entries-into-their-own-function.patch b/target/linux/generic/backport-6.18/612-02-v6.19-net-dsa-b53-move-reading-ARL-entries-into-their-own-function.patch
deleted file mode 100644 (file)
index 8cf85ce..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-From 4a291fe7226736a465ddb3fa93c21fcef7162ec7 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 7 Nov 2025 09:07:43 +0100
-Subject: [PATCH] net: dsa: b53: move reading ARL entries into their own
- function
-
-Instead of duplicating the whole code iterating over all bins for
-BCM5325, factor out reading and parsing the entry into its own
-functions, and name it the modern one after the first chip with that ARL
-format, (BCM53)95.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251107080749.26936-3-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 69 +++++++++++---------------------
- 1 file changed, 23 insertions(+), 46 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1830,48 +1830,30 @@ static int b53_arl_rw_op(struct b53_devi
-       return b53_arl_op_wait(dev);
- }
--static int b53_arl_read(struct b53_device *dev, const u8 *mac,
--                      u16 vid, struct b53_arl_entry *ent, u8 *idx)
-+static void b53_arl_read_entry_25(struct b53_device *dev,
-+                                struct b53_arl_entry *ent, u8 idx)
- {
--      DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
--      unsigned int i;
--      int ret;
--
--      ret = b53_arl_op_wait(dev);
--      if (ret)
--              return ret;
-+      u64 mac_vid;
--      bitmap_zero(free_bins, dev->num_arl_bins);
--
--      /* Read the bins */
--      for (i = 0; i < dev->num_arl_bins; i++) {
--              u64 mac_vid;
--              u32 fwd_entry;
--
--              b53_read64(dev, B53_ARLIO_PAGE,
--                         B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid);
--              b53_read32(dev, B53_ARLIO_PAGE,
--                         B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
--              b53_arl_to_entry(ent, mac_vid, fwd_entry);
-+      b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
-+                 &mac_vid);
-+      b53_arl_to_entry_25(ent, mac_vid);
-+}
--              if (!ent->is_valid) {
--                      set_bit(i, free_bins);
--                      continue;
--              }
--              if (!ether_addr_equal(ent->mac, mac))
--                      continue;
--              if (dev->vlan_enabled && ent->vid != vid)
--                      continue;
--              *idx = i;
--              return 0;
--      }
-+static void b53_arl_read_entry_95(struct b53_device *dev,
-+                                struct b53_arl_entry *ent, u8 idx)
-+{
-+      u32 fwd_entry;
-+      u64 mac_vid;
--      *idx = find_first_bit(free_bins, dev->num_arl_bins);
--      return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT;
-+      b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
-+                 &mac_vid);
-+      b53_read32(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), &fwd_entry);
-+      b53_arl_to_entry(ent, mac_vid, fwd_entry);
- }
--static int b53_arl_read_25(struct b53_device *dev, const u8 *mac,
--                         u16 vid, struct b53_arl_entry *ent, u8 *idx)
-+static int b53_arl_read(struct b53_device *dev, const u8 *mac,
-+                      u16 vid, struct b53_arl_entry *ent, u8 *idx)
- {
-       DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
-       unsigned int i;
-@@ -1885,12 +1867,10 @@ static int b53_arl_read_25(struct b53_de
-       /* Read the bins */
-       for (i = 0; i < dev->num_arl_bins; i++) {
--              u64 mac_vid;
--
--              b53_read64(dev, B53_ARLIO_PAGE,
--                         B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid);
--
--              b53_arl_to_entry_25(ent, mac_vid);
-+              if (is5325(dev) || is5365(dev))
-+                      b53_arl_read_entry_25(dev, ent, i);
-+              else
-+                      b53_arl_read_entry_95(dev, ent, i);
-               if (!ent->is_valid) {
-                       set_bit(i, free_bins);
-@@ -1930,10 +1910,7 @@ static int b53_arl_op(struct b53_device
-       if (ret)
-               return ret;
--      if (is5325(dev) || is5365(dev))
--              ret = b53_arl_read_25(dev, addr, vid, &ent, &idx);
--      else
--              ret = b53_arl_read(dev, addr, vid, &ent, &idx);
-+      ret = b53_arl_read(dev, addr, vid, &ent, &idx);
-       /* If this is a read, just finish now */
-       if (op)
diff --git a/target/linux/generic/backport-6.18/612-03-v6.19-net-dsa-b53-move-writing-ARL-entries-into-their-own-functions.patch b/target/linux/generic/backport-6.18/612-03-v6.19-net-dsa-b53-move-writing-ARL-entries-into-their-own-functions.patch
deleted file mode 100644 (file)
index a171232..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-From bf6e9d2ae1dbafee53ec4ccd126595172e1e5278 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 7 Nov 2025 09:07:44 +0100
-Subject: [PATCH] net: dsa: b53: move writing ARL entries into their own
- functions
-
-Move writing ARL entries into individual functions for each format.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251107080749.26936-4-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 38 ++++++++++++++++++++++----------
- 1 file changed, 26 insertions(+), 12 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1840,6 +1840,16 @@ static void b53_arl_read_entry_25(struct
-       b53_arl_to_entry_25(ent, mac_vid);
- }
-+static void b53_arl_write_entry_25(struct b53_device *dev,
-+                                 const struct b53_arl_entry *ent, u8 idx)
-+{
-+      u64 mac_vid;
-+
-+      b53_arl_from_entry_25(&mac_vid, ent);
-+      b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
-+                  mac_vid);
-+}
-+
- static void b53_arl_read_entry_95(struct b53_device *dev,
-                                 struct b53_arl_entry *ent, u8 idx)
- {
-@@ -1852,6 +1862,19 @@ static void b53_arl_read_entry_95(struct
-       b53_arl_to_entry(ent, mac_vid, fwd_entry);
- }
-+static void b53_arl_write_entry_95(struct b53_device *dev,
-+                                 const struct b53_arl_entry *ent, u8 idx)
-+{
-+      u32 fwd_entry;
-+      u64 mac_vid;
-+
-+      b53_arl_from_entry(&mac_vid, &fwd_entry, ent);
-+      b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
-+                  mac_vid);
-+      b53_write32(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx),
-+                  fwd_entry);
-+}
-+
- static int b53_arl_read(struct b53_device *dev, const u8 *mac,
-                       u16 vid, struct b53_arl_entry *ent, u8 *idx)
- {
-@@ -1892,9 +1915,8 @@ static int b53_arl_op(struct b53_device
-                     const unsigned char *addr, u16 vid, bool is_valid)
- {
-       struct b53_arl_entry ent;
--      u32 fwd_entry;
--      u64 mac, mac_vid = 0;
-       u8 idx = 0;
-+      u64 mac;
-       int ret;
-       /* Convert the array into a 64-bit MAC */
-@@ -1927,7 +1949,6 @@ static int b53_arl_op(struct b53_device
-               /* We could not find a matching MAC, so reset to a new entry */
-               dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n",
-                       addr, vid, idx);
--              fwd_entry = 0;
-               break;
-       default:
-               dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n",
-@@ -1955,16 +1976,9 @@ static int b53_arl_op(struct b53_device
-       ent.is_age = false;
-       memcpy(ent.mac, addr, ETH_ALEN);
-       if (is5325(dev) || is5365(dev))
--              b53_arl_from_entry_25(&mac_vid, &ent);
-+              b53_arl_write_entry_25(dev, &ent, idx);
-       else
--              b53_arl_from_entry(&mac_vid, &fwd_entry, &ent);
--
--      b53_write64(dev, B53_ARLIO_PAGE,
--                  B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid);
--
--      if (!is5325(dev) && !is5365(dev))
--              b53_write32(dev, B53_ARLIO_PAGE,
--                          B53_ARLTBL_DATA_ENTRY(idx), fwd_entry);
-+              b53_arl_write_entry_95(dev, &ent, idx);
-       return b53_arl_rw_op(dev, 0);
- }
diff --git a/target/linux/generic/backport-6.18/612-04-v6.19-net-dsa-b53-provide-accessors-for-accessing-ARL_SRCH_CTL.patch b/target/linux/generic/backport-6.18/612-04-v6.19-net-dsa-b53-provide-accessors-for-accessing-ARL_SRCH_CTL.patch
deleted file mode 100644 (file)
index 2922427..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From 1716be6db04af53bac9b869f01156a460595cf41 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 7 Nov 2025 09:07:45 +0100
-Subject: [PATCH] net: dsa: b53: provide accessors for accessing ARL_SRCH_CTL
-
-In order to more easily support more formats, move accessing
-ARL_SRCH_CTL into helper functions to contain the differences.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251107080749.26936-5-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 37 +++++++++++++++++++++-----------
- 1 file changed, 24 insertions(+), 13 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2013,18 +2013,37 @@ int b53_fdb_del(struct dsa_switch *ds, i
- }
- EXPORT_SYMBOL(b53_fdb_del);
--static int b53_arl_search_wait(struct b53_device *dev)
-+static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val)
- {
--      unsigned int timeout = 1000;
--      u8 reg, offset;
-+      u8 offset;
-+
-+      if (is5325(dev) || is5365(dev))
-+              offset = B53_ARL_SRCH_CTL_25;
-+      else
-+              offset = B53_ARL_SRCH_CTL;
-+
-+      b53_read8(dev, B53_ARLIO_PAGE, offset, val);
-+}
-+
-+static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val)
-+{
-+      u8 offset;
-       if (is5325(dev) || is5365(dev))
-               offset = B53_ARL_SRCH_CTL_25;
-       else
-               offset = B53_ARL_SRCH_CTL;
-+      b53_write8(dev, B53_ARLIO_PAGE, offset, val);
-+}
-+
-+static int b53_arl_search_wait(struct b53_device *dev)
-+{
-+      unsigned int timeout = 1000;
-+      u8 reg;
-+
-       do {
--              b53_read8(dev, B53_ARLIO_PAGE, offset, &reg);
-+              b53_read_arl_srch_ctl(dev, &reg);
-               if (!(reg & ARL_SRCH_STDN))
-                       return -ENOENT;
-@@ -2082,23 +2101,15 @@ int b53_fdb_dump(struct dsa_switch *ds,
-       unsigned int count = 0, results_per_hit = 1;
-       struct b53_device *priv = ds->priv;
-       struct b53_arl_entry results[2];
--      u8 offset;
-       int ret;
--      u8 reg;
-       if (priv->num_arl_bins > 2)
-               results_per_hit = 2;
-       mutex_lock(&priv->arl_mutex);
--      if (is5325(priv) || is5365(priv))
--              offset = B53_ARL_SRCH_CTL_25;
--      else
--              offset = B53_ARL_SRCH_CTL;
--
-       /* Start search operation */
--      reg = ARL_SRCH_STDN;
--      b53_write8(priv, B53_ARLIO_PAGE, offset, reg);
-+      b53_write_arl_srch_ctl(priv, ARL_SRCH_STDN);
-       do {
-               ret = b53_arl_search_wait(priv);
diff --git a/target/linux/generic/backport-6.18/612-05-v6.19-net-dsa-b53-split-reading-search-entry-into-their-own-functions.patch b/target/linux/generic/backport-6.18/612-05-v6.19-net-dsa-b53-split-reading-search-entry-into-their-own-functions.patch
deleted file mode 100644 (file)
index 3e263f8..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-From e0c476f325a8c9b961a3d446c24d3c8ecae7d186 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 7 Nov 2025 09:07:46 +0100
-Subject: [PATCH] net: dsa: b53: split reading search entry into their own
- functions
-
-Split reading search entries into a function for each format.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251107080749.26936-6-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 56 ++++++++++++++++++++++----------
- 1 file changed, 38 insertions(+), 18 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2056,28 +2056,48 @@ static int b53_arl_search_wait(struct b5
-       return -ETIMEDOUT;
- }
--static void b53_arl_search_rd(struct b53_device *dev, u8 idx,
--                            struct b53_arl_entry *ent)
-+static void b53_arl_search_read_25(struct b53_device *dev, u8 idx,
-+                                 struct b53_arl_entry *ent)
- {
-       u64 mac_vid;
--      if (is5325(dev)) {
--              b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
--                         &mac_vid);
--              b53_arl_to_entry_25(ent, mac_vid);
--      } else if (is5365(dev)) {
--              b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65,
--                         &mac_vid);
--              b53_arl_to_entry_25(ent, mac_vid);
--      } else {
--              u32 fwd_entry;
--
--              b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx),
--                         &mac_vid);
--              b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx),
--                         &fwd_entry);
--              b53_arl_to_entry(ent, mac_vid, fwd_entry);
--      }
-+      b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
-+                 &mac_vid);
-+      b53_arl_to_entry_25(ent, mac_vid);
-+}
-+
-+static void b53_arl_search_read_65(struct b53_device *dev, u8 idx,
-+                                 struct b53_arl_entry *ent)
-+{
-+      u64 mac_vid;
-+
-+      b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65,
-+                 &mac_vid);
-+      b53_arl_to_entry_25(ent, mac_vid);
-+}
-+
-+static void b53_arl_search_read_95(struct b53_device *dev, u8 idx,
-+                                 struct b53_arl_entry *ent)
-+{
-+      u32 fwd_entry;
-+      u64 mac_vid;
-+
-+      b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx),
-+                 &mac_vid);
-+      b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx),
-+                 &fwd_entry);
-+      b53_arl_to_entry(ent, mac_vid, fwd_entry);
-+}
-+
-+static void b53_arl_search_rd(struct b53_device *dev, u8 idx,
-+                            struct b53_arl_entry *ent)
-+{
-+      if (is5325(dev))
-+              b53_arl_search_read_25(dev, idx, ent);
-+      else if (is5365(dev))
-+              b53_arl_search_read_65(dev, idx, ent);
-+      else
-+              b53_arl_search_read_95(dev, idx, ent);
- }
- static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
diff --git a/target/linux/generic/backport-6.18/612-06-v6.19-net-dsa-b53-move-ARL-entry-functions-into-ops-struct.patch b/target/linux/generic/backport-6.18/612-06-v6.19-net-dsa-b53-move-ARL-entry-functions-into-ops-struct.patch
deleted file mode 100644 (file)
index 110e160..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-From a7e73339ad46ade76d29fb6cc7d7854222608c26 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 7 Nov 2025 09:07:47 +0100
-Subject: [PATCH] net: dsa: b53: move ARL entry functions into ops struct
-
-Now that the differences in ARL entry formats are neatly contained into
-functions per chip family, wrap them into an ops struct and add wrapper
-functions to access them.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251107080749.26936-7-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 67 ++++++++++++++++++++++----------
- drivers/net/dsa/b53/b53_priv.h   | 30 ++++++++++++++
- 2 files changed, 76 insertions(+), 21 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1890,10 +1890,7 @@ static int b53_arl_read(struct b53_devic
-       /* Read the bins */
-       for (i = 0; i < dev->num_arl_bins; i++) {
--              if (is5325(dev) || is5365(dev))
--                      b53_arl_read_entry_25(dev, ent, i);
--              else
--                      b53_arl_read_entry_95(dev, ent, i);
-+              b53_arl_read_entry(dev, ent, i);
-               if (!ent->is_valid) {
-                       set_bit(i, free_bins);
-@@ -1975,10 +1972,7 @@ static int b53_arl_op(struct b53_device
-       ent.is_static = true;
-       ent.is_age = false;
-       memcpy(ent.mac, addr, ETH_ALEN);
--      if (is5325(dev) || is5365(dev))
--              b53_arl_write_entry_25(dev, &ent, idx);
--      else
--              b53_arl_write_entry_95(dev, &ent, idx);
-+      b53_arl_write_entry(dev, &ent, idx);
-       return b53_arl_rw_op(dev, 0);
- }
-@@ -2089,17 +2083,6 @@ static void b53_arl_search_read_95(struc
-       b53_arl_to_entry(ent, mac_vid, fwd_entry);
- }
--static void b53_arl_search_rd(struct b53_device *dev, u8 idx,
--                            struct b53_arl_entry *ent)
--{
--      if (is5325(dev))
--              b53_arl_search_read_25(dev, idx, ent);
--      else if (is5365(dev))
--              b53_arl_search_read_65(dev, idx, ent);
--      else
--              b53_arl_search_read_95(dev, idx, ent);
--}
--
- static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
-                       dsa_fdb_dump_cb_t *cb, void *data)
- {
-@@ -2136,13 +2119,13 @@ int b53_fdb_dump(struct dsa_switch *ds,
-               if (ret)
-                       break;
--              b53_arl_search_rd(priv, 0, &results[0]);
-+              b53_arl_search_read(priv, 0, &results[0]);
-               ret = b53_fdb_copy(port, &results[0], cb, data);
-               if (ret)
-                       break;
-               if (results_per_hit == 2) {
--                      b53_arl_search_rd(priv, 1, &results[1]);
-+                      b53_arl_search_read(priv, 1, &results[1]);
-                       ret = b53_fdb_copy(port, &results[1], cb, data);
-                       if (ret)
-                               break;
-@@ -2675,6 +2658,24 @@ static const struct dsa_switch_ops b53_s
-       .port_change_mtu        = b53_change_mtu,
- };
-+static const struct b53_arl_ops b53_arl_ops_25 = {
-+      .arl_read_entry = b53_arl_read_entry_25,
-+      .arl_write_entry = b53_arl_write_entry_25,
-+      .arl_search_read = b53_arl_search_read_25,
-+};
-+
-+static const struct b53_arl_ops b53_arl_ops_65 = {
-+      .arl_read_entry = b53_arl_read_entry_25,
-+      .arl_write_entry = b53_arl_write_entry_25,
-+      .arl_search_read = b53_arl_search_read_65,
-+};
-+
-+static const struct b53_arl_ops b53_arl_ops_95 = {
-+      .arl_read_entry = b53_arl_read_entry_95,
-+      .arl_write_entry = b53_arl_write_entry_95,
-+      .arl_search_read = b53_arl_search_read_95,
-+};
-+
- struct b53_chip_data {
-       u32 chip_id;
-       const char *dev_name;
-@@ -2688,6 +2689,7 @@ struct b53_chip_data {
-       u8 duplex_reg;
-       u8 jumbo_pm_reg;
-       u8 jumbo_size_reg;
-+      const struct b53_arl_ops *arl_ops;
- };
- #define B53_VTA_REGS  \
-@@ -2707,6 +2709,7 @@ static const struct b53_chip_data b53_sw
-               .arl_buckets = 1024,
-               .imp_port = 5,
-               .duplex_reg = B53_DUPLEX_STAT_FE,
-+              .arl_ops = &b53_arl_ops_25,
-       },
-       {
-               .chip_id = BCM5365_DEVICE_ID,
-@@ -2717,6 +2720,7 @@ static const struct b53_chip_data b53_sw
-               .arl_buckets = 1024,
-               .imp_port = 5,
-               .duplex_reg = B53_DUPLEX_STAT_FE,
-+              .arl_ops = &b53_arl_ops_65,
-       },
-       {
-               .chip_id = BCM5389_DEVICE_ID,
-@@ -2730,6 +2734,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM5395_DEVICE_ID,
-@@ -2743,6 +2748,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM5397_DEVICE_ID,
-@@ -2756,6 +2762,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM5398_DEVICE_ID,
-@@ -2769,6 +2776,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53101_DEVICE_ID,
-@@ -2782,6 +2790,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53115_DEVICE_ID,
-@@ -2795,6 +2804,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53125_DEVICE_ID,
-@@ -2808,6 +2818,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53128_DEVICE_ID,
-@@ -2821,6 +2832,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM63XX_DEVICE_ID,
-@@ -2834,6 +2846,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_63XX,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53010_DEVICE_ID,
-@@ -2847,6 +2860,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53011_DEVICE_ID,
-@@ -2860,6 +2874,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53012_DEVICE_ID,
-@@ -2873,6 +2888,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53018_DEVICE_ID,
-@@ -2886,6 +2902,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53019_DEVICE_ID,
-@@ -2899,6 +2916,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM58XX_DEVICE_ID,
-@@ -2912,6 +2930,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM583XX_DEVICE_ID,
-@@ -2925,6 +2944,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       /* Starfighter 2 */
-       {
-@@ -2939,6 +2959,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM7445_DEVICE_ID,
-@@ -2952,6 +2973,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM7278_DEVICE_ID,
-@@ -2965,6 +2987,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
-       {
-               .chip_id = BCM53134_DEVICE_ID,
-@@ -2979,6 +3002,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-+              .arl_ops = &b53_arl_ops_95,
-       },
- };
-@@ -3007,6 +3031,7 @@ static int b53_switch_init(struct b53_de
-                       dev->num_vlans = chip->vlans;
-                       dev->num_arl_bins = chip->arl_bins;
-                       dev->num_arl_buckets = chip->arl_buckets;
-+                      dev->arl_ops = chip->arl_ops;
-                       break;
-               }
-       }
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -58,6 +58,17 @@ struct b53_io_ops {
-                               bool link_up);
- };
-+struct b53_arl_entry;
-+
-+struct b53_arl_ops {
-+      void (*arl_read_entry)(struct b53_device *dev,
-+                             struct b53_arl_entry *ent, u8 idx);
-+      void (*arl_write_entry)(struct b53_device *dev,
-+                              const struct b53_arl_entry *ent, u8 idx);
-+      void (*arl_search_read)(struct b53_device *dev, u8 idx,
-+                              struct b53_arl_entry *ent);
-+};
-+
- #define B53_INVALID_LANE      0xff
- enum {
-@@ -127,6 +138,7 @@ struct b53_device {
-       struct mutex stats_mutex;
-       struct mutex arl_mutex;
-       const struct b53_io_ops *ops;
-+      const struct b53_arl_ops *arl_ops;
-       /* chip specific data */
-       u32 chip_id;
-@@ -371,6 +383,24 @@ static inline void b53_arl_from_entry_25
-               *mac_vid |= ARLTBL_AGE_25;
- }
-+static inline void b53_arl_read_entry(struct b53_device *dev,
-+                                    struct b53_arl_entry *ent, u8 idx)
-+{
-+      dev->arl_ops->arl_read_entry(dev, ent, idx);
-+}
-+
-+static inline void b53_arl_write_entry(struct b53_device *dev,
-+                                     const struct b53_arl_entry *ent, u8 idx)
-+{
-+      dev->arl_ops->arl_write_entry(dev, ent, idx);
-+}
-+
-+static inline void b53_arl_search_read(struct b53_device *dev, u8 idx,
-+                                     struct b53_arl_entry *ent)
-+{
-+      dev->arl_ops->arl_search_read(dev, idx, ent);
-+}
-+
- #ifdef CONFIG_BCM47XX
- #include <linux/bcm47xx_nvram.h>
diff --git a/target/linux/generic/backport-6.18/612-07-v6.19-net-dsa-b53-add-support-for-5389-5397-5398-ARL-entry-format.patch b/target/linux/generic/backport-6.18/612-07-v6.19-net-dsa-b53-add-support-for-5389-5397-5398-ARL-entry-format.patch
deleted file mode 100644 (file)
index 948b4ab..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-From 300f78e8b6b7be17c2c78afeded75be68acb1aa7 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 7 Nov 2025 09:07:48 +0100
-Subject: [PATCH] net: dsa: b53: add support for 5389/5397/5398 ARL entry
- format
-
-BCM5389, BCM5397 and BCM5398 use a different ARL entry format with just
-a 16 bit fwdentry register, as well as different search control and data
-offsets.
-
-So add appropriate ops for them and switch those chips to use them.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251107080749.26936-8-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 53 ++++++++++++++++++++++++++++++--
- drivers/net/dsa/b53/b53_priv.h   | 26 ++++++++++++++++
- drivers/net/dsa/b53/b53_regs.h   | 13 ++++++++
- 3 files changed, 89 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1850,6 +1850,31 @@ static void b53_arl_write_entry_25(struc
-                   mac_vid);
- }
-+static void b53_arl_read_entry_89(struct b53_device *dev,
-+                                struct b53_arl_entry *ent, u8 idx)
-+{
-+      u64 mac_vid;
-+      u16 fwd_entry;
-+
-+      b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
-+                 &mac_vid);
-+      b53_read16(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), &fwd_entry);
-+      b53_arl_to_entry_89(ent, mac_vid, fwd_entry);
-+}
-+
-+static void b53_arl_write_entry_89(struct b53_device *dev,
-+                                 const struct b53_arl_entry *ent, u8 idx)
-+{
-+      u32 fwd_entry;
-+      u64 mac_vid;
-+
-+      b53_arl_from_entry_89(&mac_vid, &fwd_entry, ent);
-+      b53_write64(dev, B53_ARLIO_PAGE,
-+                  B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid);
-+      b53_write16(dev, B53_ARLIO_PAGE,
-+                  B53_ARLTBL_DATA_ENTRY(idx), fwd_entry);
-+}
-+
- static void b53_arl_read_entry_95(struct b53_device *dev,
-                                 struct b53_arl_entry *ent, u8 idx)
- {
-@@ -2013,6 +2038,8 @@ static void b53_read_arl_srch_ctl(struct
-       if (is5325(dev) || is5365(dev))
-               offset = B53_ARL_SRCH_CTL_25;
-+      else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev))
-+              offset = B53_ARL_SRCH_CTL_89;
-       else
-               offset = B53_ARL_SRCH_CTL;
-@@ -2025,6 +2052,8 @@ static void b53_write_arl_srch_ctl(struc
-       if (is5325(dev) || is5365(dev))
-               offset = B53_ARL_SRCH_CTL_25;
-+      else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev))
-+              offset = B53_ARL_SRCH_CTL_89;
-       else
-               offset = B53_ARL_SRCH_CTL;
-@@ -2070,6 +2099,18 @@ static void b53_arl_search_read_65(struc
-       b53_arl_to_entry_25(ent, mac_vid);
- }
-+static void b53_arl_search_read_89(struct b53_device *dev, u8 idx,
-+                                 struct b53_arl_entry *ent)
-+{
-+      u16 fwd_entry;
-+      u64 mac_vid;
-+
-+      b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_MACVID_89,
-+                 &mac_vid);
-+      b53_read16(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_89, &fwd_entry);
-+      b53_arl_to_entry_89(ent, mac_vid, fwd_entry);
-+}
-+
- static void b53_arl_search_read_95(struct b53_device *dev, u8 idx,
-                                  struct b53_arl_entry *ent)
- {
-@@ -2670,6 +2711,12 @@ static const struct b53_arl_ops b53_arl_
-       .arl_search_read = b53_arl_search_read_65,
- };
-+static const struct b53_arl_ops b53_arl_ops_89 = {
-+      .arl_read_entry = b53_arl_read_entry_89,
-+      .arl_write_entry = b53_arl_write_entry_89,
-+      .arl_search_read = b53_arl_search_read_89,
-+};
-+
- static const struct b53_arl_ops b53_arl_ops_95 = {
-       .arl_read_entry = b53_arl_read_entry_95,
-       .arl_write_entry = b53_arl_write_entry_95,
-@@ -2734,7 +2781,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
--              .arl_ops = &b53_arl_ops_95,
-+              .arl_ops = &b53_arl_ops_89,
-       },
-       {
-               .chip_id = BCM5395_DEVICE_ID,
-@@ -2762,7 +2809,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
--              .arl_ops = &b53_arl_ops_95,
-+              .arl_ops = &b53_arl_ops_89,
-       },
-       {
-               .chip_id = BCM5398_DEVICE_ID,
-@@ -2776,7 +2823,7 @@ static const struct b53_chip_data b53_sw
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
--              .arl_ops = &b53_arl_ops_95,
-+              .arl_ops = &b53_arl_ops_89,
-       },
-       {
-               .chip_id = BCM53101_DEVICE_ID,
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -353,6 +353,18 @@ static inline void b53_arl_to_entry_25(s
-       ent->vid = mac_vid >> ARLTBL_VID_S_65;
- }
-+static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent,
-+                                     u64 mac_vid, u16 fwd_entry)
-+{
-+      memset(ent, 0, sizeof(*ent));
-+      ent->port = fwd_entry & ARLTBL_DATA_PORT_ID_MASK_89;
-+      ent->is_valid = !!(fwd_entry & ARLTBL_VALID_89);
-+      ent->is_age = !!(fwd_entry & ARLTBL_AGE_89);
-+      ent->is_static = !!(fwd_entry & ARLTBL_STATIC_89);
-+      u64_to_ether_addr(mac_vid, ent->mac);
-+      ent->vid = mac_vid >> ARLTBL_VID_S;
-+}
-+
- static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry,
-                                     const struct b53_arl_entry *ent)
- {
-@@ -383,6 +395,20 @@ static inline void b53_arl_from_entry_25
-               *mac_vid |= ARLTBL_AGE_25;
- }
-+static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry,
-+                                       const struct b53_arl_entry *ent)
-+{
-+      *mac_vid = ether_addr_to_u64(ent->mac);
-+      *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK) << ARLTBL_VID_S;
-+      *fwd_entry = ent->port & ARLTBL_DATA_PORT_ID_MASK_89;
-+      if (ent->is_valid)
-+              *fwd_entry |= ARLTBL_VALID_89;
-+      if (ent->is_static)
-+              *fwd_entry |= ARLTBL_STATIC_89;
-+      if (ent->is_age)
-+              *fwd_entry |= ARLTBL_AGE_89;
-+}
-+
- static inline void b53_arl_read_entry(struct b53_device *dev,
-                                     struct b53_arl_entry *ent, u8 idx)
- {
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -342,12 +342,20 @@
- #define   ARLTBL_STATIC                       BIT(15)
- #define   ARLTBL_VALID                        BIT(16)
-+/* BCM5389 ARL Table Data Entry N Register format (16 bit) */
-+#define   ARLTBL_DATA_PORT_ID_MASK_89 GENMASK(8, 0)
-+#define   ARLTBL_TC_MASK_89           GENMASK(12, 10)
-+#define   ARLTBL_AGE_89                       BIT(13)
-+#define   ARLTBL_STATIC_89            BIT(14)
-+#define   ARLTBL_VALID_89             BIT(15)
-+
- /* Maximum number of bin entries in the ARL for all switches */
- #define B53_ARLTBL_MAX_BIN_ENTRIES    4
- /* ARL Search Control Register (8 bit) */
- #define B53_ARL_SRCH_CTL              0x50
- #define B53_ARL_SRCH_CTL_25           0x20
-+#define B53_ARL_SRCH_CTL_89           0x30
- #define   ARL_SRCH_VLID                       BIT(0)
- #define   ARL_SRCH_STDN                       BIT(7)
-@@ -355,10 +363,12 @@
- #define B53_ARL_SRCH_ADDR             0x51
- #define B53_ARL_SRCH_ADDR_25          0x22
- #define B53_ARL_SRCH_ADDR_65          0x24
-+#define B53_ARL_SRCH_ADDR_89          0x31
- #define  ARL_ADDR_MASK                        GENMASK(14, 0)
- /* ARL Search MAC/VID Result (64 bit) */
- #define B53_ARL_SRCH_RSTL_0_MACVID    0x60
-+#define B53_ARL_SRCH_RSLT_MACVID_89   0x33
- /* Single register search result on 5325 */
- #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24
-@@ -368,6 +378,9 @@
- /* ARL Search Data Result (32 bit) */
- #define B53_ARL_SRCH_RSTL_0           0x68
-+/* BCM5389 ARL Search Data Result (16 bit) */
-+#define B53_ARL_SRCH_RSLT_89          0x3b
-+
- #define B53_ARL_SRCH_RSTL_MACVID(x)   (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10))
- #define B53_ARL_SRCH_RSTL(x)          (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10))
diff --git a/target/linux/generic/backport-6.18/612-08-v6.19-net-dsa-b53-add-support-for-bcm63xx-ARL-entry-format.patch b/target/linux/generic/backport-6.18/612-08-v6.19-net-dsa-b53-add-support-for-bcm63xx-ARL-entry-format.patch
deleted file mode 100644 (file)
index ec0e85e..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-From 2b3013ac03028a2364d8779719bb6bfbc0212435 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 7 Nov 2025 09:07:49 +0100
-Subject: [PATCH] net: dsa: b53: add support for bcm63xx ARL entry format
-
-The ARL registers of BCM63XX embedded switches are somewhat unique. The
-normal ARL table access registers have the same format as BCM5389, but
-the ARL search registers differ:
-
-* SRCH_CTL is at the same offset of BCM5389, but 16 bits wide. It does
-  not have more fields, just needs to be accessed by a 16 bit read.
-* SRCH_RSLT_MACVID and SRCH_RSLT are aligned to 32 bit, and have shifted
-  offsets.
-* SRCH_RSLT has a different format than the normal ARL data entry
-  register.
-* There is only one set of ENTRY_N registers, implying a 1 bin layout.
-
-So add appropriate ops for bcm63xx and let it use it.
-
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251107080749.26936-9-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 44 +++++++++++++++++++++++++++-----
- drivers/net/dsa/b53/b53_priv.h   | 15 +++++++++++
- drivers/net/dsa/b53/b53_regs.h   |  9 +++++++
- 3 files changed, 61 insertions(+), 7 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2038,12 +2038,20 @@ static void b53_read_arl_srch_ctl(struct
-       if (is5325(dev) || is5365(dev))
-               offset = B53_ARL_SRCH_CTL_25;
--      else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev))
-+      else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) ||
-+               is63xx(dev))
-               offset = B53_ARL_SRCH_CTL_89;
-       else
-               offset = B53_ARL_SRCH_CTL;
--      b53_read8(dev, B53_ARLIO_PAGE, offset, val);
-+      if (is63xx(dev)) {
-+              u16 val16;
-+
-+              b53_read16(dev, B53_ARLIO_PAGE, offset, &val16);
-+              *val = val16 & 0xff;
-+      } else {
-+              b53_read8(dev, B53_ARLIO_PAGE, offset, val);
-+      }
- }
- static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val)
-@@ -2052,12 +2060,16 @@ static void b53_write_arl_srch_ctl(struc
-       if (is5325(dev) || is5365(dev))
-               offset = B53_ARL_SRCH_CTL_25;
--      else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev))
-+      else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) ||
-+               is63xx(dev))
-               offset = B53_ARL_SRCH_CTL_89;
-       else
-               offset = B53_ARL_SRCH_CTL;
--      b53_write8(dev, B53_ARLIO_PAGE, offset, val);
-+      if (is63xx(dev))
-+              b53_write16(dev, B53_ARLIO_PAGE, offset, val);
-+      else
-+              b53_write8(dev, B53_ARLIO_PAGE, offset, val);
- }
- static int b53_arl_search_wait(struct b53_device *dev)
-@@ -2111,6 +2123,18 @@ static void b53_arl_search_read_89(struc
-       b53_arl_to_entry_89(ent, mac_vid, fwd_entry);
- }
-+static void b53_arl_search_read_63xx(struct b53_device *dev, u8 idx,
-+                                   struct b53_arl_entry *ent)
-+{
-+      u16 fwd_entry;
-+      u64 mac_vid;
-+
-+      b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_MACVID_63XX,
-+                 &mac_vid);
-+      b53_read16(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_63XX, &fwd_entry);
-+      b53_arl_search_to_entry_63xx(ent, mac_vid, fwd_entry);
-+}
-+
- static void b53_arl_search_read_95(struct b53_device *dev, u8 idx,
-                                  struct b53_arl_entry *ent)
- {
-@@ -2717,6 +2741,12 @@ static const struct b53_arl_ops b53_arl_
-       .arl_search_read = b53_arl_search_read_89,
- };
-+static const struct b53_arl_ops b53_arl_ops_63xx = {
-+      .arl_read_entry = b53_arl_read_entry_89,
-+      .arl_write_entry = b53_arl_write_entry_89,
-+      .arl_search_read = b53_arl_search_read_63xx,
-+};
-+
- static const struct b53_arl_ops b53_arl_ops_95 = {
-       .arl_read_entry = b53_arl_read_entry_95,
-       .arl_write_entry = b53_arl_write_entry_95,
-@@ -2886,14 +2916,14 @@ static const struct b53_chip_data b53_sw
-               .dev_name = "BCM63xx",
-               .vlans = 4096,
-               .enabled_ports = 0, /* pdata must provide them */
--              .arl_bins = 4,
--              .arl_buckets = 1024,
-+              .arl_bins = 1,
-+              .arl_buckets = 4096,
-               .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,
--              .arl_ops = &b53_arl_ops_95,
-+              .arl_ops = &b53_arl_ops_63xx,
-       },
-       {
-               .chip_id = BCM53010_DEVICE_ID,
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -409,6 +409,21 @@ static inline void b53_arl_from_entry_89
-               *fwd_entry |= ARLTBL_AGE_89;
- }
-+static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent,
-+                                              u64 mac_vid, u16 fwd_entry)
-+{
-+      memset(ent, 0, sizeof(*ent));
-+      u64_to_ether_addr(mac_vid, ent->mac);
-+      ent->vid = mac_vid >> ARLTBL_VID_S;
-+
-+      ent->port = fwd_entry & ARL_SRST_PORT_ID_MASK_63XX;
-+      ent->port >>= 1;
-+
-+      ent->is_age = !!(fwd_entry & ARL_SRST_AGE_63XX);
-+      ent->is_static = !!(fwd_entry & ARL_SRST_STATIC_63XX);
-+      ent->is_valid = 1;
-+}
-+
- static inline void b53_arl_read_entry(struct b53_device *dev,
-                                     struct b53_arl_entry *ent, u8 idx)
- {
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -364,11 +364,13 @@
- #define B53_ARL_SRCH_ADDR_25          0x22
- #define B53_ARL_SRCH_ADDR_65          0x24
- #define B53_ARL_SRCH_ADDR_89          0x31
-+#define B53_ARL_SRCH_ADDR_63XX                0x32
- #define  ARL_ADDR_MASK                        GENMASK(14, 0)
- /* ARL Search MAC/VID Result (64 bit) */
- #define B53_ARL_SRCH_RSTL_0_MACVID    0x60
- #define B53_ARL_SRCH_RSLT_MACVID_89   0x33
-+#define B53_ARL_SRCH_RSLT_MACVID_63XX 0x34
- /* Single register search result on 5325 */
- #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24
-@@ -384,6 +386,13 @@
- #define B53_ARL_SRCH_RSTL_MACVID(x)   (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10))
- #define B53_ARL_SRCH_RSTL(x)          (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10))
-+/* 63XX ARL Search Data Result (16 bit) */
-+#define B53_ARL_SRCH_RSLT_63XX                0x3c
-+#define   ARL_SRST_PORT_ID_MASK_63XX  GENMASK(9, 1)
-+#define   ARL_SRST_TC_MASK_63XX               GENMASK(13, 11)
-+#define   ARL_SRST_AGE_63XX           BIT(14)
-+#define   ARL_SRST_STATIC_63XX                BIT(15)
-+
- /*************************************************************************
-  * IEEE 802.1X Registers
-  *************************************************************************/
diff --git a/target/linux/generic/backport-6.18/613-01-v6.19-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch b/target/linux/generic/backport-6.18/613-01-v6.19-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch
deleted file mode 100644 (file)
index d953ea7..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-From 6f268e275c74dae0536e0b61982a8db25bcf4f16 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 28 Nov 2025 09:06:19 +0100
-Subject: [PATCH] net: dsa: b53: fix VLAN_ID_IDX write size for BCM5325/65
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Since BCM5325 and BCM5365 only support up to 256 VLANs, the VLAN_ID_IDX
-register is only 8 bit wide, not 16 bit, so use an appropriate accessor.
-
-Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Tested-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Link: https://patch.msgid.link/20251128080625.27181-2-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1946,8 +1946,12 @@ static int b53_arl_op(struct b53_device
-       /* Perform a read for the given MAC and VID */
-       b53_write48(dev, B53_ARLIO_PAGE, B53_MAC_ADDR_IDX, mac);
--      if (!is5325m(dev))
--              b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
-+      if (!is5325m(dev)) {
-+              if (is5325(dev) || is5365(dev))
-+                      b53_write8(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
-+              else
-+                      b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
-+      }
-       /* Issue a read operation for this MAC */
-       ret = b53_arl_rw_op(dev, 1);
diff --git a/target/linux/generic/backport-6.18/613-02-v6.19-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch b/target/linux/generic/backport-6.18/613-02-v6.19-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch
deleted file mode 100644 (file)
index 72f81d0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 9316012dd01952f75e37035360138ccc786ef727 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 28 Nov 2025 09:06:20 +0100
-Subject: [PATCH] net: dsa: b53: fix extracting VID from entry for BCM5325/65
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM5325/65's Entry register uses the highest three bits for
-VALID/STATIC/AGE, so shifting by 53 only will add these to
-b53_arl_entry::vid.
-
-So make sure to mask the vid value as well, to not get invalid VIDs.
-
-Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Tested-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Link: https://patch.msgid.link/20251128080625.27181-3-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_priv.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -350,7 +350,7 @@ static inline void b53_arl_to_entry_25(s
-       ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
-       ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
-       u64_to_ether_addr(mac_vid, ent->mac);
--      ent->vid = mac_vid >> ARLTBL_VID_S_65;
-+      ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
- }
- static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent,
diff --git a/target/linux/generic/backport-6.18/613-03-v6.19-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch b/target/linux/generic/backport-6.18/613-03-v6.19-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch
deleted file mode 100644 (file)
index ddb95df..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-From 8e46aacea4264bcb8d4265fb07577afff58ae78d Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 28 Nov 2025 09:06:21 +0100
-Subject: [PATCH] net: dsa: b53: use same ARL search result offset for BCM5325/65
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM5365's search result is at the same offset as BCM5325's search
-result, and they (mostly) share the same format, so switch BCM5365 to
-BCM5325's arl ops.
-
-Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Tested-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Link: https://patch.msgid.link/20251128080625.27181-4-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 18 +-----------------
- drivers/net/dsa/b53/b53_regs.h   |  4 +---
- 2 files changed, 2 insertions(+), 20 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2105,16 +2105,6 @@ static void b53_arl_search_read_25(struc
-       b53_arl_to_entry_25(ent, mac_vid);
- }
--static void b53_arl_search_read_65(struct b53_device *dev, u8 idx,
--                                 struct b53_arl_entry *ent)
--{
--      u64 mac_vid;
--
--      b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65,
--                 &mac_vid);
--      b53_arl_to_entry_25(ent, mac_vid);
--}
--
- static void b53_arl_search_read_89(struct b53_device *dev, u8 idx,
-                                  struct b53_arl_entry *ent)
- {
-@@ -2733,12 +2723,6 @@ static const struct b53_arl_ops b53_arl_
-       .arl_search_read = b53_arl_search_read_25,
- };
--static const struct b53_arl_ops b53_arl_ops_65 = {
--      .arl_read_entry = b53_arl_read_entry_25,
--      .arl_write_entry = b53_arl_write_entry_25,
--      .arl_search_read = b53_arl_search_read_65,
--};
--
- static const struct b53_arl_ops b53_arl_ops_89 = {
-       .arl_read_entry = b53_arl_read_entry_89,
-       .arl_write_entry = b53_arl_write_entry_89,
-@@ -2801,7 +2785,7 @@ static const struct b53_chip_data b53_sw
-               .arl_buckets = 1024,
-               .imp_port = 5,
-               .duplex_reg = B53_DUPLEX_STAT_FE,
--              .arl_ops = &b53_arl_ops_65,
-+              .arl_ops = &b53_arl_ops_25,
-       },
-       {
-               .chip_id = BCM5389_DEVICE_ID,
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -372,10 +372,8 @@
- #define B53_ARL_SRCH_RSLT_MACVID_89   0x33
- #define B53_ARL_SRCH_RSLT_MACVID_63XX 0x34
--/* Single register search result on 5325 */
-+/* Single register search result on 5325/5365 */
- #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24
--/* Single register search result on 5365 */
--#define B53_ARL_SRCH_RSTL_0_MACVID_65 0x30
- /* ARL Search Data Result (32 bit) */
- #define B53_ARL_SRCH_RSTL_0           0x68
diff --git a/target/linux/generic/backport-6.18/613-04-v6.19-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch b/target/linux/generic/backport-6.18/613-04-v6.19-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch
deleted file mode 100644 (file)
index 3748892..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From 85132103f700b1340fc17df8a981509d17bf4872 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 28 Nov 2025 09:06:22 +0100
-Subject: [PATCH] net: dsa: b53: fix CPU port unicast ARL entries for BCM5325/65
-
-On BCM5325 and BCM5365, unicast ARL entries use 8 as the value for the
-CPU port, so we need to translate it to/from 5 as used for the CPU port
-at most other places.
-
-Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251128080625.27181-5-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_priv.h | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -344,12 +344,14 @@ static inline void b53_arl_to_entry_25(s
-                                      u64 mac_vid)
- {
-       memset(ent, 0, sizeof(*ent));
--      ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) &
--                   ARLTBL_DATA_PORT_ID_MASK_25;
-       ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
-       ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
-       ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
-       u64_to_ether_addr(mac_vid, ent->mac);
-+      ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) &
-+                   ARLTBL_DATA_PORT_ID_MASK_25;
-+      if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
-+              ent->port = B53_CPU_PORT_25;
-       ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
- }
-@@ -383,8 +385,11 @@ static inline void b53_arl_from_entry_25
-                                        const struct b53_arl_entry *ent)
- {
-       *mac_vid = ether_addr_to_u64(ent->mac);
--      *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) <<
--                        ARLTBL_DATA_PORT_ID_S_25;
-+      if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25)
-+              *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25;
-+      else
-+              *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) <<
-+                                ARLTBL_DATA_PORT_ID_S_25;
-       *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) <<
-                         ARLTBL_VID_S_65;
-       if (ent->is_valid)
diff --git a/target/linux/generic/backport-6.18/613-05-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch b/target/linux/generic/backport-6.18/613-05-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch
deleted file mode 100644 (file)
index c0f5b5d..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-From 3b08863469aa6028ac7c3120966f4e2f6051cf6b Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 28 Nov 2025 09:06:23 +0100
-Subject: [PATCH] net: dsa: b53: fix BCM5325/65 ARL entry multicast port masks
-
-We currently use the mask 0xf for writing and reading b53_entry::port,
-but this is only correct for unicast ARL entries. Multicast ARL entries
-use a bitmask, and 0xf is not enough space for ports > 3, which includes
-the CPU port.
-
-So extend the mask accordingly to also fit port 4 (bit 4) and MII (bit
-5). According to the datasheet the multicast port mask is [60:48],
-making it 12 bit wide, but bits 60-55 are reserved anyway, and collide
-with the priority field at [60:59], so I am not sure if this is valid.
-Therefore leave it at the actual used range, [53:48].
-
-The ARL search result register differs a bit, and there the mask is only
-[52:48], so only spanning the user ports. The MII port bit is
-contained in the Search Result Extension register. So create a separate
-search result parse function that properly handles this.
-
-Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Link: https://patch.msgid.link/20251128080625.27181-6-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c |  4 +++-
- drivers/net/dsa/b53/b53_priv.h   | 25 +++++++++++++++++++++----
- drivers/net/dsa/b53/b53_regs.h   |  8 +++++++-
- 3 files changed, 31 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2099,10 +2099,12 @@ static void b53_arl_search_read_25(struc
-                                  struct b53_arl_entry *ent)
- {
-       u64 mac_vid;
-+      u8 ext;
-+      b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_EXT_25, &ext);
-       b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
-                  &mac_vid);
--      b53_arl_to_entry_25(ent, mac_vid);
-+      b53_arl_search_to_entry_25(ent, mac_vid, ext);
- }
- static void b53_arl_search_read_89(struct b53_device *dev, u8 idx,
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -348,8 +348,8 @@ static inline void b53_arl_to_entry_25(s
-       ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
-       ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
-       u64_to_ether_addr(mac_vid, ent->mac);
--      ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) &
--                   ARLTBL_DATA_PORT_ID_MASK_25;
-+      ent->port = (mac_vid & ARLTBL_DATA_PORT_ID_MASK_25) >>
-+                   ARLTBL_DATA_PORT_ID_S_25;
-       if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
-               ent->port = B53_CPU_PORT_25;
-       ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
-@@ -388,8 +388,8 @@ static inline void b53_arl_from_entry_25
-       if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25)
-               *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25;
-       else
--              *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) <<
--                                ARLTBL_DATA_PORT_ID_S_25;
-+              *mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) &
-+                          ARLTBL_DATA_PORT_ID_MASK_25;
-       *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) <<
-                         ARLTBL_VID_S_65;
-       if (ent->is_valid)
-@@ -414,6 +414,23 @@ static inline void b53_arl_from_entry_89
-               *fwd_entry |= ARLTBL_AGE_89;
- }
-+static inline void b53_arl_search_to_entry_25(struct b53_arl_entry *ent,
-+                                            u64 mac_vid, u8 ext)
-+{
-+      memset(ent, 0, sizeof(*ent));
-+      ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
-+      ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
-+      ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
-+      u64_to_ether_addr(mac_vid, ent->mac);
-+      ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
-+      ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >>
-+                  ARL_SRCH_RSLT_PORT_ID_S_25;
-+      if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII))
-+              ent->port |= BIT(B53_CPU_PORT_25);
-+      else if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
-+              ent->port = B53_CPU_PORT_25;
-+}
-+
- static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent,
-                                               u64 mac_vid, u16 fwd_entry)
- {
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -328,7 +328,7 @@
- #define   ARLTBL_VID_MASK_25          0xff
- #define   ARLTBL_VID_MASK             0xfff
- #define   ARLTBL_DATA_PORT_ID_S_25    48
--#define   ARLTBL_DATA_PORT_ID_MASK_25 0xf
-+#define   ARLTBL_DATA_PORT_ID_MASK_25 GENMASK_ULL(53, 48)
- #define   ARLTBL_VID_S_65             53
- #define   ARLTBL_AGE_25                       BIT_ULL(61)
- #define   ARLTBL_STATIC_25            BIT_ULL(62)
-@@ -374,6 +374,12 @@
- /* Single register search result on 5325/5365 */
- #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24
-+#define   ARL_SRCH_RSLT_PORT_ID_S_25  48
-+#define   ARL_SRCH_RSLT_PORT_ID_MASK_25       GENMASK_ULL(52, 48)
-+
-+/* BCM5325/5365 Search result extend register (8 bit) */
-+#define B53_ARL_SRCH_RSLT_EXT_25      0x2c
-+#define   ARL_SRCH_RSLT_EXT_MC_MII    BIT(2)
- /* ARL Search Data Result (32 bit) */
- #define B53_ARL_SRCH_RSTL_0           0x68
diff --git a/target/linux/generic/backport-6.18/613-06-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch b/target/linux/generic/backport-6.18/613-06-v6.19-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch
deleted file mode 100644 (file)
index a2025f9..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-From d39514e6a2d14f57830d649e2bf03b49612c2f73 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@gmail.com>
-Date: Fri, 28 Nov 2025 09:06:24 +0100
-Subject: [PATCH] net: dsa: b53: fix BCM5325/65 ARL entry VIDs
-
-BCM5325/65's ARL entry registers do not contain the VID, only the search
-result register does. ARL entries have a separate VID entry register for
-the index into the VLAN table.
-
-So make ARL entry accessors use the VID entry registers instead, and
-move the VLAN ID field definition to the search register definition.
-
-Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
-Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Link: https://patch.msgid.link/20251128080625.27181-7-jonas.gorski@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c |  9 +++++++--
- drivers/net/dsa/b53/b53_priv.h   | 12 ++++++------
- drivers/net/dsa/b53/b53_regs.h   |  7 +++++--
- 3 files changed, 18 insertions(+), 10 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1833,19 +1833,24 @@ static int b53_arl_rw_op(struct b53_devi
- static void b53_arl_read_entry_25(struct b53_device *dev,
-                                 struct b53_arl_entry *ent, u8 idx)
- {
-+      u8 vid_entry;
-       u64 mac_vid;
-+      b53_read8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx),
-+                &vid_entry);
-       b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
-                  &mac_vid);
--      b53_arl_to_entry_25(ent, mac_vid);
-+      b53_arl_to_entry_25(ent, mac_vid, vid_entry);
- }
- static void b53_arl_write_entry_25(struct b53_device *dev,
-                                  const struct b53_arl_entry *ent, u8 idx)
- {
-+      u8 vid_entry;
-       u64 mac_vid;
--      b53_arl_from_entry_25(&mac_vid, ent);
-+      b53_arl_from_entry_25(&mac_vid, &vid_entry, ent);
-+      b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), vid_entry);
-       b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
-                   mac_vid);
- }
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -341,7 +341,7 @@ static inline void b53_arl_to_entry(stru
- }
- static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent,
--                                     u64 mac_vid)
-+                                     u64 mac_vid, u8 vid_entry)
- {
-       memset(ent, 0, sizeof(*ent));
-       ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
-@@ -352,7 +352,7 @@ static inline void b53_arl_to_entry_25(s
-                    ARLTBL_DATA_PORT_ID_S_25;
-       if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
-               ent->port = B53_CPU_PORT_25;
--      ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
-+      ent->vid = vid_entry;
- }
- static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent,
-@@ -381,7 +381,7 @@ static inline void b53_arl_from_entry(u6
-               *fwd_entry |= ARLTBL_AGE;
- }
--static inline void b53_arl_from_entry_25(u64 *mac_vid,
-+static inline void b53_arl_from_entry_25(u64 *mac_vid, u8 *vid_entry,
-                                        const struct b53_arl_entry *ent)
- {
-       *mac_vid = ether_addr_to_u64(ent->mac);
-@@ -390,14 +390,13 @@ static inline void b53_arl_from_entry_25
-       else
-               *mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) &
-                           ARLTBL_DATA_PORT_ID_MASK_25;
--      *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) <<
--                        ARLTBL_VID_S_65;
-       if (ent->is_valid)
-               *mac_vid |= ARLTBL_VALID_25;
-       if (ent->is_static)
-               *mac_vid |= ARLTBL_STATIC_25;
-       if (ent->is_age)
-               *mac_vid |= ARLTBL_AGE_25;
-+      *vid_entry = ent->vid;
- }
- static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry,
-@@ -422,7 +421,8 @@ static inline void b53_arl_search_to_ent
-       ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
-       ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
-       u64_to_ether_addr(mac_vid, ent->mac);
--      ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
-+      ent->vid = (mac_vid & ARL_SRCH_RSLT_VID_MASK_25) >>
-+                 ARL_SRCH_RSLT_VID_S_25;
-       ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >>
-                   ARL_SRCH_RSLT_PORT_ID_S_25;
-       if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII))
---- a/drivers/net/dsa/b53/b53_regs.h
-+++ b/drivers/net/dsa/b53/b53_regs.h
-@@ -325,11 +325,9 @@
- #define B53_ARLTBL_MAC_VID_ENTRY(n)   ((0x10 * (n)) + 0x10)
- #define   ARLTBL_MAC_MASK             0xffffffffffffULL
- #define   ARLTBL_VID_S                        48
--#define   ARLTBL_VID_MASK_25          0xff
- #define   ARLTBL_VID_MASK             0xfff
- #define   ARLTBL_DATA_PORT_ID_S_25    48
- #define   ARLTBL_DATA_PORT_ID_MASK_25 GENMASK_ULL(53, 48)
--#define   ARLTBL_VID_S_65             53
- #define   ARLTBL_AGE_25                       BIT_ULL(61)
- #define   ARLTBL_STATIC_25            BIT_ULL(62)
- #define   ARLTBL_VALID_25             BIT_ULL(63)
-@@ -349,6 +347,9 @@
- #define   ARLTBL_STATIC_89            BIT(14)
- #define   ARLTBL_VALID_89             BIT(15)
-+/* BCM5325/BCM565 ARL Table VID Entry N Registers (8 bit) */
-+#define B53_ARLTBL_VID_ENTRY_25(n)    ((0x2 * (n)) + 0x30)
-+
- /* Maximum number of bin entries in the ARL for all switches */
- #define B53_ARLTBL_MAX_BIN_ENTRIES    4
-@@ -376,6 +377,8 @@
- #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24
- #define   ARL_SRCH_RSLT_PORT_ID_S_25  48
- #define   ARL_SRCH_RSLT_PORT_ID_MASK_25       GENMASK_ULL(52, 48)
-+#define   ARL_SRCH_RSLT_VID_S_25      53
-+#define   ARL_SRCH_RSLT_VID_MASK_25   GENMASK_ULL(60, 53)
- /* BCM5325/5365 Search result extend register (8 bit) */
- #define B53_ARL_SRCH_RSLT_EXT_25      0x2c
diff --git a/target/linux/generic/backport-6.18/620-v6.15-ppp-use-IFF_NO_QUEUE-in-virtual-interfaces.patch b/target/linux/generic/backport-6.18/620-v6.15-ppp-use-IFF_NO_QUEUE-in-virtual-interfaces.patch
deleted file mode 100644 (file)
index 333627a..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From: Qingfang Deng <dqfext@gmail.com>
-Date: Sat, 1 Mar 2025 21:55:16 +0800
-Subject: [PATCH] ppp: use IFF_NO_QUEUE in virtual interfaces
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-For PPPoE, PPTP, and PPPoL2TP, the start_xmit() function directly
-forwards packets to the underlying network stack and never returns
-anything other than 1. So these interfaces do not require a qdisc,
-and the IFF_NO_QUEUE flag should be set.
-
-Introduces a direct_xmit flag in struct ppp_channel to indicate when
-IFF_NO_QUEUE should be applied. The flag is set in ppp_connect_channel()
-for relevant protocols.
-
-While at it, remove the usused latency member from struct ppp_channel.
-
-Signed-off-by: Qingfang Deng <dqfext@gmail.com>
-Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
-Link: https://patch.msgid.link/20250301135517.695809-1-dqfext@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ppp/ppp_generic.c
-+++ b/drivers/net/ppp/ppp_generic.c
-@@ -3504,6 +3504,10 @@ ppp_connect_channel(struct channel *pch,
-               ret = -ENOTCONN;
-               goto outl;
-       }
-+      if (pch->chan->direct_xmit)
-+              ppp->dev->priv_flags |= IFF_NO_QUEUE;
-+      else
-+              ppp->dev->priv_flags &= ~IFF_NO_QUEUE;
-       spin_unlock_bh(&pch->downl);
-       if (pch->file.hdrlen > ppp->file.hdrlen)
-               ppp->file.hdrlen = pch->file.hdrlen;
---- a/drivers/net/ppp/pppoe.c
-+++ b/drivers/net/ppp/pppoe.c
-@@ -693,6 +693,7 @@ static int pppoe_connect(struct socket *
-               po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2;
-               po->chan.private = sk;
-               po->chan.ops = &pppoe_chan_ops;
-+              po->chan.direct_xmit = true;
-               error = ppp_register_net_channel(dev_net(dev), &po->chan);
-               if (error) {
---- a/drivers/net/ppp/pptp.c
-+++ b/drivers/net/ppp/pptp.c
-@@ -469,6 +469,7 @@ static int pptp_connect(struct socket *s
-       po->chan.mtu -= PPTP_HEADER_OVERHEAD;
-       po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header);
-+      po->chan.direct_xmit = true;
-       error = ppp_register_channel(&po->chan);
-       if (error) {
-               pr_err("PPTP: failed to register PPP channel (%d)\n", error);
---- a/include/linux/ppp_channel.h
-+++ b/include/linux/ppp_channel.h
-@@ -42,8 +42,7 @@ struct ppp_channel {
-       int             hdrlen;         /* amount of headroom channel needs */
-       void            *ppp;           /* opaque to channel */
-       int             speed;          /* transfer rate (bytes/second) */
--      /* the following is not used at present */
--      int             latency;        /* overhead time in milliseconds */
-+      bool            direct_xmit;    /* no qdisc, xmit directly */
- };
- #ifdef __KERNEL__
---- a/net/l2tp/l2tp_ppp.c
-+++ b/net/l2tp/l2tp_ppp.c
-@@ -796,6 +796,7 @@ static int pppol2tp_connect(struct socke
-       po->chan.private = sk;
-       po->chan.ops     = &pppol2tp_chan_ops;
-       po->chan.mtu     = pppol2tp_tunnel_mtu(tunnel);
-+      po->chan.direct_xmit    = true;
-       error = ppp_register_net_channel(sock_net(sk), &po->chan);
-       if (error) {
diff --git a/target/linux/generic/backport-6.18/621-v6.17-ppp-convert-to-percpu-netstats.patch b/target/linux/generic/backport-6.18/621-v6.17-ppp-convert-to-percpu-netstats.patch
deleted file mode 100644 (file)
index 874d2bf..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-From 1a3e9b7a6b09e8ab3d2af019e4a392622685855e Mon Sep 17 00:00:00 2001
-From: Qingfang Deng <dqfext@gmail.com>
-Date: Tue, 10 Jun 2025 16:32:10 +0800
-Subject: [PATCH] ppp: convert to percpu netstats
-
-Convert to percpu netstats to avoid lock contention when reading them.
-
-Signed-off-by: Qingfang Deng <dqfext@gmail.com>
-Link: https://patch.msgid.link/20250610083211.909015-1-dqfext@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ppp/ppp_generic.c | 52 +++++++++++++----------------------
- 1 file changed, 19 insertions(+), 33 deletions(-)
-
---- a/drivers/net/ppp/ppp_generic.c
-+++ b/drivers/net/ppp/ppp_generic.c
-@@ -108,18 +108,6 @@ struct ppp_file {
- #define PF_TO_CHANNEL(pf)     PF_TO_X(pf, struct channel)
- /*
-- * Data structure to hold primary network stats for which
-- * we want to use 64 bit storage.  Other network stats
-- * are stored in dev->stats of the ppp strucute.
-- */
--struct ppp_link_stats {
--      u64 rx_packets;
--      u64 tx_packets;
--      u64 rx_bytes;
--      u64 tx_bytes;
--};
--
--/*
-  * Data structure describing one ppp unit.
-  * A ppp unit corresponds to a ppp network interface device
-  * and represents a multilink bundle.
-@@ -162,7 +150,6 @@ struct ppp {
-       struct bpf_prog *active_filter; /* filter for pkts to reset idle */
- #endif /* CONFIG_PPP_FILTER */
-       struct net      *ppp_net;       /* the net we belong to */
--      struct ppp_link_stats stats64;  /* 64 bit network stats */
- };
- /*
-@@ -1541,23 +1528,12 @@ ppp_net_siocdevprivate(struct net_device
- static void
- ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64)
- {
--      struct ppp *ppp = netdev_priv(dev);
--
--      ppp_recv_lock(ppp);
--      stats64->rx_packets = ppp->stats64.rx_packets;
--      stats64->rx_bytes   = ppp->stats64.rx_bytes;
--      ppp_recv_unlock(ppp);
--
--      ppp_xmit_lock(ppp);
--      stats64->tx_packets = ppp->stats64.tx_packets;
--      stats64->tx_bytes   = ppp->stats64.tx_bytes;
--      ppp_xmit_unlock(ppp);
--
-       stats64->rx_errors        = dev->stats.rx_errors;
-       stats64->tx_errors        = dev->stats.tx_errors;
-       stats64->rx_dropped       = dev->stats.rx_dropped;
-       stats64->tx_dropped       = dev->stats.tx_dropped;
-       stats64->rx_length_errors = dev->stats.rx_length_errors;
-+      dev_fetch_sw_netstats(stats64, dev->tstats);
- }
- static int ppp_dev_init(struct net_device *dev)
-@@ -1655,6 +1631,7 @@ static void ppp_setup(struct net_device
-       dev->type = ARPHRD_PPP;
-       dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-       dev->priv_destructor = ppp_dev_priv_destructor;
-+      dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
-       netif_keep_dst(dev);
- }
-@@ -1800,8 +1777,7 @@ ppp_send_frame(struct ppp *ppp, struct s
- #endif /* CONFIG_PPP_FILTER */
-       }
--      ++ppp->stats64.tx_packets;
--      ppp->stats64.tx_bytes += skb->len - PPP_PROTO_LEN;
-+      dev_sw_netstats_tx_add(ppp->dev, 1, skb->len - PPP_PROTO_LEN);
-       switch (proto) {
-       case PPP_IP:
-@@ -2479,8 +2455,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp,
-               break;
-       }
--      ++ppp->stats64.rx_packets;
--      ppp->stats64.rx_bytes += skb->len - 2;
-+      dev_sw_netstats_rx_add(ppp->dev, skb->len - PPP_PROTO_LEN);
-       npi = proto_to_npindex(proto);
-       if (npi < 0) {
-@@ -3308,14 +3283,25 @@ static void
- ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
- {
-       struct slcompress *vj = ppp->vj;
-+      int cpu;
-       memset(st, 0, sizeof(*st));
--      st->p.ppp_ipackets = ppp->stats64.rx_packets;
-+      for_each_possible_cpu(cpu) {
-+              struct pcpu_sw_netstats *p = per_cpu_ptr(ppp->dev->tstats, cpu);
-+              u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
-+
-+              rx_packets = u64_stats_read(&p->rx_packets);
-+              rx_bytes = u64_stats_read(&p->rx_bytes);
-+              tx_packets = u64_stats_read(&p->tx_packets);
-+              tx_bytes = u64_stats_read(&p->tx_bytes);
-+
-+              st->p.ppp_ipackets += rx_packets;
-+              st->p.ppp_ibytes += rx_bytes;
-+              st->p.ppp_opackets += tx_packets;
-+              st->p.ppp_obytes += tx_bytes;
-+      }
-       st->p.ppp_ierrors = ppp->dev->stats.rx_errors;
--      st->p.ppp_ibytes = ppp->stats64.rx_bytes;
--      st->p.ppp_opackets = ppp->stats64.tx_packets;
-       st->p.ppp_oerrors = ppp->dev->stats.tx_errors;
--      st->p.ppp_obytes = ppp->stats64.tx_bytes;
-       if (!vj)
-               return;
-       st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed;
diff --git a/target/linux/generic/backport-6.18/622-v6.18-ppp-remove-rwlock-usage.patch b/target/linux/generic/backport-6.18/622-v6.18-ppp-remove-rwlock-usage.patch
deleted file mode 100644 (file)
index f66a522..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-From b8844aab519a154808dbce15a132f3e8f1c34af6 Mon Sep 17 00:00:00 2001
-From: Qingfang Deng <dqfext@gmail.com>
-Date: Fri, 22 Aug 2025 09:25:47 +0800
-Subject: [PATCH] ppp: remove rwlock usage
-
-In struct channel, the upl lock is implemented using rwlock_t,
-protecting access to pch->ppp and pch->bridge.
-
-As previously discussed on the list, using rwlock in the network fast
-path is not recommended.
-This patch replaces the rwlock with a spinlock for writers, and uses RCU
-for readers.
-
-- pch->ppp and pch->bridge are now declared as __rcu pointers.
-- Readers use rcu_dereference_bh() under rcu_read_lock_bh().
-- Writers use spin_lock() to update.
-
-Signed-off-by: Qingfang Deng <dqfext@gmail.com>
-Link: https://patch.msgid.link/20250822012548.6232-1-dqfext@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ppp/ppp_generic.c | 120 ++++++++++++++++++----------------
- 1 file changed, 63 insertions(+), 57 deletions(-)
-
---- a/drivers/net/ppp/ppp_generic.c
-+++ b/drivers/net/ppp/ppp_generic.c
-@@ -173,11 +173,11 @@ struct channel {
-       struct ppp_channel *chan;       /* public channel data structure */
-       struct rw_semaphore chan_sem;   /* protects `chan' during chan ioctl */
-       spinlock_t      downl;          /* protects `chan', file.xq dequeue */
--      struct ppp      *ppp;           /* ppp unit we're connected to */
-+      struct ppp __rcu *ppp;          /* ppp unit we're connected to */
-       struct net      *chan_net;      /* the net channel belongs to */
-       netns_tracker   ns_tracker;
-       struct list_head clist;         /* link in list of channels per unit */
--      rwlock_t        upl;            /* protects `ppp' and 'bridge' */
-+      spinlock_t      upl;            /* protects `ppp' and 'bridge' */
-       struct channel __rcu *bridge;   /* "bridged" ppp channel */
- #ifdef CONFIG_PPP_MULTILINK
-       u8              avail;          /* flag used in multilink stuff */
-@@ -639,34 +639,34 @@ static struct bpf_prog *compat_ppp_get_f
-  */
- static int ppp_bridge_channels(struct channel *pch, struct channel *pchb)
- {
--      write_lock_bh(&pch->upl);
--      if (pch->ppp ||
-+      spin_lock(&pch->upl);
-+      if (rcu_dereference_protected(pch->ppp, lockdep_is_held(&pch->upl)) ||
-           rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl))) {
--              write_unlock_bh(&pch->upl);
-+              spin_unlock(&pch->upl);
-               return -EALREADY;
-       }
-       refcount_inc(&pchb->file.refcnt);
-       rcu_assign_pointer(pch->bridge, pchb);
--      write_unlock_bh(&pch->upl);
-+      spin_unlock(&pch->upl);
--      write_lock_bh(&pchb->upl);
--      if (pchb->ppp ||
-+      spin_lock(&pchb->upl);
-+      if (rcu_dereference_protected(pchb->ppp, lockdep_is_held(&pchb->upl)) ||
-           rcu_dereference_protected(pchb->bridge, lockdep_is_held(&pchb->upl))) {
--              write_unlock_bh(&pchb->upl);
-+              spin_unlock(&pchb->upl);
-               goto err_unset;
-       }
-       refcount_inc(&pch->file.refcnt);
-       rcu_assign_pointer(pchb->bridge, pch);
--      write_unlock_bh(&pchb->upl);
-+      spin_unlock(&pchb->upl);
-       return 0;
- err_unset:
--      write_lock_bh(&pch->upl);
-+      spin_lock(&pch->upl);
-       /* Re-read pch->bridge with upl held in case it was modified concurrently */
-       pchb = rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl));
-       RCU_INIT_POINTER(pch->bridge, NULL);
--      write_unlock_bh(&pch->upl);
-+      spin_unlock(&pch->upl);
-       synchronize_rcu();
-       if (pchb)
-@@ -680,25 +680,25 @@ static int ppp_unbridge_channels(struct
- {
-       struct channel *pchb, *pchbb;
--      write_lock_bh(&pch->upl);
-+      spin_lock(&pch->upl);
-       pchb = rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl));
-       if (!pchb) {
--              write_unlock_bh(&pch->upl);
-+              spin_unlock(&pch->upl);
-               return -EINVAL;
-       }
-       RCU_INIT_POINTER(pch->bridge, NULL);
--      write_unlock_bh(&pch->upl);
-+      spin_unlock(&pch->upl);
-       /* Only modify pchb if phcb->bridge points back to pch.
-        * If not, it implies that there has been a race unbridging (and possibly
-        * even rebridging) pchb.  We should leave pchb alone to avoid either a
-        * refcount underflow, or breaking another established bridge instance.
-        */
--      write_lock_bh(&pchb->upl);
-+      spin_lock(&pchb->upl);
-       pchbb = rcu_dereference_protected(pchb->bridge, lockdep_is_held(&pchb->upl));
-       if (pchbb == pch)
-               RCU_INIT_POINTER(pchb->bridge, NULL);
--      write_unlock_bh(&pchb->upl);
-+      spin_unlock(&pchb->upl);
-       synchronize_rcu();
-@@ -2144,10 +2144,9 @@ static int ppp_mp_explode(struct ppp *pp
- #endif /* CONFIG_PPP_MULTILINK */
- /* Try to send data out on a channel */
--static void __ppp_channel_push(struct channel *pch)
-+static void __ppp_channel_push(struct channel *pch, struct ppp *ppp)
- {
-       struct sk_buff *skb;
--      struct ppp *ppp;
-       spin_lock(&pch->downl);
-       if (pch->chan) {
-@@ -2166,7 +2165,6 @@ static void __ppp_channel_push(struct ch
-       spin_unlock(&pch->downl);
-       /* see if there is anything from the attached unit to be sent */
-       if (skb_queue_empty(&pch->file.xq)) {
--              ppp = pch->ppp;
-               if (ppp)
-                       __ppp_xmit_process(ppp, NULL);
-       }
-@@ -2174,15 +2172,18 @@ static void __ppp_channel_push(struct ch
- static void ppp_channel_push(struct channel *pch)
- {
--      read_lock_bh(&pch->upl);
--      if (pch->ppp) {
--              (*this_cpu_ptr(pch->ppp->xmit_recursion))++;
--              __ppp_channel_push(pch);
--              (*this_cpu_ptr(pch->ppp->xmit_recursion))--;
-+      struct ppp *ppp;
-+
-+      rcu_read_lock_bh();
-+      ppp = rcu_dereference_bh(pch->ppp);
-+      if (ppp) {
-+              (*this_cpu_ptr(ppp->xmit_recursion))++;
-+              __ppp_channel_push(pch, ppp);
-+              (*this_cpu_ptr(ppp->xmit_recursion))--;
-       } else {
--              __ppp_channel_push(pch);
-+              __ppp_channel_push(pch, NULL);
-       }
--      read_unlock_bh(&pch->upl);
-+      rcu_read_unlock_bh();
- }
- /*
-@@ -2284,6 +2285,7 @@ void
- ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
- {
-       struct channel *pch = chan->ppp;
-+      struct ppp *ppp;
-       int proto;
-       if (!pch) {
-@@ -2295,18 +2297,19 @@ ppp_input(struct ppp_channel *chan, stru
-       if (ppp_channel_bridge_input(pch, skb))
-               return;
--      read_lock_bh(&pch->upl);
-+      rcu_read_lock_bh();
-+      ppp = rcu_dereference_bh(pch->ppp);
-       if (!ppp_decompress_proto(skb)) {
-               kfree_skb(skb);
--              if (pch->ppp) {
--                      ++pch->ppp->dev->stats.rx_length_errors;
--                      ppp_receive_error(pch->ppp);
-+              if (ppp) {
-+                      ++ppp->dev->stats.rx_length_errors;
-+                      ppp_receive_error(ppp);
-               }
-               goto done;
-       }
-       proto = PPP_PROTO(skb);
--      if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
-+      if (!ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
-               /* put it on the channel queue */
-               skb_queue_tail(&pch->file.rq, skb);
-               /* drop old frames if queue too long */
-@@ -2315,11 +2318,11 @@ ppp_input(struct ppp_channel *chan, stru
-                       kfree_skb(skb);
-               wake_up_interruptible(&pch->file.rwait);
-       } else {
--              ppp_do_recv(pch->ppp, skb, pch);
-+              ppp_do_recv(ppp, skb, pch);
-       }
- done:
--      read_unlock_bh(&pch->upl);
-+      rcu_read_unlock_bh();
- }
- /* Put a 0-length skb in the receive queue as an error indication */
-@@ -2328,20 +2331,22 @@ ppp_input_error(struct ppp_channel *chan
- {
-       struct channel *pch = chan->ppp;
-       struct sk_buff *skb;
-+      struct ppp *ppp;
-       if (!pch)
-               return;
--      read_lock_bh(&pch->upl);
--      if (pch->ppp) {
-+      rcu_read_lock_bh();
-+      ppp = rcu_dereference_bh(pch->ppp);
-+      if (ppp) {
-               skb = alloc_skb(0, GFP_ATOMIC);
-               if (skb) {
-                       skb->len = 0;           /* probably unnecessary */
-                       skb->cb[0] = code;
--                      ppp_do_recv(pch->ppp, skb, pch);
-+                      ppp_do_recv(ppp, skb, pch);
-               }
-       }
--      read_unlock_bh(&pch->upl);
-+      rcu_read_unlock_bh();
- }
- /*
-@@ -2889,7 +2894,6 @@ int ppp_register_net_channel(struct net
-       pn = ppp_pernet(net);
--      pch->ppp = NULL;
-       pch->chan = chan;
-       pch->chan_net = get_net_track(net, &pch->ns_tracker, GFP_KERNEL);
-       chan->ppp = pch;
-@@ -2900,7 +2904,7 @@ int ppp_register_net_channel(struct net
- #endif /* CONFIG_PPP_MULTILINK */
-       init_rwsem(&pch->chan_sem);
-       spin_lock_init(&pch->downl);
--      rwlock_init(&pch->upl);
-+      spin_lock_init(&pch->upl);
-       spin_lock_bh(&pn->all_channels_lock);
-       pch->file.index = ++pn->last_channel_index;
-@@ -2929,13 +2933,15 @@ int ppp_channel_index(struct ppp_channel
- int ppp_unit_number(struct ppp_channel *chan)
- {
-       struct channel *pch = chan->ppp;
-+      struct ppp *ppp;
-       int unit = -1;
-       if (pch) {
--              read_lock_bh(&pch->upl);
--              if (pch->ppp)
--                      unit = pch->ppp->file.index;
--              read_unlock_bh(&pch->upl);
-+              rcu_read_lock();
-+              ppp = rcu_dereference(pch->ppp);
-+              if (ppp)
-+                      unit = ppp->file.index;
-+              rcu_read_unlock();
-       }
-       return unit;
- }
-@@ -2947,12 +2953,14 @@ char *ppp_dev_name(struct ppp_channel *c
- {
-       struct channel *pch = chan->ppp;
-       char *name = NULL;
-+      struct ppp *ppp;
-       if (pch) {
--              read_lock_bh(&pch->upl);
--              if (pch->ppp && pch->ppp->dev)
--                      name = pch->ppp->dev->name;
--              read_unlock_bh(&pch->upl);
-+              rcu_read_lock();
-+              ppp = rcu_dereference(pch->ppp);
-+              if (ppp && ppp->dev)
-+                      name = ppp->dev->name;
-+              rcu_read_unlock();
-       }
-       return name;
- }
-@@ -3475,9 +3483,9 @@ ppp_connect_channel(struct channel *pch,
-       ppp = ppp_find_unit(pn, unit);
-       if (!ppp)
-               goto out;
--      write_lock_bh(&pch->upl);
-+      spin_lock(&pch->upl);
-       ret = -EINVAL;
--      if (pch->ppp ||
-+      if (rcu_dereference_protected(pch->ppp, lockdep_is_held(&pch->upl)) ||
-           rcu_dereference_protected(pch->bridge, lockdep_is_held(&pch->upl)))
-               goto outl;
-@@ -3502,13 +3510,13 @@ ppp_connect_channel(struct channel *pch,
-               ppp->dev->hard_header_len = hdrlen;
-       list_add_tail_rcu(&pch->clist, &ppp->channels);
-       ++ppp->n_channels;
--      pch->ppp = ppp;
-+      rcu_assign_pointer(pch->ppp, ppp);
-       refcount_inc(&ppp->file.refcnt);
-       ppp_unlock(ppp);
-       ret = 0;
-  outl:
--      write_unlock_bh(&pch->upl);
-+      spin_unlock(&pch->upl);
-  out:
-       mutex_unlock(&pn->all_ppp_mutex);
-       return ret;
-@@ -3523,10 +3531,9 @@ ppp_disconnect_channel(struct channel *p
-       struct ppp *ppp;
-       int err = -EINVAL;
--      write_lock_bh(&pch->upl);
--      ppp = pch->ppp;
--      pch->ppp = NULL;
--      write_unlock_bh(&pch->upl);
-+      spin_lock(&pch->upl);
-+      ppp = rcu_replace_pointer(pch->ppp, NULL, lockdep_is_held(&pch->upl));
-+      spin_unlock(&pch->upl);
-       if (ppp) {
-               /* remove it from the ppp unit's list */
-               ppp_lock(ppp);
diff --git a/target/linux/generic/backport-6.18/623-v6.18-pppoe-remove-rwlock-usage.patch b/target/linux/generic/backport-6.18/623-v6.18-pppoe-remove-rwlock-usage.patch
deleted file mode 100644 (file)
index 619f1cb..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-From 72cdc67e7fa74931b055df3a76852bab551f1a04 Mon Sep 17 00:00:00 2001
-From: Qingfang Deng <dqfext@gmail.com>
-Date: Thu, 28 Aug 2025 09:20:16 +0800
-Subject: [PATCH] pppoe: remove rwlock usage
-
-Like ppp_generic.c, convert the PPPoE socket hash table to use RCU for
-lookups and a spinlock for updates. This removes rwlock usage and allows
-lockless readers on the fast path.
-
-- Mark hash table and list pointers as __rcu.
-- Use spin_lock() to protect writers.
-- Readers use rcu_dereference() under rcu_read_lock(). All known callers
-  of get_item() already hold the RCU read lock, so no additional locking
-  is needed.
-- get_item() now uses refcount_inc_not_zero() instead of sock_hold() to
-  safely take a reference. This prevents crashes if a socket is already
-  in the process of being freed (sk_refcnt == 0).
-- Set SOCK_RCU_FREE to defer socket freeing until after an RCU grace
-  period.
-- Move skb_queue_purge() into sk_destruct callback to ensure purge
-  happens after an RCU grace period.
-
-Signed-off-by: Qingfang Deng <dqfext@gmail.com>
-Reviewed-by: Eric Dumazet <edumazet@google.com>
-Link: https://patch.msgid.link/20250828012018.15922-1-dqfext@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ppp/pppoe.c  | 94 ++++++++++++++++++++++------------------
- include/linux/if_pppox.h |  2 +-
- 2 files changed, 54 insertions(+), 42 deletions(-)
-
---- a/drivers/net/ppp/pppoe.c
-+++ b/drivers/net/ppp/pppoe.c
-@@ -100,8 +100,8 @@ struct pppoe_net {
-        * as well, moreover in case of SMP less locking
-        * controversy here
-        */
--      struct pppox_sock *hash_table[PPPOE_HASH_SIZE];
--      rwlock_t hash_lock;
-+      struct pppox_sock __rcu *hash_table[PPPOE_HASH_SIZE];
-+      spinlock_t hash_lock;
- };
- /*
-@@ -162,13 +162,13 @@ static struct pppox_sock *__get_item(str
-       int hash = hash_item(sid, addr);
-       struct pppox_sock *ret;
--      ret = pn->hash_table[hash];
-+      ret = rcu_dereference(pn->hash_table[hash]);
-       while (ret) {
-               if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
-                   ret->pppoe_ifindex == ifindex)
-                       return ret;
--              ret = ret->next;
-+              ret = rcu_dereference(ret->next);
-       }
-       return NULL;
-@@ -177,19 +177,20 @@ static struct pppox_sock *__get_item(str
- static int __set_item(struct pppoe_net *pn, struct pppox_sock *po)
- {
-       int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
--      struct pppox_sock *ret;
-+      struct pppox_sock *ret, *first;
--      ret = pn->hash_table[hash];
-+      first = rcu_dereference_protected(pn->hash_table[hash], lockdep_is_held(&pn->hash_lock));
-+      ret = first;
-       while (ret) {
-               if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) &&
-                   ret->pppoe_ifindex == po->pppoe_ifindex)
-                       return -EALREADY;
--              ret = ret->next;
-+              ret = rcu_dereference_protected(ret->next, lockdep_is_held(&pn->hash_lock));
-       }
--      po->next = pn->hash_table[hash];
--      pn->hash_table[hash] = po;
-+      RCU_INIT_POINTER(po->next, first);
-+      rcu_assign_pointer(pn->hash_table[hash], po);
-       return 0;
- }
-@@ -198,20 +199,24 @@ static void __delete_item(struct pppoe_n
-                                       char *addr, int ifindex)
- {
-       int hash = hash_item(sid, addr);
--      struct pppox_sock *ret, **src;
-+      struct pppox_sock *ret, __rcu **src;
--      ret = pn->hash_table[hash];
-+      ret = rcu_dereference_protected(pn->hash_table[hash], lockdep_is_held(&pn->hash_lock));
-       src = &pn->hash_table[hash];
-       while (ret) {
-               if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
-                   ret->pppoe_ifindex == ifindex) {
--                      *src = ret->next;
-+                      struct pppox_sock *next;
-+
-+                      next = rcu_dereference_protected(ret->next,
-+                                                       lockdep_is_held(&pn->hash_lock));
-+                      rcu_assign_pointer(*src, next);
-                       break;
-               }
-               src = &ret->next;
--              ret = ret->next;
-+              ret = rcu_dereference_protected(ret->next, lockdep_is_held(&pn->hash_lock));
-       }
- }
-@@ -225,11 +230,9 @@ static inline struct pppox_sock *get_ite
- {
-       struct pppox_sock *po;
--      read_lock_bh(&pn->hash_lock);
-       po = __get_item(pn, sid, addr, ifindex);
--      if (po)
--              sock_hold(sk_pppox(po));
--      read_unlock_bh(&pn->hash_lock);
-+      if (po && !refcount_inc_not_zero(&sk_pppox(po)->sk_refcnt))
-+              po = NULL;
-       return po;
- }
-@@ -258,9 +261,9 @@ static inline struct pppox_sock *get_ite
- static inline void delete_item(struct pppoe_net *pn, __be16 sid,
-                                       char *addr, int ifindex)
- {
--      write_lock_bh(&pn->hash_lock);
-+      spin_lock(&pn->hash_lock);
-       __delete_item(pn, sid, addr, ifindex);
--      write_unlock_bh(&pn->hash_lock);
-+      spin_unlock(&pn->hash_lock);
- }
- /***************************************************************************
-@@ -276,14 +279,16 @@ static void pppoe_flush_dev(struct net_d
-       int i;
-       pn = pppoe_pernet(dev_net(dev));
--      write_lock_bh(&pn->hash_lock);
-+      spin_lock(&pn->hash_lock);
-       for (i = 0; i < PPPOE_HASH_SIZE; i++) {
--              struct pppox_sock *po = pn->hash_table[i];
-+              struct pppox_sock *po = rcu_dereference_protected(pn->hash_table[i],
-+                                                                lockdep_is_held(&pn->hash_lock));
-               struct sock *sk;
-               while (po) {
-                       while (po && po->pppoe_dev != dev) {
--                              po = po->next;
-+                              po = rcu_dereference_protected(po->next,
-+                                                             lockdep_is_held(&pn->hash_lock));
-                       }
-                       if (!po)
-@@ -300,7 +305,7 @@ static void pppoe_flush_dev(struct net_d
-                        */
-                       sock_hold(sk);
--                      write_unlock_bh(&pn->hash_lock);
-+                      spin_unlock(&pn->hash_lock);
-                       lock_sock(sk);
-                       if (po->pppoe_dev == dev &&
-@@ -320,11 +325,12 @@ static void pppoe_flush_dev(struct net_d
-                        */
-                       BUG_ON(pppoe_pernet(dev_net(dev)) == NULL);
--                      write_lock_bh(&pn->hash_lock);
--                      po = pn->hash_table[i];
-+                      spin_lock(&pn->hash_lock);
-+                      po = rcu_dereference_protected(pn->hash_table[i],
-+                                                     lockdep_is_held(&pn->hash_lock));
-               }
-       }
--      write_unlock_bh(&pn->hash_lock);
-+      spin_unlock(&pn->hash_lock);
- }
- static int pppoe_device_event(struct notifier_block *this,
-@@ -528,6 +534,11 @@ static struct proto pppoe_sk_proto __rea
-       .obj_size = sizeof(struct pppox_sock),
- };
-+static void pppoe_destruct(struct sock *sk)
-+{
-+      skb_queue_purge(&sk->sk_receive_queue);
-+}
-+
- /***********************************************************************
-  *
-  * Initialize a new struct sock.
-@@ -542,11 +553,13 @@ static int pppoe_create(struct net *net,
-               return -ENOMEM;
-       sock_init_data(sock, sk);
-+      sock_set_flag(sk, SOCK_RCU_FREE);
-       sock->state     = SS_UNCONNECTED;
-       sock->ops       = &pppoe_ops;
-       sk->sk_backlog_rcv      = pppoe_rcv_core;
-+      sk->sk_destruct         = pppoe_destruct;
-       sk->sk_state            = PPPOX_NONE;
-       sk->sk_type             = SOCK_STREAM;
-       sk->sk_family           = PF_PPPOX;
-@@ -599,7 +612,6 @@ static int pppoe_release(struct socket *
-       sock_orphan(sk);
-       sock->sk = NULL;
--      skb_queue_purge(&sk->sk_receive_queue);
-       release_sock(sk);
-       sock_put(sk);
-@@ -681,9 +693,9 @@ static int pppoe_connect(struct socket *
-                      &sp->sa_addr.pppoe,
-                      sizeof(struct pppoe_addr));
--              write_lock_bh(&pn->hash_lock);
-+              spin_lock(&pn->hash_lock);
-               error = __set_item(pn, po);
--              write_unlock_bh(&pn->hash_lock);
-+              spin_unlock(&pn->hash_lock);
-               if (error < 0)
-                       goto err_put;
-@@ -1052,11 +1064,11 @@ static inline struct pppox_sock *pppoe_g
-       int i;
-       for (i = 0; i < PPPOE_HASH_SIZE; i++) {
--              po = pn->hash_table[i];
-+              po = rcu_dereference(pn->hash_table[i]);
-               while (po) {
-                       if (!pos--)
-                               goto out;
--                      po = po->next;
-+                      po = rcu_dereference(po->next);
-               }
-       }
-@@ -1065,19 +1077,19 @@ out:
- }
- static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos)
--      __acquires(pn->hash_lock)
-+      __acquires(RCU)
- {
-       struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
-       loff_t l = *pos;
--      read_lock_bh(&pn->hash_lock);
-+      rcu_read_lock();
-       return l ? pppoe_get_idx(pn, --l) : SEQ_START_TOKEN;
- }
- static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
- {
-       struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
--      struct pppox_sock *po;
-+      struct pppox_sock *po, *next;
-       ++*pos;
-       if (v == SEQ_START_TOKEN) {
-@@ -1085,14 +1097,15 @@ static void *pppoe_seq_next(struct seq_f
-               goto out;
-       }
-       po = v;
--      if (po->next)
--              po = po->next;
-+      next = rcu_dereference(po->next);
-+      if (next)
-+              po = next;
-       else {
-               int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
-               po = NULL;
-               while (++hash < PPPOE_HASH_SIZE) {
--                      po = pn->hash_table[hash];
-+                      po = rcu_dereference(pn->hash_table[hash]);
-                       if (po)
-                               break;
-               }
-@@ -1103,10 +1116,9 @@ out:
- }
- static void pppoe_seq_stop(struct seq_file *seq, void *v)
--      __releases(pn->hash_lock)
-+      __releases(RCU)
- {
--      struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
--      read_unlock_bh(&pn->hash_lock);
-+      rcu_read_unlock();
- }
- static const struct seq_operations pppoe_seq_ops = {
-@@ -1149,7 +1161,7 @@ static __net_init int pppoe_init_net(str
-       struct pppoe_net *pn = pppoe_pernet(net);
-       struct proc_dir_entry *pde;
--      rwlock_init(&pn->hash_lock);
-+      spin_lock_init(&pn->hash_lock);
-       pde = proc_create_net("pppoe", 0444, net->proc_net,
-                       &pppoe_seq_ops, sizeof(struct seq_net_private));
---- a/include/linux/if_pppox.h
-+++ b/include/linux/if_pppox.h
-@@ -43,7 +43,7 @@ struct pppox_sock {
-       /* struct sock must be the first member of pppox_sock */
-       struct sock sk;
-       struct ppp_channel chan;
--      struct pppox_sock       *next;    /* for hash table */
-+      struct pppox_sock __rcu *next;    /* for hash table */
-       union {
-               struct pppoe_opt pppoe;
-               struct pptp_opt  pptp;
diff --git a/target/linux/generic/backport-6.18/624-v6.18-pppoe-drop-sock-reference-counting-on-fast-path.patch b/target/linux/generic/backport-6.18/624-v6.18-pppoe-drop-sock-reference-counting-on-fast-path.patch
deleted file mode 100644 (file)
index 2637621..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-From 4f54dff818d7b5b1d84becd5d90bc46e6233c0d7 Mon Sep 17 00:00:00 2001
-From: Qingfang Deng <dqfext@gmail.com>
-Date: Thu, 28 Aug 2025 09:20:17 +0800
-Subject: [PATCH] pppoe: drop sock reference counting on fast path
-
-Now that PPPoE sockets are freed via RCU (SOCK_RCU_FREE), it is no longer
-necessary to take a reference count when looking up sockets on the receive
-path. Readers are protected by RCU, so the socket memory remains valid
-until after a grace period.
-
-Convert fast-path lookups to avoid refcounting:
- - Replace get_item() and sk_receive_skb() in pppoe_rcv() with
-   __get_item() and __sk_receive_skb().
- - Rework get_item_by_addr() into __get_item_by_addr() (no refcount and
-   move RCU lock into pppoe_ioctl)
- - Remove unnecessary sock_put() calls.
-
-This avoids cacheline bouncing from atomic reference counting and improves
-performance on the receive fast path.
-
-Signed-off-by: Qingfang Deng <dqfext@gmail.com>
-Reviewed-by: Eric Dumazet <edumazet@google.com>
-Link: https://patch.msgid.link/20250828012018.15922-2-dqfext@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ppp/pppoe.c | 35 +++++++++++++----------------------
- 1 file changed, 13 insertions(+), 22 deletions(-)
-
---- a/drivers/net/ppp/pppoe.c
-+++ b/drivers/net/ppp/pppoe.c
-@@ -237,8 +237,8 @@ static inline struct pppox_sock *get_ite
-       return po;
- }
--static inline struct pppox_sock *get_item_by_addr(struct net *net,
--                                              struct sockaddr_pppox *sp)
-+static inline struct pppox_sock *__get_item_by_addr(struct net *net,
-+                                                  struct sockaddr_pppox *sp)
- {
-       struct net_device *dev;
-       struct pppoe_net *pn;
-@@ -246,15 +246,13 @@ static inline struct pppox_sock *get_ite
-       int ifindex;
--      rcu_read_lock();
-       dev = dev_get_by_name_rcu(net, sp->sa_addr.pppoe.dev);
-       if (dev) {
-               ifindex = dev->ifindex;
-               pn = pppoe_pernet(net);
--              pppox_sock = get_item(pn, sp->sa_addr.pppoe.sid,
--                              sp->sa_addr.pppoe.remote, ifindex);
-+              pppox_sock = __get_item(pn, sp->sa_addr.pppoe.sid,
-+                                      sp->sa_addr.pppoe.remote, ifindex);
-       }
--      rcu_read_unlock();
-       return pppox_sock;
- }
-@@ -384,18 +382,16 @@ static int pppoe_rcv_core(struct sock *s
-       if (sk->sk_state & PPPOX_BOUND) {
-               ppp_input(&po->chan, skb);
-       } else if (sk->sk_state & PPPOX_RELAY) {
--              relay_po = get_item_by_addr(sock_net(sk),
--                                          &po->pppoe_relay);
-+              relay_po = __get_item_by_addr(sock_net(sk),
-+                                            &po->pppoe_relay);
-               if (relay_po == NULL)
-                       goto abort_kfree;
-               if ((sk_pppox(relay_po)->sk_state & PPPOX_CONNECTED) == 0)
--                      goto abort_put;
-+                      goto abort_kfree;
-               if (!__pppoe_xmit(sk_pppox(relay_po), skb))
--                      goto abort_put;
--
--              sock_put(sk_pppox(relay_po));
-+                      goto abort_kfree;
-       } else {
-               if (sock_queue_rcv_skb(sk, skb))
-                       goto abort_kfree;
-@@ -403,9 +399,6 @@ static int pppoe_rcv_core(struct sock *s
-       return NET_RX_SUCCESS;
--abort_put:
--      sock_put(sk_pppox(relay_po));
--
- abort_kfree:
-       kfree_skb(skb);
-       return NET_RX_DROP;
-@@ -447,14 +440,11 @@ static int pppoe_rcv(struct sk_buff *skb
-       ph = pppoe_hdr(skb);
-       pn = pppoe_pernet(dev_net(dev));
--      /* Note that get_item does a sock_hold(), so sk_pppox(po)
--       * is known to be safe.
--       */
--      po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
-+      po = __get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
-       if (!po)
-               goto drop;
--      return sk_receive_skb(sk_pppox(po), skb, 0);
-+      return __sk_receive_skb(sk_pppox(po), skb, 0, 1, false);
- drop:
-       kfree_skb(skb);
-@@ -820,11 +810,12 @@ static int pppoe_ioctl(struct socket *so
-               /* Check that the socket referenced by the address
-                  actually exists. */
--              relay_po = get_item_by_addr(sock_net(sk), &po->pppoe_relay);
-+              rcu_read_lock();
-+              relay_po = __get_item_by_addr(sock_net(sk), &po->pppoe_relay);
-+              rcu_read_unlock();
-               if (!relay_po)
-                       break;
--              sock_put(sk_pppox(relay_po));
-               sk->sk_state |= PPPOX_RELAY;
-               err = 0;
-               break;
diff --git a/target/linux/generic/backport-6.18/626-01-v6.13-net-pse-pd-Add-power-limit-check.patch b/target/linux/generic/backport-6.18/626-01-v6.13-net-pse-pd-Add-power-limit-check.patch
deleted file mode 100644 (file)
index fbcc3ec..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From 6e56a6d47a7fad705a1a1d088237b0858c01a770 Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:22 +0100
-Subject: [PATCH] net: pse-pd: Add power limit check
-
-Checking only the current limit is not sufficient. According to the
-standard, voltage can reach up to 57V and current up to 1.92A, which
-exceeds the power limit described in the standard (99.9W). Add a power
-limit check to prevent this.
-
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pse_core.c | 3 +++
- include/linux/pse-pd/pse.h    | 2 ++
- 2 files changed, 5 insertions(+)
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -868,6 +868,9 @@ int pse_ethtool_set_pw_limit(struct pse_
-       int uV, uA, ret;
-       s64 tmp_64;
-+      if (pw_limit > MAX_PI_PW)
-+              return -ERANGE;
-+
-       ret = regulator_get_voltage(psec->ps);
-       if (!ret) {
-               NL_SET_ERR_MSG(extack,
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -11,6 +11,8 @@
- /* Maximum current in uA according to IEEE 802.3-2022 Table 145-1 */
- #define MAX_PI_CURRENT 1920000
-+/* Maximum power in mW according to IEEE 802.3-2022 Table 145-16 */
-+#define MAX_PI_PW 99900
- struct phy_device;
- struct pse_controller_dev;
diff --git a/target/linux/generic/backport-6.18/626-02-v6.13-net-pse-pd-tps23881-Simplify-function-returns.patch b/target/linux/generic/backport-6.18/626-02-v6.13-net-pse-pd-tps23881-Simplify-function-returns.patch
deleted file mode 100644 (file)
index fc6d532..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-From 0b567519d1152de52b29b2da2c47aa0f39a46266 Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:23 +0100
-Subject: [PATCH] net: pse-pd: tps23881: Simplify function returns by removing
- redundant checks
-
-Cleaned up several functions in tps23881 by removing redundant checks on
-return values at the end of functions. These check has been removed, and
-the return statement now directly returns the function result, reducing
-the code's complexity and making it more concise.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Reviewed-by: Kyle Swenson <kyle.swenson@est.tech>
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/tps23881.c | 34 ++++++----------------------------
- 1 file changed, 6 insertions(+), 28 deletions(-)
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -59,7 +59,6 @@ static int tps23881_pi_enable(struct pse
-       struct i2c_client *client = priv->client;
-       u8 chan;
-       u16 val;
--      int ret;
-       if (id >= TPS23881_MAX_CHANS)
-               return -ERANGE;
-@@ -78,11 +77,7 @@ static int tps23881_pi_enable(struct pse
-                       val |= BIT(chan + 4);
-       }
--      ret = i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
--      if (ret)
--              return ret;
--
--      return 0;
-+      return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
- }
- static int tps23881_pi_disable(struct pse_controller_dev *pcdev, int id)
-@@ -91,7 +86,6 @@ static int tps23881_pi_disable(struct ps
-       struct i2c_client *client = priv->client;
-       u8 chan;
-       u16 val;
--      int ret;
-       if (id >= TPS23881_MAX_CHANS)
-               return -ERANGE;
-@@ -110,11 +104,7 @@ static int tps23881_pi_disable(struct ps
-                       val |= BIT(chan + 8);
-       }
--      ret = i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
--      if (ret)
--              return ret;
--
--      return 0;
-+      return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
- }
- static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
-@@ -480,7 +470,7 @@ tps23881_write_port_matrix(struct tps238
-       struct i2c_client *client = priv->client;
-       u8 pi_id, lgcl_chan, hw_chan;
-       u16 val = 0;
--      int i, ret;
-+      int i;
-       for (i = 0; i < port_cnt; i++) {
-               pi_id = port_matrix[i].pi_id;
-@@ -511,11 +501,7 @@ tps23881_write_port_matrix(struct tps238
-       }
-       /* Write hardware ports matrix */
--      ret = i2c_smbus_write_word_data(client, TPS23881_REG_PORT_MAP, val);
--      if (ret)
--              return ret;
--
--      return 0;
-+      return i2c_smbus_write_word_data(client, TPS23881_REG_PORT_MAP, val);
- }
- static int
-@@ -564,11 +550,7 @@ tps23881_set_ports_conf(struct tps23881_
-                       val |= BIT(port_matrix[i].lgcl_chan[1]) |
-                              BIT(port_matrix[i].lgcl_chan[1] + 4);
-       }
--      ret = i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val);
--      if (ret)
--              return ret;
--
--      return 0;
-+      return i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val);
- }
- static int
-@@ -594,11 +576,7 @@ tps23881_set_ports_matrix(struct tps2388
-       if (ret)
-               return ret;
--      ret = tps23881_set_ports_conf(priv, port_matrix);
--      if (ret)
--              return ret;
--
--      return 0;
-+      return tps23881_set_ports_conf(priv, port_matrix);
- }
- static int tps23881_setup_pi_matrix(struct pse_controller_dev *pcdev)
diff --git a/target/linux/generic/backport-6.18/626-03-v6.13-net-pse-pd-tps23881-Use-helpers-to-calculate-bit-offset.patch b/target/linux/generic/backport-6.18/626-03-v6.13-net-pse-pd-tps23881-Use-helpers-to-calculate-bit-offset.patch
deleted file mode 100644 (file)
index 3b390ea..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-From 4c2bab507eb7edc8e497e91b9b7f05d76d7e32bb Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:24 +0100
-Subject: [PATCH] net: pse-pd: tps23881: Use helpers to calculate bit offset
- for a channel
-
-This driver frequently follows a pattern where two registers are read or
-written in a single operation, followed by calculating the bit offset for
-a specific channel.
-
-Introduce helpers to streamline this process and reduce code redundancy,
-making the codebase cleaner and more maintainable.
-
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/tps23881.c | 107 ++++++++++++++++++++++------------
- 1 file changed, 69 insertions(+), 38 deletions(-)
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -53,6 +53,55 @@ static struct tps23881_priv *to_tps23881
-       return container_of(pcdev, struct tps23881_priv, pcdev);
- }
-+/*
-+ * Helper to extract a value from a u16 register value, which is made of two
-+ * u8 registers. The function calculates the bit offset based on the channel
-+ * and extracts the relevant bits using a provided field mask.
-+ *
-+ * @param reg_val: The u16 register value (composed of two u8 registers).
-+ * @param chan: The channel number (0-7).
-+ * @param field_offset: The base bit offset to apply (e.g., 0 or 4).
-+ * @param field_mask: The mask to apply to extract the required bits.
-+ * @return: The extracted value for the specific channel.
-+ */
-+static u16 tps23881_calc_val(u16 reg_val, u8 chan, u8 field_offset,
-+                           u16 field_mask)
-+{
-+      if (chan >= 4)
-+              reg_val >>= 8;
-+
-+      return (reg_val >> field_offset) & field_mask;
-+}
-+
-+/*
-+ * Helper to combine individual channel values into a u16 register value.
-+ * The function sets the value for a specific channel in the appropriate
-+ * position.
-+ *
-+ * @param reg_val: The current u16 register value.
-+ * @param chan: The channel number (0-7).
-+ * @param field_offset: The base bit offset to apply (e.g., 0 or 4).
-+ * @param field_mask: The mask to apply for the field (e.g., 0x0F).
-+ * @param field_val: The value to set for the specific channel (masked by
-+ *                   field_mask).
-+ * @return: The updated u16 register value with the channel value set.
-+ */
-+static u16 tps23881_set_val(u16 reg_val, u8 chan, u8 field_offset,
-+                          u16 field_mask, u16 field_val)
-+{
-+      field_val &= field_mask;
-+
-+      if (chan < 4) {
-+              reg_val &= ~(field_mask << field_offset);
-+              reg_val |= (field_val << field_offset);
-+      } else {
-+              reg_val &= ~(field_mask << (field_offset + 8));
-+              reg_val |= (field_val << (field_offset + 8));
-+      }
-+
-+      return reg_val;
-+}
-+
- static int tps23881_pi_enable(struct pse_controller_dev *pcdev, int id)
- {
-       struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-@@ -64,17 +113,12 @@ static int tps23881_pi_enable(struct pse
-               return -ERANGE;
-       chan = priv->port[id].chan[0];
--      if (chan < 4)
--              val = BIT(chan);
--      else
--              val = BIT(chan + 4);
-+      val = tps23881_set_val(0, chan, 0, BIT(chan % 4), BIT(chan % 4));
-       if (priv->port[id].is_4p) {
-               chan = priv->port[id].chan[1];
--              if (chan < 4)
--                      val |= BIT(chan);
--              else
--                      val |= BIT(chan + 4);
-+              val = tps23881_set_val(val, chan, 0, BIT(chan % 4),
-+                                     BIT(chan % 4));
-       }
-       return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
-@@ -91,17 +135,12 @@ static int tps23881_pi_disable(struct ps
-               return -ERANGE;
-       chan = priv->port[id].chan[0];
--      if (chan < 4)
--              val = BIT(chan + 4);
--      else
--              val = BIT(chan + 8);
-+      val = tps23881_set_val(0, chan, 4, BIT(chan % 4), BIT(chan % 4));
-       if (priv->port[id].is_4p) {
-               chan = priv->port[id].chan[1];
--              if (chan < 4)
--                      val |= BIT(chan + 4);
--              else
--                      val |= BIT(chan + 8);
-+              val = tps23881_set_val(val, chan, 4, BIT(chan % 4),
-+                                     BIT(chan % 4));
-       }
-       return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
-@@ -113,6 +152,7 @@ static int tps23881_pi_is_enabled(struct
-       struct i2c_client *client = priv->client;
-       bool enabled;
-       u8 chan;
-+      u16 val;
-       int ret;
-       ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS);
-@@ -120,17 +160,13 @@ static int tps23881_pi_is_enabled(struct
-               return ret;
-       chan = priv->port[id].chan[0];
--      if (chan < 4)
--              enabled = ret & BIT(chan);
--      else
--              enabled = ret & BIT(chan + 4);
-+      val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
-+      enabled = !!(val);
-       if (priv->port[id].is_4p) {
-               chan = priv->port[id].chan[1];
--              if (chan < 4)
--                      enabled &= !!(ret & BIT(chan));
--              else
--                      enabled &= !!(ret & BIT(chan + 4));
-+              val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
-+              enabled &= !!(val);
-       }
-       /* Return enabled status only if both channel are on this state */
-@@ -146,6 +182,7 @@ static int tps23881_ethtool_get_status(s
-       struct i2c_client *client = priv->client;
-       bool enabled, delivering;
-       u8 chan;
-+      u16 val;
-       int ret;
-       ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS);
-@@ -153,23 +190,17 @@ static int tps23881_ethtool_get_status(s
-               return ret;
-       chan = priv->port[id].chan[0];
--      if (chan < 4) {
--              enabled = ret & BIT(chan);
--              delivering = ret & BIT(chan + 4);
--      } else {
--              enabled = ret & BIT(chan + 4);
--              delivering = ret & BIT(chan + 8);
--      }
-+      val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
-+      enabled = !!(val);
-+      val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
-+      delivering = !!(val);
-       if (priv->port[id].is_4p) {
-               chan = priv->port[id].chan[1];
--              if (chan < 4) {
--                      enabled &= !!(ret & BIT(chan));
--                      delivering &= !!(ret & BIT(chan + 4));
--              } else {
--                      enabled &= !!(ret & BIT(chan + 4));
--                      delivering &= !!(ret & BIT(chan + 8));
--              }
-+              val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
-+              enabled &= !!(val);
-+              val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
-+              delivering &= !!(val);
-       }
-       /* Return delivering status only if both channel are on this state */
diff --git a/target/linux/generic/backport-6.18/626-04-v6.13-net-pse-pd-tps23881-Add-missing-configuration-register.patch b/target/linux/generic/backport-6.18/626-04-v6.13-net-pse-pd-tps23881-Add-missing-configuration-register.patch
deleted file mode 100644 (file)
index c00dd90..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-From f3cb3c7bea0c08e821d8e9dfd2f96acd1db7c24e Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:25 +0100
-Subject: [PATCH] net: pse-pd: tps23881: Add missing configuration register
- after disable
-
-When setting the PWOFF register, the controller resets multiple
-configuration registers. This patch ensures these registers are
-reconfigured as needed following a disable operation.
-
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/tps23881.c | 30 +++++++++++++++++++++++++++++-
- 1 file changed, 29 insertions(+), 1 deletion(-)
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -130,6 +130,7 @@ static int tps23881_pi_disable(struct ps
-       struct i2c_client *client = priv->client;
-       u8 chan;
-       u16 val;
-+      int ret;
-       if (id >= TPS23881_MAX_CHANS)
-               return -ERANGE;
-@@ -143,7 +144,34 @@ static int tps23881_pi_disable(struct ps
-                                      BIT(chan % 4));
-       }
--      return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
-+      ret = i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
-+      if (ret)
-+              return ret;
-+
-+      /* PWOFF command resets lots of register which need to be
-+       * configured again. According to the datasheet "It may take upwards
-+       * of 5ms after PWOFFn command for all register values to be updated"
-+       */
-+      mdelay(5);
-+
-+      /* Enable detection and classification */
-+      ret = i2c_smbus_read_word_data(client, TPS23881_REG_DET_CLA_EN);
-+      if (ret < 0)
-+              return ret;
-+
-+      chan = priv->port[id].chan[0];
-+      val = tps23881_set_val(ret, chan, 0, BIT(chan % 4), BIT(chan % 4));
-+      val = tps23881_set_val(val, chan, 4, BIT(chan % 4), BIT(chan % 4));
-+
-+      if (priv->port[id].is_4p) {
-+              chan = priv->port[id].chan[1];
-+              val = tps23881_set_val(ret, chan, 0, BIT(chan % 4),
-+                                     BIT(chan % 4));
-+              val = tps23881_set_val(val, chan, 4, BIT(chan % 4),
-+                                     BIT(chan % 4));
-+      }
-+
-+      return i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val);
- }
- static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
diff --git a/target/linux/generic/backport-6.18/626-05-v6.13-net-pse-pd-Split-ethtool_get_status-into-multiple-callbacks.patch b/target/linux/generic/backport-6.18/626-05-v6.13-net-pse-pd-Split-ethtool_get_status-into-multiple-callbacks.patch
deleted file mode 100644 (file)
index 71a2379..0000000
+++ /dev/null
@@ -1,714 +0,0 @@
-From 3e9dbfec499807767d03592ebdf19d9c15fd495b Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:27 +0100
-Subject: [PATCH] net: pse-pd: Split ethtool_get_status into multiple callbacks
-
-The ethtool_get_status callback currently handles all status and PSE
-information within a single function. This approach has two key
-drawbacks:
-
-1. If the core requires some information for purposes other than
-   ethtool_get_status, redundant code will be needed to fetch the same
-   data from the driver (like is_enabled).
-
-2. Drivers currently have access to all information passed to ethtool.
-   New variables will soon be added to ethtool status, such as PSE ID,
-   power domain IDs, and budget evaluation strategies, which are meant
-   to be managed solely by the core. Drivers should not have the ability
-   to modify these variables.
-
-To resolve these issues, ethtool_get_status has been split into multiple
-callbacks, with each handling a specific piece of information required
-by ethtool or the core.
-
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pd692x0.c       | 153 ++++++++++++++++++++---------
- drivers/net/pse-pd/pse_core.c      |  83 ++++++++++++++--
- drivers/net/pse-pd/pse_regulator.c |  26 +++--
- drivers/net/pse-pd/tps23881.c      |  60 ++++++++---
- include/linux/pse-pd/pse.h         |  87 +++++++++++++---
- net/ethtool/pse-pd.c               |   8 +-
- 6 files changed, 323 insertions(+), 94 deletions(-)
-
---- a/drivers/net/pse-pd/pd692x0.c
-+++ b/drivers/net/pse-pd/pd692x0.c
-@@ -517,21 +517,38 @@ pd692x0_pse_ext_state_map[] = {
-       { /* sentinel */ }
- };
--static void
--pd692x0_get_ext_state(struct ethtool_c33_pse_ext_state_info *c33_ext_state_info,
--                    u32 status_code)
-+static int
-+pd692x0_pi_get_ext_state(struct pse_controller_dev *pcdev, int id,
-+                       struct pse_ext_state_info *ext_state_info)
- {
-+      struct ethtool_c33_pse_ext_state_info *c33_ext_state_info;
-       const struct pd692x0_pse_ext_state_mapping *ext_state_map;
-+      struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-+      struct pd692x0_msg msg, buf = {0};
-+      int ret;
-+
-+      ret = pd692x0_fw_unavailable(priv);
-+      if (ret)
-+              return ret;
-+      msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
-+      msg.sub[2] = id;
-+      ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
-+      if (ret < 0)
-+              return ret;
-+
-+      c33_ext_state_info = &ext_state_info->c33_ext_state_info;
-       ext_state_map = pd692x0_pse_ext_state_map;
-       while (ext_state_map->status_code) {
--              if (ext_state_map->status_code == status_code) {
-+              if (ext_state_map->status_code == buf.sub[0]) {
-                       c33_ext_state_info->c33_pse_ext_state = ext_state_map->pse_ext_state;
-                       c33_ext_state_info->__c33_pse_ext_substate = ext_state_map->pse_ext_substate;
--                      return;
-+                      return  0;
-               }
-               ext_state_map++;
-       }
-+
-+      return 0;
- }
- struct pd692x0_class_pw {
-@@ -613,35 +630,36 @@ static int pd692x0_pi_set_pw_from_table(
- }
- static int
--pd692x0_pi_get_pw_ranges(struct pse_control_status *st)
-+pd692x0_pi_get_pw_limit_ranges(struct pse_controller_dev *pcdev, int id,
-+                             struct pse_pw_limit_ranges *pw_limit_ranges)
- {
-+      struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges;
-       const struct pd692x0_class_pw *pw_table;
-       int i;
-       pw_table = pd692x0_class_pw_table;
--      st->c33_pw_limit_ranges = kcalloc(PD692X0_CLASS_PW_TABLE_SIZE,
--                                        sizeof(struct ethtool_c33_pse_pw_limit_range),
--                                        GFP_KERNEL);
--      if (!st->c33_pw_limit_ranges)
-+      c33_pw_limit_ranges = kcalloc(PD692X0_CLASS_PW_TABLE_SIZE,
-+                                    sizeof(*c33_pw_limit_ranges),
-+                                    GFP_KERNEL);
-+      if (!c33_pw_limit_ranges)
-               return -ENOMEM;
-       for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
--              st->c33_pw_limit_ranges[i].min = pw_table->class_pw;
--              st->c33_pw_limit_ranges[i].max = pw_table->class_pw + pw_table->max_added_class_pw;
-+              c33_pw_limit_ranges[i].min = pw_table->class_pw;
-+              c33_pw_limit_ranges[i].max = pw_table->class_pw +
-+                                           pw_table->max_added_class_pw;
-       }
--      st->c33_pw_limit_nb_ranges = i;
--      return 0;
-+      pw_limit_ranges->c33_pw_limit_ranges = c33_pw_limit_ranges;
-+      return i;
- }
--static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
--                                    unsigned long id,
--                                    struct netlink_ext_ack *extack,
--                                    struct pse_control_status *status)
-+static int
-+pd692x0_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,
-+                         struct pse_admin_state *admin_state)
- {
-       struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-       struct pd692x0_msg msg, buf = {0};
--      u32 class;
-       int ret;
-       ret = pd692x0_fw_unavailable(priv);
-@@ -654,39 +672,65 @@ static int pd692x0_ethtool_get_status(st
-       if (ret < 0)
-               return ret;
--      /* Compare Port Status (Communication Protocol Document par. 7.1) */
--      if ((buf.sub[0] & 0xf0) == 0x80 || (buf.sub[0] & 0xf0) == 0x90)
--              status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
--      else if (buf.sub[0] == 0x1b || buf.sub[0] == 0x22)
--              status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING;
--      else if (buf.sub[0] == 0x12)
--              status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_FAULT;
--      else
--              status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
--
-       if (buf.sub[1])
--              status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
-+              admin_state->c33_admin_state =
-+                      ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
-       else
--              status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
-+              admin_state->c33_admin_state =
-+                      ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
--      priv->admin_state[id] = status->c33_admin_state;
-+      priv->admin_state[id] = admin_state->c33_admin_state;
--      pd692x0_get_ext_state(&status->c33_ext_state_info, buf.sub[0]);
--      status->c33_actual_pw = (buf.data[0] << 4 | buf.data[1]) * 100;
-+      return 0;
-+}
--      msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
-+static int
-+pd692x0_pi_get_pw_status(struct pse_controller_dev *pcdev, int id,
-+                       struct pse_pw_status *pw_status)
-+{
-+      struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-+      struct pd692x0_msg msg, buf = {0};
-+      int ret;
-+
-+      ret = pd692x0_fw_unavailable(priv);
-+      if (ret)
-+              return ret;
-+
-+      msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
-       msg.sub[2] = id;
--      memset(&buf, 0, sizeof(buf));
-       ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
-       if (ret < 0)
-               return ret;
--      ret = pd692x0_pi_get_pw_from_table(buf.data[0], buf.data[1]);
--      if (ret < 0)
-+      /* Compare Port Status (Communication Protocol Document par. 7.1) */
-+      if ((buf.sub[0] & 0xf0) == 0x80 || (buf.sub[0] & 0xf0) == 0x90)
-+              pw_status->c33_pw_status =
-+                      ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
-+      else if (buf.sub[0] == 0x1b || buf.sub[0] == 0x22)
-+              pw_status->c33_pw_status =
-+                      ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING;
-+      else if (buf.sub[0] == 0x12)
-+              pw_status->c33_pw_status =
-+                      ETHTOOL_C33_PSE_PW_D_STATUS_FAULT;
-+      else
-+              pw_status->c33_pw_status =
-+                      ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
-+
-+      return 0;
-+}
-+
-+static int
-+pd692x0_pi_get_pw_class(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-+      struct pd692x0_msg msg, buf = {0};
-+      u32 class;
-+      int ret;
-+
-+      ret = pd692x0_fw_unavailable(priv);
-+      if (ret)
-               return ret;
--      status->c33_avail_pw_limit = ret;
--      memset(&buf, 0, sizeof(buf));
-       msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_CLASS];
-       msg.sub[2] = id;
-       ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
-@@ -695,13 +739,29 @@ static int pd692x0_ethtool_get_status(st
-       class = buf.data[3] >> 4;
-       if (class <= 8)
--              status->c33_pw_class = class;
-+              return class;
-+
-+      return 0;
-+}
-+
-+static int
-+pd692x0_pi_get_actual_pw(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-+      struct pd692x0_msg msg, buf = {0};
-+      int ret;
-+
-+      ret = pd692x0_fw_unavailable(priv);
-+      if (ret)
-+              return ret;
--      ret = pd692x0_pi_get_pw_ranges(status);
-+      msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
-+      msg.sub[2] = id;
-+      ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
-       if (ret < 0)
-               return ret;
--      return 0;
-+      return (buf.data[0] << 4 | buf.data[1]) * 100;
- }
- static struct pd692x0_msg_ver pd692x0_get_sw_version(struct pd692x0_priv *priv)
-@@ -1038,13 +1098,18 @@ static int pd692x0_pi_set_pw_limit(struc
- static const struct pse_controller_ops pd692x0_ops = {
-       .setup_pi_matrix = pd692x0_setup_pi_matrix,
--      .ethtool_get_status = pd692x0_ethtool_get_status,
-+      .pi_get_admin_state = pd692x0_pi_get_admin_state,
-+      .pi_get_pw_status = pd692x0_pi_get_pw_status,
-+      .pi_get_ext_state = pd692x0_pi_get_ext_state,
-+      .pi_get_pw_class = pd692x0_pi_get_pw_class,
-+      .pi_get_actual_pw = pd692x0_pi_get_actual_pw,
-       .pi_enable = pd692x0_pi_enable,
-       .pi_disable = pd692x0_pi_disable,
-       .pi_is_enabled = pd692x0_pi_is_enabled,
-       .pi_get_voltage = pd692x0_pi_get_voltage,
-       .pi_get_pw_limit = pd692x0_pi_get_pw_limit,
-       .pi_set_pw_limit = pd692x0_pi_set_pw_limit,
-+      .pi_get_pw_limit_ranges = pd692x0_pi_get_pw_limit_ranges,
- };
- #define PD692X0_FW_LINE_MAX_SZ 0xff
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -443,6 +443,13 @@ int pse_controller_register(struct pse_c
-       if (!pcdev->nr_lines)
-               pcdev->nr_lines = 1;
-+      if (!pcdev->ops->pi_get_admin_state ||
-+          !pcdev->ops->pi_get_pw_status) {
-+              dev_err(pcdev->dev,
-+                      "Mandatory status report callbacks are missing");
-+              return -EINVAL;
-+      }
-+
-       ret = of_load_pse_pis(pcdev);
-       if (ret)
-               return ret;
-@@ -745,25 +752,81 @@ EXPORT_SYMBOL_GPL(of_pse_control_get);
-  */
- int pse_ethtool_get_status(struct pse_control *psec,
-                          struct netlink_ext_ack *extack,
--                         struct pse_control_status *status)
-+                         struct ethtool_pse_control_status *status)
- {
-+      struct pse_admin_state admin_state = {0};
-+      struct pse_pw_status pw_status = {0};
-       const struct pse_controller_ops *ops;
-       struct pse_controller_dev *pcdev;
--      int err;
-+      int ret;
-       pcdev = psec->pcdev;
-       ops = pcdev->ops;
--      if (!ops->ethtool_get_status) {
--              NL_SET_ERR_MSG(extack,
--                             "PSE driver does not support status report");
--              return -EOPNOTSUPP;
-+      mutex_lock(&pcdev->lock);
-+      ret = ops->pi_get_admin_state(pcdev, psec->id, &admin_state);
-+      if (ret)
-+              goto out;
-+      status->podl_admin_state = admin_state.podl_admin_state;
-+      status->c33_admin_state = admin_state.c33_admin_state;
-+
-+      ret = ops->pi_get_pw_status(pcdev, psec->id, &pw_status);
-+      if (ret)
-+              goto out;
-+      status->podl_pw_status = pw_status.podl_pw_status;
-+      status->c33_pw_status = pw_status.c33_pw_status;
-+
-+      if (ops->pi_get_ext_state) {
-+              struct pse_ext_state_info ext_state_info = {0};
-+
-+              ret = ops->pi_get_ext_state(pcdev, psec->id,
-+                                          &ext_state_info);
-+              if (ret)
-+                      goto out;
-+
-+              memcpy(&status->c33_ext_state_info,
-+                     &ext_state_info.c33_ext_state_info,
-+                     sizeof(status->c33_ext_state_info));
-       }
--      mutex_lock(&pcdev->lock);
--      err = ops->ethtool_get_status(pcdev, psec->id, extack, status);
--      mutex_unlock(&pcdev->lock);
-+      if (ops->pi_get_pw_class) {
-+              ret = ops->pi_get_pw_class(pcdev, psec->id);
-+              if (ret < 0)
-+                      goto out;
-+
-+              status->c33_pw_class = ret;
-+      }
-+
-+      if (ops->pi_get_actual_pw) {
-+              ret = ops->pi_get_actual_pw(pcdev, psec->id);
-+              if (ret < 0)
-+                      goto out;
-+
-+              status->c33_actual_pw = ret;
-+      }
-+
-+      if (ops->pi_get_pw_limit) {
-+              ret = ops->pi_get_pw_limit(pcdev, psec->id);
-+              if (ret < 0)
-+                      goto out;
-+
-+              status->c33_avail_pw_limit = ret;
-+      }
-+
-+      if (ops->pi_get_pw_limit_ranges) {
-+              struct pse_pw_limit_ranges pw_limit_ranges = {0};
--      return err;
-+              ret = ops->pi_get_pw_limit_ranges(pcdev, psec->id,
-+                                                &pw_limit_ranges);
-+              if (ret < 0)
-+                      goto out;
-+
-+              status->c33_pw_limit_ranges =
-+                      pw_limit_ranges.c33_pw_limit_ranges;
-+              status->c33_pw_limit_nb_ranges = ret;
-+      }
-+out:
-+      mutex_unlock(&psec->pcdev->lock);
-+      return ret;
- }
- EXPORT_SYMBOL_GPL(pse_ethtool_get_status);
---- a/drivers/net/pse-pd/pse_regulator.c
-+++ b/drivers/net/pse-pd/pse_regulator.c
-@@ -60,9 +60,19 @@ pse_reg_pi_is_enabled(struct pse_control
- }
- static int
--pse_reg_ethtool_get_status(struct pse_controller_dev *pcdev, unsigned long id,
--                         struct netlink_ext_ack *extack,
--                         struct pse_control_status *status)
-+pse_reg_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,
-+                         struct pse_admin_state *admin_state)
-+{
-+      struct pse_reg_priv *priv = to_pse_reg(pcdev);
-+
-+      admin_state->podl_admin_state = priv->admin_state;
-+
-+      return 0;
-+}
-+
-+static int
-+pse_reg_pi_get_pw_status(struct pse_controller_dev *pcdev, int id,
-+                       struct pse_pw_status *pw_status)
- {
-       struct pse_reg_priv *priv = to_pse_reg(pcdev);
-       int ret;
-@@ -72,18 +82,18 @@ pse_reg_ethtool_get_status(struct pse_co
-               return ret;
-       if (!ret)
--              status->podl_pw_status = ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED;
-+              pw_status->podl_pw_status =
-+                      ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED;
-       else
--              status->podl_pw_status =
-+              pw_status->podl_pw_status =
-                       ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING;
--      status->podl_admin_state = priv->admin_state;
--
-       return 0;
- }
- static const struct pse_controller_ops pse_reg_ops = {
--      .ethtool_get_status = pse_reg_ethtool_get_status,
-+      .pi_get_admin_state = pse_reg_pi_get_admin_state,
-+      .pi_get_pw_status = pse_reg_pi_get_pw_status,
-       .pi_enable = pse_reg_pi_enable,
-       .pi_is_enabled = pse_reg_pi_is_enabled,
-       .pi_disable = pse_reg_pi_disable,
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -201,14 +201,13 @@ static int tps23881_pi_is_enabled(struct
-       return enabled;
- }
--static int tps23881_ethtool_get_status(struct pse_controller_dev *pcdev,
--                                     unsigned long id,
--                                     struct netlink_ext_ack *extack,
--                                     struct pse_control_status *status)
-+static int
-+tps23881_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,
-+                          struct pse_admin_state *admin_state)
- {
-       struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-       struct i2c_client *client = priv->client;
--      bool enabled, delivering;
-+      bool enabled;
-       u8 chan;
-       u16 val;
-       int ret;
-@@ -220,28 +219,56 @@ static int tps23881_ethtool_get_status(s
-       chan = priv->port[id].chan[0];
-       val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
-       enabled = !!(val);
--      val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
--      delivering = !!(val);
-       if (priv->port[id].is_4p) {
-               chan = priv->port[id].chan[1];
-               val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
-               enabled &= !!(val);
-+      }
-+
-+      /* Return enabled status only if both channel are on this state */
-+      if (enabled)
-+              admin_state->c33_admin_state =
-+                      ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
-+      else
-+              admin_state->c33_admin_state =
-+                      ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
-+
-+      return 0;
-+}
-+
-+static int
-+tps23881_pi_get_pw_status(struct pse_controller_dev *pcdev, int id,
-+                        struct pse_pw_status *pw_status)
-+{
-+      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-+      struct i2c_client *client = priv->client;
-+      bool delivering;
-+      u8 chan;
-+      u16 val;
-+      int ret;
-+
-+      ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS);
-+      if (ret < 0)
-+              return ret;
-+
-+      chan = priv->port[id].chan[0];
-+      val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
-+      delivering = !!(val);
-+
-+      if (priv->port[id].is_4p) {
-+              chan = priv->port[id].chan[1];
-               val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
-               delivering &= !!(val);
-       }
-       /* Return delivering status only if both channel are on this state */
-       if (delivering)
--              status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
--      else
--              status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
--
--      /* Return enabled status only if both channel are on this state */
--      if (enabled)
--              status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
-+              pw_status->c33_pw_status =
-+                      ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
-       else
--              status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
-+              pw_status->c33_pw_status =
-+                      ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
-       return 0;
- }
-@@ -664,7 +691,8 @@ static const struct pse_controller_ops t
-       .pi_enable = tps23881_pi_enable,
-       .pi_disable = tps23881_pi_disable,
-       .pi_is_enabled = tps23881_pi_is_enabled,
--      .ethtool_get_status = tps23881_ethtool_get_status,
-+      .pi_get_admin_state = tps23881_pi_get_admin_state,
-+      .pi_get_pw_status = tps23881_pi_get_pw_status,
- };
- static const char fw_parity_name[] = "ti/tps23881/tps23881-parity-14.bin";
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -31,7 +31,52 @@ struct pse_control_config {
- };
- /**
-- * struct pse_control_status - PSE control/channel status.
-+ * struct pse_admin_state - PSE operational state
-+ *
-+ * @podl_admin_state: operational state of the PoDL PSE
-+ *    functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
-+ * @c33_admin_state: operational state of the PSE
-+ *    functions. IEEE 802.3-2022 30.9.1.1.2 aPSEAdminState
-+ */
-+struct pse_admin_state {
-+      enum ethtool_podl_pse_admin_state podl_admin_state;
-+      enum ethtool_c33_pse_admin_state c33_admin_state;
-+};
-+
-+/**
-+ * struct pse_pw_status - PSE power detection status
-+ *
-+ * @podl_pw_status: power detection status of the PoDL PSE.
-+ *    IEEE 802.3-2018 30.15.1.1.3 aPoDLPSEPowerDetectionStatus:
-+ * @c33_pw_status: power detection status of the PSE.
-+ *    IEEE 802.3-2022 30.9.1.1.5 aPSEPowerDetectionStatus:
-+ */
-+struct pse_pw_status {
-+      enum ethtool_podl_pse_pw_d_status podl_pw_status;
-+      enum ethtool_c33_pse_pw_d_status c33_pw_status;
-+};
-+
-+/**
-+ * struct pse_ext_state_info - PSE extended state information
-+ *
-+ * @c33_ext_state_info: extended state information of the PSE
-+ */
-+struct pse_ext_state_info {
-+      struct ethtool_c33_pse_ext_state_info c33_ext_state_info;
-+};
-+
-+/**
-+ * struct pse_pw_limit_ranges - PSE power limit configuration range
-+ *
-+ * @c33_pw_limit_ranges: supported power limit configuration range. The driver
-+ *                     is in charge of the memory allocation.
-+ */
-+struct pse_pw_limit_ranges {
-+      struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges;
-+};
-+
-+/**
-+ * struct ethtool_pse_control_status - PSE control/channel status.
-  *
-  * @podl_admin_state: operational state of the PoDL PSE
-  *    functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
-@@ -49,11 +94,11 @@ struct pse_control_config {
-  * @c33_avail_pw_limit: available power limit of the PSE in mW
-  *    IEEE 802.3-2022 145.2.5.4 pse_avail_pwr
-  * @c33_pw_limit_ranges: supported power limit configuration range. The driver
-- *    is in charge of the memory allocation.
-+ *    is in charge of the memory allocation
-  * @c33_pw_limit_nb_ranges: number of supported power limit configuration
-  *    ranges
-  */
--struct pse_control_status {
-+struct ethtool_pse_control_status {
-       enum ethtool_podl_pse_admin_state podl_admin_state;
-       enum ethtool_podl_pse_pw_d_status podl_pw_status;
-       enum ethtool_c33_pse_admin_state c33_admin_state;
-@@ -69,22 +114,37 @@ struct pse_control_status {
- /**
-  * struct pse_controller_ops - PSE controller driver callbacks
-  *
-- * @ethtool_get_status: get PSE control status for ethtool interface
-  * @setup_pi_matrix: setup PI matrix of the PSE controller
-+ * @pi_get_admin_state: Get the operational state of the PSE PI. This ops
-+ *                    is mandatory.
-+ * @pi_get_pw_status: Get the power detection status of the PSE PI. This
-+ *                  ops is mandatory.
-+ * @pi_get_ext_state: Get the extended state of the PSE PI.
-+ * @pi_get_pw_class: Get the power class of the PSE PI.
-+ * @pi_get_actual_pw: Get actual power of the PSE PI in mW.
-  * @pi_is_enabled: Return 1 if the PSE PI is enabled, 0 if not.
-  *               May also return negative errno.
-  * @pi_enable: Configure the PSE PI as enabled.
-  * @pi_disable: Configure the PSE PI as disabled.
-  * @pi_get_voltage: Return voltage similarly to get_voltage regulator
-- *                callback.
-- * @pi_get_pw_limit: Get the configured power limit of the PSE PI.
-- * @pi_set_pw_limit: Configure the power limit of the PSE PI.
-+ *                callback in uV.
-+ * @pi_get_pw_limit: Get the configured power limit of the PSE PI in mW.
-+ * @pi_set_pw_limit: Configure the power limit of the PSE PI in mW.
-+ * @pi_get_pw_limit_ranges: Get the supported power limit configuration
-+ *                        range. The driver is in charge of the memory
-+ *                        allocation and should return the number of
-+ *                        ranges.
-  */
- struct pse_controller_ops {
--      int (*ethtool_get_status)(struct pse_controller_dev *pcdev,
--              unsigned long id, struct netlink_ext_ack *extack,
--              struct pse_control_status *status);
-       int (*setup_pi_matrix)(struct pse_controller_dev *pcdev);
-+      int (*pi_get_admin_state)(struct pse_controller_dev *pcdev, int id,
-+                                struct pse_admin_state *admin_state);
-+      int (*pi_get_pw_status)(struct pse_controller_dev *pcdev, int id,
-+                              struct pse_pw_status *pw_status);
-+      int (*pi_get_ext_state)(struct pse_controller_dev *pcdev, int id,
-+                              struct pse_ext_state_info *ext_state_info);
-+      int (*pi_get_pw_class)(struct pse_controller_dev *pcdev, int id);
-+      int (*pi_get_actual_pw)(struct pse_controller_dev *pcdev, int id);
-       int (*pi_is_enabled)(struct pse_controller_dev *pcdev, int id);
-       int (*pi_enable)(struct pse_controller_dev *pcdev, int id);
-       int (*pi_disable)(struct pse_controller_dev *pcdev, int id);
-@@ -93,12 +153,15 @@ struct pse_controller_ops {
-                              int id);
-       int (*pi_set_pw_limit)(struct pse_controller_dev *pcdev,
-                              int id, int max_mW);
-+      int (*pi_get_pw_limit_ranges)(struct pse_controller_dev *pcdev, int id,
-+                                    struct pse_pw_limit_ranges *pw_limit_ranges);
- };
- struct module;
- struct device_node;
- struct of_phandle_args;
- struct pse_control;
-+struct ethtool_pse_control_status;
- /* PSE PI pairset pinout can either be Alternative A or Alternative B */
- enum pse_pi_pairset_pinout {
-@@ -175,7 +238,7 @@ void pse_control_put(struct pse_control
- int pse_ethtool_get_status(struct pse_control *psec,
-                          struct netlink_ext_ack *extack,
--                         struct pse_control_status *status);
-+                         struct ethtool_pse_control_status *status);
- int pse_ethtool_set_config(struct pse_control *psec,
-                          struct netlink_ext_ack *extack,
-                          const struct pse_control_config *config);
-@@ -201,7 +264,7 @@ static inline void pse_control_put(struc
- static inline int pse_ethtool_get_status(struct pse_control *psec,
-                                        struct netlink_ext_ack *extack,
--                                       struct pse_control_status *status)
-+                                       struct ethtool_pse_control_status *status)
- {
-       return -EOPNOTSUPP;
- }
---- a/net/ethtool/pse-pd.c
-+++ b/net/ethtool/pse-pd.c
-@@ -19,7 +19,7 @@ struct pse_req_info {
- struct pse_reply_data {
-       struct ethnl_reply_data base;
--      struct pse_control_status status;
-+      struct ethtool_pse_control_status status;
- };
- #define PSE_REPDATA(__reply_base) \
-@@ -80,7 +80,7 @@ static int pse_reply_size(const struct e
-                         const struct ethnl_reply_data *reply_base)
- {
-       const struct pse_reply_data *data = PSE_REPDATA(reply_base);
--      const struct pse_control_status *st = &data->status;
-+      const struct ethtool_pse_control_status *st = &data->status;
-       int len = 0;
-       if (st->podl_admin_state > 0)
-@@ -114,7 +114,7 @@ static int pse_reply_size(const struct e
- }
- static int pse_put_pw_limit_ranges(struct sk_buff *skb,
--                                 const struct pse_control_status *st)
-+                                 const struct ethtool_pse_control_status *st)
- {
-       const struct ethtool_c33_pse_pw_limit_range *pw_limit_ranges;
-       int i;
-@@ -146,7 +146,7 @@ static int pse_fill_reply(struct sk_buff
-                         const struct ethnl_reply_data *reply_base)
- {
-       const struct pse_reply_data *data = PSE_REPDATA(reply_base);
--      const struct pse_control_status *st = &data->status;
-+      const struct ethtool_pse_control_status *st = &data->status;
-       if (st->podl_admin_state > 0 &&
-           nla_put_u32(skb, ETHTOOL_A_PODL_PSE_ADMIN_STATE,
diff --git a/target/linux/generic/backport-6.18/626-06-v6.13-net-pse-pd-Remove-is_enabled-callback-from-drivers.patch b/target/linux/generic/backport-6.18/626-06-v6.13-net-pse-pd-Remove-is_enabled-callback-from-drivers.patch
deleted file mode 100644 (file)
index dd7a20e..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-From 4640a1f0d8f2246f34d6e74330d7e7d2cf75605b Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:28 +0100
-Subject: [PATCH] net: pse-pd: Remove is_enabled callback from drivers
-
-The is_enabled callback is now redundant as the admin_state can be obtained
-directly from the driver and provides the same information.
-
-To simplify functionality, the core will handle this internally, making
-the is_enabled callback unnecessary at the driver level. Remove the
-callback from all drivers.
-
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pd692x0.c       | 26 --------------------------
- drivers/net/pse-pd/pse_core.c      | 13 +++++++++++--
- drivers/net/pse-pd/pse_regulator.c |  9 ---------
- drivers/net/pse-pd/tps23881.c      | 28 ----------------------------
- include/linux/pse-pd/pse.h         |  3 ---
- 5 files changed, 11 insertions(+), 68 deletions(-)
-
---- a/drivers/net/pse-pd/pd692x0.c
-+++ b/drivers/net/pse-pd/pd692x0.c
-@@ -431,31 +431,6 @@ static int pd692x0_pi_disable(struct pse
-       return 0;
- }
--static int pd692x0_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
--{
--      struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
--      struct pd692x0_msg msg, buf = {0};
--      int ret;
--
--      ret = pd692x0_fw_unavailable(priv);
--      if (ret)
--              return ret;
--
--      msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
--      msg.sub[2] = id;
--      ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
--      if (ret < 0)
--              return ret;
--
--      if (buf.sub[1]) {
--              priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
--              return 1;
--      } else {
--              priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
--              return 0;
--      }
--}
--
- struct pd692x0_pse_ext_state_mapping {
-       u32 status_code;
-       enum ethtool_c33_pse_ext_state pse_ext_state;
-@@ -1105,7 +1080,6 @@ static const struct pse_controller_ops p
-       .pi_get_actual_pw = pd692x0_pi_get_actual_pw,
-       .pi_enable = pd692x0_pi_enable,
-       .pi_disable = pd692x0_pi_disable,
--      .pi_is_enabled = pd692x0_pi_is_enabled,
-       .pi_get_voltage = pd692x0_pi_get_voltage,
-       .pi_get_pw_limit = pd692x0_pi_get_pw_limit,
-       .pi_set_pw_limit = pd692x0_pi_set_pw_limit,
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -210,16 +210,25 @@ out:
- static int pse_pi_is_enabled(struct regulator_dev *rdev)
- {
-       struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
-+      struct pse_admin_state admin_state = {0};
-       const struct pse_controller_ops *ops;
-       int id, ret;
-       ops = pcdev->ops;
--      if (!ops->pi_is_enabled)
-+      if (!ops->pi_get_admin_state)
-               return -EOPNOTSUPP;
-       id = rdev_get_id(rdev);
-       mutex_lock(&pcdev->lock);
--      ret = ops->pi_is_enabled(pcdev, id);
-+      ret = ops->pi_get_admin_state(pcdev, id, &admin_state);
-+      if (ret)
-+              goto out;
-+
-+      if (admin_state.podl_admin_state == ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED ||
-+          admin_state.c33_admin_state == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED)
-+              ret = 1;
-+
-+out:
-       mutex_unlock(&pcdev->lock);
-       return ret;
---- a/drivers/net/pse-pd/pse_regulator.c
-+++ b/drivers/net/pse-pd/pse_regulator.c
-@@ -52,14 +52,6 @@ pse_reg_pi_disable(struct pse_controller
- }
- static int
--pse_reg_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
--{
--      struct pse_reg_priv *priv = to_pse_reg(pcdev);
--
--      return regulator_is_enabled(priv->ps);
--}
--
--static int
- pse_reg_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,
-                          struct pse_admin_state *admin_state)
- {
-@@ -95,7 +87,6 @@ static const struct pse_controller_ops p
-       .pi_get_admin_state = pse_reg_pi_get_admin_state,
-       .pi_get_pw_status = pse_reg_pi_get_pw_status,
-       .pi_enable = pse_reg_pi_enable,
--      .pi_is_enabled = pse_reg_pi_is_enabled,
-       .pi_disable = pse_reg_pi_disable,
- };
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -174,33 +174,6 @@ static int tps23881_pi_disable(struct ps
-       return i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val);
- }
--static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
--{
--      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
--      struct i2c_client *client = priv->client;
--      bool enabled;
--      u8 chan;
--      u16 val;
--      int ret;
--
--      ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS);
--      if (ret < 0)
--              return ret;
--
--      chan = priv->port[id].chan[0];
--      val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
--      enabled = !!(val);
--
--      if (priv->port[id].is_4p) {
--              chan = priv->port[id].chan[1];
--              val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
--              enabled &= !!(val);
--      }
--
--      /* Return enabled status only if both channel are on this state */
--      return enabled;
--}
--
- static int
- tps23881_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,
-                           struct pse_admin_state *admin_state)
-@@ -690,7 +663,6 @@ static const struct pse_controller_ops t
-       .setup_pi_matrix = tps23881_setup_pi_matrix,
-       .pi_enable = tps23881_pi_enable,
-       .pi_disable = tps23881_pi_disable,
--      .pi_is_enabled = tps23881_pi_is_enabled,
-       .pi_get_admin_state = tps23881_pi_get_admin_state,
-       .pi_get_pw_status = tps23881_pi_get_pw_status,
- };
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -122,8 +122,6 @@ struct ethtool_pse_control_status {
-  * @pi_get_ext_state: Get the extended state of the PSE PI.
-  * @pi_get_pw_class: Get the power class of the PSE PI.
-  * @pi_get_actual_pw: Get actual power of the PSE PI in mW.
-- * @pi_is_enabled: Return 1 if the PSE PI is enabled, 0 if not.
-- *               May also return negative errno.
-  * @pi_enable: Configure the PSE PI as enabled.
-  * @pi_disable: Configure the PSE PI as disabled.
-  * @pi_get_voltage: Return voltage similarly to get_voltage regulator
-@@ -145,7 +143,6 @@ struct pse_controller_ops {
-                               struct pse_ext_state_info *ext_state_info);
-       int (*pi_get_pw_class)(struct pse_controller_dev *pcdev, int id);
-       int (*pi_get_actual_pw)(struct pse_controller_dev *pcdev, int id);
--      int (*pi_is_enabled)(struct pse_controller_dev *pcdev, int id);
-       int (*pi_enable)(struct pse_controller_dev *pcdev, int id);
-       int (*pi_disable)(struct pse_controller_dev *pcdev, int id);
-       int (*pi_get_voltage)(struct pse_controller_dev *pcdev, int id);
diff --git a/target/linux/generic/backport-6.18/626-07-v6.13-net-pse-pd-tps23881-Add-power-limit-and-measurement-features.patch b/target/linux/generic/backport-6.18/626-07-v6.13-net-pse-pd-tps23881-Add-power-limit-and-measurement-features.patch
deleted file mode 100644 (file)
index de3cc76..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-From 7f076ce3f17334964590c2cce49a02c0851c099a Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:29 +0100
-Subject: [PATCH] net: pse-pd: tps23881: Add support for power limit and
- measurement features
-
-Expand PSE callbacks to support the newly introduced
-pi_get/set_pw_limit() and pi_get_voltage() functions. These callbacks
-allow for power limit configuration in the TPS23881 controller.
-
-Additionally, the patch includes the pi_get_pw_class() the
-pi_get_actual_pw(), and the pi_get_pw_limit_ranges') callbacks providing
-more comprehensive PoE status reporting.
-
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/tps23881.c | 258 +++++++++++++++++++++++++++++++++-
- 1 file changed, 256 insertions(+), 2 deletions(-)
-
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -25,20 +25,32 @@
- #define TPS23881_REG_GEN_MASK 0x17
- #define TPS23881_REG_NBITACC  BIT(5)
- #define TPS23881_REG_PW_EN    0x19
-+#define TPS23881_REG_2PAIR_POL1       0x1e
- #define TPS23881_REG_PORT_MAP 0x26
- #define TPS23881_REG_PORT_POWER       0x29
--#define TPS23881_REG_POEPLUS  0x40
-+#define TPS23881_REG_4PAIR_POL1       0x2a
-+#define TPS23881_REG_INPUT_V  0x2e
-+#define TPS23881_REG_CHAN1_A  0x30
-+#define TPS23881_REG_CHAN1_V  0x32
-+#define TPS23881_REG_FOLDBACK 0x40
- #define TPS23881_REG_TPON     BIT(0)
- #define TPS23881_REG_FWREV    0x41
- #define TPS23881_REG_DEVID    0x43
- #define TPS23881_REG_DEVID_MASK       0xF0
- #define TPS23881_DEVICE_ID    0x02
-+#define TPS23881_REG_CHAN1_CLASS      0x4c
- #define TPS23881_REG_SRAM_CTRL        0x60
- #define TPS23881_REG_SRAM_DATA        0x61
-+#define TPS23881_UV_STEP      3662
-+#define TPS23881_NA_STEP      70190
-+#define TPS23881_MW_STEP      500
-+#define TPS23881_MIN_PI_PW_LIMIT_MW   2000
-+
- struct tps23881_port_desc {
-       u8 chan[2];
-       bool is_4p;
-+      int pw_pol;
- };
- struct tps23881_priv {
-@@ -102,6 +114,54 @@ static u16 tps23881_set_val(u16 reg_val,
-       return reg_val;
- }
-+static int
-+tps23881_pi_set_pw_pol_limit(struct tps23881_priv *priv, int id, u8 pw_pol,
-+                           bool is_4p)
-+{
-+      struct i2c_client *client = priv->client;
-+      int ret, reg;
-+      u16 val;
-+      u8 chan;
-+
-+      chan = priv->port[id].chan[0];
-+      if (!is_4p) {
-+              reg = TPS23881_REG_2PAIR_POL1 + (chan % 4);
-+      } else {
-+              /* One chan is enough to configure the 4p PI power limit */
-+              if ((chan % 4) < 2)
-+                      reg = TPS23881_REG_4PAIR_POL1;
-+              else
-+                      reg = TPS23881_REG_4PAIR_POL1 + 1;
-+      }
-+
-+      ret = i2c_smbus_read_word_data(client, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = tps23881_set_val(ret, chan, 0, 0xff, pw_pol);
-+      return i2c_smbus_write_word_data(client, reg, val);
-+}
-+
-+static int tps23881_pi_enable_manual_pol(struct tps23881_priv *priv, int id)
-+{
-+      struct i2c_client *client = priv->client;
-+      int ret;
-+      u8 chan;
-+      u16 val;
-+
-+      ret = i2c_smbus_read_byte_data(client, TPS23881_REG_FOLDBACK);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* No need to test if the chan is PoE4 as setting either bit for a
-+       * 4P configured port disables the automatic configuration on both
-+       * channels.
-+       */
-+      chan = priv->port[id].chan[0];
-+      val = tps23881_set_val(ret, chan, 0, BIT(chan % 4), BIT(chan % 4));
-+      return i2c_smbus_write_byte_data(client, TPS23881_REG_FOLDBACK, val);
-+}
-+
- static int tps23881_pi_enable(struct pse_controller_dev *pcdev, int id)
- {
-       struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-@@ -171,7 +231,21 @@ static int tps23881_pi_disable(struct ps
-                                      BIT(chan % 4));
-       }
--      return i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val);
-+      ret = i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val);
-+      if (ret)
-+              return ret;
-+
-+      /* No power policy */
-+      if (priv->port[id].pw_pol < 0)
-+              return 0;
-+
-+      ret = tps23881_pi_enable_manual_pol(priv, id);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Set power policy */
-+      return tps23881_pi_set_pw_pol_limit(priv, id, priv->port[id].pw_pol,
-+                                          priv->port[id].is_4p);
- }
- static int
-@@ -246,6 +320,177 @@ tps23881_pi_get_pw_status(struct pse_con
-       return 0;
- }
-+static int tps23881_pi_get_voltage(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-+      struct i2c_client *client = priv->client;
-+      int ret;
-+      u64 uV;
-+
-+      ret = i2c_smbus_read_word_data(client, TPS23881_REG_INPUT_V);
-+      if (ret < 0)
-+              return ret;
-+
-+      uV = ret & 0x3fff;
-+      uV *= TPS23881_UV_STEP;
-+
-+      return (int)uV;
-+}
-+
-+static int
-+tps23881_pi_get_chan_current(struct tps23881_priv *priv, u8 chan)
-+{
-+      struct i2c_client *client = priv->client;
-+      int reg, ret;
-+      u64 tmp_64;
-+
-+      /* Registers 0x30 to 0x3d */
-+      reg = TPS23881_REG_CHAN1_A + (chan % 4) * 4 + (chan >= 4);
-+      ret = i2c_smbus_read_word_data(client, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      tmp_64 = ret & 0x3fff;
-+      tmp_64 *= TPS23881_NA_STEP;
-+      /* uA = nA / 1000 */
-+      tmp_64 = DIV_ROUND_CLOSEST_ULL(tmp_64, 1000);
-+      return (int)tmp_64;
-+}
-+
-+static int tps23881_pi_get_pw_class(struct pse_controller_dev *pcdev,
-+                                  int id)
-+{
-+      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-+      struct i2c_client *client = priv->client;
-+      int ret, reg;
-+      u8 chan;
-+
-+      chan = priv->port[id].chan[0];
-+      reg = TPS23881_REG_CHAN1_CLASS + (chan % 4);
-+      ret = i2c_smbus_read_word_data(client, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      return tps23881_calc_val(ret, chan, 4, 0x0f);
-+}
-+
-+static int
-+tps23881_pi_get_actual_pw(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-+      int ret, uV, uA;
-+      u64 tmp_64;
-+      u8 chan;
-+
-+      ret = tps23881_pi_get_voltage(&priv->pcdev, id);
-+      if (ret < 0)
-+              return ret;
-+      uV = ret;
-+
-+      chan = priv->port[id].chan[0];
-+      ret = tps23881_pi_get_chan_current(priv, chan);
-+      if (ret < 0)
-+              return ret;
-+      uA = ret;
-+
-+      if (priv->port[id].is_4p) {
-+              chan = priv->port[id].chan[1];
-+              ret = tps23881_pi_get_chan_current(priv, chan);
-+              if (ret < 0)
-+                      return ret;
-+              uA += ret;
-+      }
-+
-+      tmp_64 = uV;
-+      tmp_64 *= uA;
-+      /* mW = uV * uA / 1000000000 */
-+      return DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
-+}
-+
-+static int
-+tps23881_pi_get_pw_limit_chan(struct tps23881_priv *priv, u8 chan)
-+{
-+      struct i2c_client *client = priv->client;
-+      int ret, reg;
-+      u16 val;
-+
-+      reg = TPS23881_REG_2PAIR_POL1 + (chan % 4);
-+      ret = i2c_smbus_read_word_data(client, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = tps23881_calc_val(ret, chan, 0, 0xff);
-+      return val * TPS23881_MW_STEP;
-+}
-+
-+static int tps23881_pi_get_pw_limit(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-+      int ret, mW;
-+      u8 chan;
-+
-+      chan = priv->port[id].chan[0];
-+      ret = tps23881_pi_get_pw_limit_chan(priv, chan);
-+      if (ret < 0)
-+              return ret;
-+
-+      mW = ret;
-+      if (priv->port[id].is_4p) {
-+              chan = priv->port[id].chan[1];
-+              ret = tps23881_pi_get_pw_limit_chan(priv, chan);
-+              if (ret < 0)
-+                      return ret;
-+              mW += ret;
-+      }
-+
-+      return mW;
-+}
-+
-+static int tps23881_pi_set_pw_limit(struct pse_controller_dev *pcdev,
-+                                  int id, int max_mW)
-+{
-+      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-+      u8 pw_pol;
-+      int ret;
-+
-+      if (max_mW < TPS23881_MIN_PI_PW_LIMIT_MW || MAX_PI_PW < max_mW) {
-+              dev_err(&priv->client->dev,
-+                      "power limit %d out of ranges [%d,%d]",
-+                      max_mW, TPS23881_MIN_PI_PW_LIMIT_MW, MAX_PI_PW);
-+              return -ERANGE;
-+      }
-+
-+      ret = tps23881_pi_enable_manual_pol(priv, id);
-+      if (ret < 0)
-+              return ret;
-+
-+      pw_pol = DIV_ROUND_CLOSEST_ULL(max_mW, TPS23881_MW_STEP);
-+
-+      /* Save power policy to reconfigure it after a disabled call */
-+      priv->port[id].pw_pol = pw_pol;
-+      return tps23881_pi_set_pw_pol_limit(priv, id, pw_pol,
-+                                          priv->port[id].is_4p);
-+}
-+
-+static int
-+tps23881_pi_get_pw_limit_ranges(struct pse_controller_dev *pcdev, int id,
-+                              struct pse_pw_limit_ranges *pw_limit_ranges)
-+{
-+      struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges;
-+
-+      c33_pw_limit_ranges = kzalloc(sizeof(*c33_pw_limit_ranges),
-+                                    GFP_KERNEL);
-+      if (!c33_pw_limit_ranges)
-+              return -ENOMEM;
-+
-+      c33_pw_limit_ranges->min = TPS23881_MIN_PI_PW_LIMIT_MW;
-+      c33_pw_limit_ranges->max = MAX_PI_PW;
-+      pw_limit_ranges->c33_pw_limit_ranges = c33_pw_limit_ranges;
-+
-+      /* Return the number of ranges */
-+      return 1;
-+}
-+
- /* Parse managers subnode into a array of device node */
- static int
- tps23881_get_of_channels(struct tps23881_priv *priv,
-@@ -540,6 +785,9 @@ tps23881_write_port_matrix(struct tps238
-               if (port_matrix[i].exist)
-                       priv->port[pi_id].chan[0] = lgcl_chan;
-+              /* Initialize power policy internal value */
-+              priv->port[pi_id].pw_pol = -1;
-+
-               /* Set hardware port matrix for all ports */
-               val |= hw_chan << (lgcl_chan * 2);
-@@ -665,6 +913,12 @@ static const struct pse_controller_ops t
-       .pi_disable = tps23881_pi_disable,
-       .pi_get_admin_state = tps23881_pi_get_admin_state,
-       .pi_get_pw_status = tps23881_pi_get_pw_status,
-+      .pi_get_pw_class = tps23881_pi_get_pw_class,
-+      .pi_get_actual_pw = tps23881_pi_get_actual_pw,
-+      .pi_get_voltage = tps23881_pi_get_voltage,
-+      .pi_get_pw_limit = tps23881_pi_get_pw_limit,
-+      .pi_set_pw_limit = tps23881_pi_set_pw_limit,
-+      .pi_get_pw_limit_ranges = tps23881_pi_get_pw_limit_ranges,
- };
- static const char fw_parity_name[] = "ti/tps23881/tps23881-parity-14.bin";
diff --git a/target/linux/generic/backport-6.18/626-08-v6.13-net-pse-pd-Fix-missing-PI-of_node-description.patch b/target/linux/generic/backport-6.18/626-08-v6.13-net-pse-pd-Fix-missing-PI-of_node-description.patch
deleted file mode 100644 (file)
index 3aa46cd..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From 10276f3e1c7e7f5de9f0bba58f8a849cb195253d Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:30 +0100
-Subject: [PATCH] net: pse-pd: Fix missing PI of_node description
-
-The PI of_node was not assigned in the regulator_config structure, leading
-to failures in resolving the correct supply when different power supplies
-are assigned to multiple PIs of a PSE controller. This fix ensures that the
-of_node is properly set in the regulator_config, allowing accurate supply
-resolution for each PI.
-
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pse_core.c | 1 +
- 1 file changed, 1 insertion(+)
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -422,6 +422,7 @@ devm_pse_pi_regulator_register(struct ps
-       rconfig.dev = pcdev->dev;
-       rconfig.driver_data = pcdev;
-       rconfig.init_data = rinit_data;
-+      rconfig.of_node = pcdev->pi[id].np;
-       rdev = devm_regulator_register(pcdev->dev, rdesc, &rconfig);
-       if (IS_ERR(rdev)) {
diff --git a/target/linux/generic/backport-6.18/626-09-v6.13-net-pse-pd-Clean-ethtool-header-of-PSE-structures.patch b/target/linux/generic/backport-6.18/626-09-v6.13-net-pse-pd-Clean-ethtool-header-of-PSE-structures.patch
deleted file mode 100644 (file)
index 7d33812..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-From 5385f1e1923ca8131eb143567d509b101a344e06 Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Fri, 10 Jan 2025 10:40:31 +0100
-Subject: [PATCH] net: pse-pd: Clean ethtool header of PSE structures
-
-Remove PSE-specific structures from the ethtool header to improve code
-modularity, maintain independent headers, and reduce incremental build
-time.
-
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pse_core.c |  1 +
- include/linux/ethtool.h       | 20 --------------------
- include/linux/pse-pd/pse.h    | 22 +++++++++++++++++++++-
- 3 files changed, 22 insertions(+), 21 deletions(-)
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -6,6 +6,7 @@
- //
- #include <linux/device.h>
-+#include <linux/ethtool.h>
- #include <linux/of.h>
- #include <linux/pse-pd/pse.h>
- #include <linux/regulator/driver.h>
---- a/include/linux/ethtool.h
-+++ b/include/linux/ethtool.h
-@@ -1322,24 +1322,4 @@ struct ethtool_forced_speed_map {
- void
- ethtool_forced_speed_maps_init(struct ethtool_forced_speed_map *maps, u32 size);
--
--/* C33 PSE extended state and substate. */
--struct ethtool_c33_pse_ext_state_info {
--      enum ethtool_c33_pse_ext_state c33_pse_ext_state;
--      union {
--              enum ethtool_c33_pse_ext_substate_error_condition error_condition;
--              enum ethtool_c33_pse_ext_substate_mr_pse_enable mr_pse_enable;
--              enum ethtool_c33_pse_ext_substate_option_detect_ted option_detect_ted;
--              enum ethtool_c33_pse_ext_substate_option_vport_lim option_vport_lim;
--              enum ethtool_c33_pse_ext_substate_ovld_detected ovld_detected;
--              enum ethtool_c33_pse_ext_substate_power_not_available power_not_available;
--              enum ethtool_c33_pse_ext_substate_short_detected short_detected;
--              u32 __c33_pse_ext_substate;
--      };
--};
--
--struct ethtool_c33_pse_pw_limit_range {
--      u32 min;
--      u32 max;
--};
- #endif /* _LINUX_ETHTOOL_H */
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -5,7 +5,6 @@
- #ifndef _LINUX_PSE_CONTROLLER_H
- #define _LINUX_PSE_CONTROLLER_H
--#include <linux/ethtool.h>
- #include <linux/list.h>
- #include <uapi/linux/ethtool.h>
-@@ -16,6 +15,27 @@
- struct phy_device;
- struct pse_controller_dev;
-+struct netlink_ext_ack;
-+
-+/* C33 PSE extended state and substate. */
-+struct ethtool_c33_pse_ext_state_info {
-+      enum ethtool_c33_pse_ext_state c33_pse_ext_state;
-+      union {
-+              enum ethtool_c33_pse_ext_substate_error_condition error_condition;
-+              enum ethtool_c33_pse_ext_substate_mr_pse_enable mr_pse_enable;
-+              enum ethtool_c33_pse_ext_substate_option_detect_ted option_detect_ted;
-+              enum ethtool_c33_pse_ext_substate_option_vport_lim option_vport_lim;
-+              enum ethtool_c33_pse_ext_substate_ovld_detected ovld_detected;
-+              enum ethtool_c33_pse_ext_substate_power_not_available power_not_available;
-+              enum ethtool_c33_pse_ext_substate_short_detected short_detected;
-+              u32 __c33_pse_ext_substate;
-+      };
-+};
-+
-+struct ethtool_c33_pse_pw_limit_range {
-+      u32 min;
-+      u32 max;
-+};
- /**
-  * struct pse_control_config - PSE control/channel configuration.
diff --git a/target/linux/generic/backport-6.18/626-10-v6.17-net-pse-pd-Introduce-attached_phydev-to-pse-control.patch b/target/linux/generic/backport-6.18/626-10-v6.17-net-pse-pd-Introduce-attached_phydev-to-pse-control.patch
deleted file mode 100644 (file)
index b00c0e1..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-From fa2f0454174c2f33005f5a6e6f70c7160a15b2a1 Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:00 +0200
-Subject: [PATCH] net: pse-pd: Introduce attached_phydev to pse control
-
-In preparation for reporting PSE events via ethtool notifications,
-introduce an attached_phydev field in the pse_control structure.
-This field stores the phy_device associated with the PSE PI,
-ensuring that notifications are sent to the correct network
-interface.
-
-The attached_phydev pointer is directly tied to the PHY lifecycle. It
-is set when the PHY is registered and cleared when the PHY is removed.
-There is no need to use a refcount, as doing so could interfere with
-the PHY removal process.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-1-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/mdio/fwnode_mdio.c | 26 ++++++++++++++------------
- drivers/net/pse-pd/pse_core.c  | 11 ++++++++---
- include/linux/pse-pd/pse.h     |  6 ++++--
- 3 files changed, 26 insertions(+), 17 deletions(-)
---- a/drivers/net/mdio/fwnode_mdio.c
-+++ b/drivers/net/mdio/fwnode_mdio.c
-@@ -18,7 +18,8 @@ MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("FWNODE MDIO bus (Ethernet PHY) accessors");
- static struct pse_control *
--fwnode_find_pse_control(struct fwnode_handle *fwnode)
-+fwnode_find_pse_control(struct fwnode_handle *fwnode,
-+                      struct phy_device *phydev)
- {
-       struct pse_control *psec;
-       struct device_node *np;
-@@ -30,7 +31,7 @@ fwnode_find_pse_control(struct fwnode_ha
-       if (!np)
-               return NULL;
--      psec = of_pse_control_get(np);
-+      psec = of_pse_control_get(np, phydev);
-       if (PTR_ERR(psec) == -ENOENT)
-               return NULL;
-@@ -128,15 +129,9 @@ int fwnode_mdiobus_register_phy(struct m
-       u32 phy_id;
-       int rc;
--      psec = fwnode_find_pse_control(child);
--      if (IS_ERR(psec))
--              return PTR_ERR(psec);
--
-       mii_ts = fwnode_find_mii_timestamper(child);
--      if (IS_ERR(mii_ts)) {
--              rc = PTR_ERR(mii_ts);
--              goto clean_pse;
--      }
-+      if (IS_ERR(mii_ts))
-+              return PTR_ERR(mii_ts);
-       is_c45 = fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45");
-       if (is_c45 || fwnode_get_phy_id(child, &phy_id))
-@@ -169,6 +164,12 @@ int fwnode_mdiobus_register_phy(struct m
-                       goto clean_phy;
-       }
-+      psec = fwnode_find_pse_control(child, phy);
-+      if (IS_ERR(psec)) {
-+              rc = PTR_ERR(psec);
-+              goto unregister_phy;
-+      }
-+
-       phy->psec = psec;
-       /* phy->mii_ts may already be defined by the PHY driver. A
-@@ -180,12 +181,13 @@ int fwnode_mdiobus_register_phy(struct m
-       return 0;
-+unregister_phy:
-+      if (is_acpi_node(child) || is_of_node(child))
-+              phy_device_remove(phy);
- clean_phy:
-       phy_device_free(phy);
- clean_mii_ts:
-       unregister_mii_timestamper(mii_ts);
--clean_pse:
--      pse_control_put(psec);
-       return rc;
- }
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -23,6 +23,7 @@ static LIST_HEAD(pse_controller_list);
-  * @list: list entry for the pcdev's PSE controller list
-  * @id: ID of the PSE line in the PSE controller device
-  * @refcnt: Number of gets of this pse_control
-+ * @attached_phydev: PHY device pointer attached by the PSE control
-  */
- struct pse_control {
-       struct pse_controller_dev *pcdev;
-@@ -30,6 +31,7 @@ struct pse_control {
-       struct list_head list;
-       unsigned int id;
-       struct kref refcnt;
-+      struct phy_device *attached_phydev;
- };
- static int of_load_single_pse_pi_pairset(struct device_node *node,
-@@ -599,7 +601,8 @@ void pse_control_put(struct pse_control
- EXPORT_SYMBOL_GPL(pse_control_put);
- static struct pse_control *
--pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index)
-+pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index,
-+                       struct phy_device *phydev)
- {
-       struct pse_control *psec;
-       int ret;
-@@ -638,6 +641,7 @@ pse_control_get_internal(struct pse_cont
-       psec->pcdev = pcdev;
-       list_add(&psec->list, &pcdev->pse_control_head);
-       psec->id = index;
-+      psec->attached_phydev = phydev;
-       kref_init(&psec->refcnt);
-       return psec;
-@@ -693,7 +697,8 @@ static int psec_id_xlate(struct pse_cont
-       return pse_spec->args[0];
- }
--struct pse_control *of_pse_control_get(struct device_node *node)
-+struct pse_control *of_pse_control_get(struct device_node *node,
-+                                     struct phy_device *phydev)
- {
-       struct pse_controller_dev *r, *pcdev;
-       struct of_phandle_args args;
-@@ -743,7 +748,7 @@ struct pse_control *of_pse_control_get(s
-       }
-       /* pse_list_mutex also protects the pcdev's pse_control list */
--      psec = pse_control_get_internal(pcdev, psec_id);
-+      psec = pse_control_get_internal(pcdev, psec_id, phydev);
- out:
-       mutex_unlock(&pse_list_mutex);
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -250,7 +250,8 @@ struct device;
- int devm_pse_controller_register(struct device *dev,
-                                struct pse_controller_dev *pcdev);
--struct pse_control *of_pse_control_get(struct device_node *node);
-+struct pse_control *of_pse_control_get(struct device_node *node,
-+                                     struct phy_device *phydev);
- void pse_control_put(struct pse_control *psec);
- int pse_ethtool_get_status(struct pse_control *psec,
-@@ -270,7 +271,8 @@ bool pse_has_c33(struct pse_control *pse
- #else
--static inline struct pse_control *of_pse_control_get(struct device_node *node)
-+static inline struct pse_control *of_pse_control_get(struct device_node *node,
-+                                                   struct phy_device *phydev)
- {
-       return ERR_PTR(-ENOENT);
- }
diff --git a/target/linux/generic/backport-6.18/626-11-v6.17-net-pse-pd-Add-support-for-reporting-events.patch b/target/linux/generic/backport-6.18/626-11-v6.17-net-pse-pd-Add-support-for-reporting-events.patch
deleted file mode 100644 (file)
index ec99fca..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-# ADAPTED FOR OPENWRT 6.12.67 - Documentation changes removed
-# Original commit: fc0e6db30941
-From fc0e6db30941a66e284b8516b82356f97f31061d Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:01 +0200
-Subject: [PATCH] net: pse-pd: Add support for reporting events
-
-Add support for devm_pse_irq_helper() to register PSE interrupts and report
-events such as over-current or over-temperature conditions. This follows a
-similar approach to the regulator API but also sends notifications using a
-dedicated PSE ethtool netlink socket.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-2-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- Documentation/netlink/specs/ethtool.yaml      |  34 ++++
- Documentation/networking/ethtool-netlink.rst  |  19 ++
- drivers/net/pse-pd/pse_core.c                 | 179 ++++++++++++++++++
- include/linux/ethtool_netlink.h               |   7 +
- include/linux/pse-pd/pse.h                    |  20 ++
- .../uapi/linux/ethtool_netlink_generated.h    |  19 ++
- net/ethtool/pse-pd.c                          |  39 ++++
- 7 files changed, 317 insertions(+)
-
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -7,10 +7,14 @@
- #include <linux/device.h>
- #include <linux/ethtool.h>
-+#include <linux/ethtool_netlink.h>
- #include <linux/of.h>
-+#include <linux/phy.h>
- #include <linux/pse-pd/pse.h>
- #include <linux/regulator/driver.h>
- #include <linux/regulator/machine.h>
-+#include <linux/rtnetlink.h>
-+#include <net/net_trackers.h>
- static DEFINE_MUTEX(pse_list_mutex);
- static LIST_HEAD(pse_controller_list);
-@@ -210,6 +214,48 @@ out:
-       return ret;
- }
-+/**
-+ * pse_control_find_net_by_id - Find net attached to the pse control id
-+ * @pcdev: a pointer to the PSE
-+ * @id: index of the PSE control
-+ *
-+ * Return: pse_control pointer or NULL. The device returned has had a
-+ *       reference added and the pointer is safe until the user calls
-+ *       pse_control_put() to indicate they have finished with it.
-+ */
-+static struct pse_control *
-+pse_control_find_by_id(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct pse_control *psec;
-+
-+      mutex_lock(&pse_list_mutex);
-+      list_for_each_entry(psec, &pcdev->pse_control_head, list) {
-+              if (psec->id == id) {
-+                      kref_get(&psec->refcnt);
-+                      mutex_unlock(&pse_list_mutex);
-+                      return psec;
-+              }
-+      }
-+      mutex_unlock(&pse_list_mutex);
-+      return NULL;
-+}
-+
-+/**
-+ * pse_control_get_netdev - Return netdev associated to a PSE control
-+ * @psec: PSE control pointer
-+ *
-+ * Return: netdev pointer or NULL
-+ */
-+static struct net_device *pse_control_get_netdev(struct pse_control *psec)
-+{
-+      ASSERT_RTNL();
-+
-+      if (!psec || !psec->attached_phydev)
-+              return NULL;
-+
-+      return psec->attached_phydev->attached_dev;
-+}
-+
- static int pse_pi_is_enabled(struct regulator_dev *rdev)
- {
-       struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
-@@ -559,6 +605,139 @@ int devm_pse_controller_register(struct
- }
- EXPORT_SYMBOL_GPL(devm_pse_controller_register);
-+struct pse_irq {
-+      struct pse_controller_dev *pcdev;
-+      struct pse_irq_desc desc;
-+      unsigned long *notifs;
-+};
-+
-+/**
-+ * pse_to_regulator_notifs - Convert PSE notifications to Regulator
-+ *                         notifications
-+ * @notifs: PSE notifications
-+ *
-+ * Return: Regulator notifications
-+ */
-+static unsigned long pse_to_regulator_notifs(unsigned long notifs)
-+{
-+      unsigned long rnotifs = 0;
-+
-+      if (notifs & ETHTOOL_PSE_EVENT_OVER_CURRENT)
-+              rnotifs |= REGULATOR_EVENT_OVER_CURRENT;
-+      if (notifs & ETHTOOL_PSE_EVENT_OVER_TEMP)
-+              rnotifs |= REGULATOR_EVENT_OVER_TEMP;
-+
-+      return rnotifs;
-+}
-+
-+/**
-+ * pse_isr - IRQ handler for PSE
-+ * @irq: irq number
-+ * @data: pointer to user interrupt structure
-+ *
-+ * Return: irqreturn_t - status of IRQ
-+ */
-+static irqreturn_t pse_isr(int irq, void *data)
-+{
-+      struct pse_controller_dev *pcdev;
-+      unsigned long notifs_mask = 0;
-+      struct pse_irq_desc *desc;
-+      struct pse_irq *h = data;
-+      int ret, i;
-+
-+      desc = &h->desc;
-+      pcdev = h->pcdev;
-+
-+      /* Clear notifs mask */
-+      memset(h->notifs, 0, pcdev->nr_lines * sizeof(*h->notifs));
-+      mutex_lock(&pcdev->lock);
-+      ret = desc->map_event(irq, pcdev, h->notifs, &notifs_mask);
-+      mutex_unlock(&pcdev->lock);
-+      if (ret || !notifs_mask)
-+              return IRQ_NONE;
-+
-+      for_each_set_bit(i, &notifs_mask, pcdev->nr_lines) {
-+              unsigned long notifs, rnotifs;
-+              struct net_device *netdev;
-+              struct pse_control *psec;
-+
-+              /* Do nothing PI not described */
-+              if (!pcdev->pi[i].rdev)
-+                      continue;
-+
-+              notifs = h->notifs[i];
-+              dev_dbg(h->pcdev->dev,
-+                      "Sending PSE notification EVT 0x%lx\n", notifs);
-+
-+              psec = pse_control_find_by_id(pcdev, i);
-+              rtnl_lock();
-+              netdev = pse_control_get_netdev(psec);
-+              if (netdev)
-+                      ethnl_pse_send_ntf(netdev, notifs);
-+              rtnl_unlock();
-+              pse_control_put(psec);
-+
-+              rnotifs = pse_to_regulator_notifs(notifs);
-+              regulator_notifier_call_chain(pcdev->pi[i].rdev, rnotifs,
-+                                            NULL);
-+      }
-+
-+      return IRQ_HANDLED;
-+}
-+
-+/**
-+ * devm_pse_irq_helper - Register IRQ based PSE event notifier
-+ * @pcdev: a pointer to the PSE
-+ * @irq: the irq value to be passed to request_irq
-+ * @irq_flags: the flags to be passed to request_irq
-+ * @d: PSE interrupt description
-+ *
-+ * Return: 0 on success and errno on failure
-+ */
-+int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
-+                      int irq_flags, const struct pse_irq_desc *d)
-+{
-+      struct device *dev = pcdev->dev;
-+      size_t irq_name_len;
-+      struct pse_irq *h;
-+      char *irq_name;
-+      int ret;
-+
-+      if (!d || !d->map_event || !d->name)
-+              return -EINVAL;
-+
-+      h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
-+      if (!h)
-+              return -ENOMEM;
-+
-+      h->pcdev = pcdev;
-+      h->desc = *d;
-+
-+      /* IRQ name len is pcdev dev name + 5 char + irq desc name + 1 */
-+      irq_name_len = strlen(dev_name(pcdev->dev)) + 5 + strlen(d->name) + 1;
-+      irq_name = devm_kzalloc(dev, irq_name_len, GFP_KERNEL);
-+      if (!irq_name)
-+              return -ENOMEM;
-+
-+      snprintf(irq_name, irq_name_len, "pse-%s:%s", dev_name(pcdev->dev),
-+               d->name);
-+
-+      h->notifs = devm_kcalloc(dev, pcdev->nr_lines,
-+                               sizeof(*h->notifs), GFP_KERNEL);
-+      if (!h->notifs)
-+              return -ENOMEM;
-+
-+      ret = devm_request_threaded_irq(dev, irq, NULL, pse_isr,
-+                                      IRQF_ONESHOT | irq_flags,
-+                                      irq_name, h);
-+      if (ret)
-+              dev_err(pcdev->dev, "Failed to request IRQ %d\n", irq);
-+
-+      pcdev->irq = irq;
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(devm_pse_irq_helper);
-+
- /* PSE control section */
- static void __pse_control_release(struct kref *kref)
---- a/include/linux/ethtool_netlink.h
-+++ b/include/linux/ethtool_netlink.h
-@@ -43,6 +43,8 @@ void ethtool_aggregate_rmon_stats(struct
-                                 struct ethtool_rmon_stats *rmon_stats);
- bool ethtool_dev_mm_supported(struct net_device *dev);
-+void ethnl_pse_send_ntf(struct net_device *netdev, unsigned long notif);
-+
- #else
- static inline int ethnl_cable_test_alloc(struct phy_device *phydev, u8 cmd)
- {
-@@ -120,6 +122,11 @@ static inline bool ethtool_dev_mm_suppor
-       return false;
- }
-+static inline void ethnl_pse_send_ntf(struct phy_device *phydev,
-+                                    unsigned long notif)
-+{
-+}
-+
- #endif /* IS_ENABLED(CONFIG_ETHTOOL_NETLINK) */
- static inline int ethnl_cable_test_result(struct phy_device *phydev, u8 pair,
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -7,12 +7,15 @@
- #include <linux/list.h>
- #include <uapi/linux/ethtool.h>
-+#include <uapi/linux/ethtool_netlink_generated.h>
-+#include <linux/regulator/driver.h>
- /* Maximum current in uA according to IEEE 802.3-2022 Table 145-1 */
- #define MAX_PI_CURRENT 1920000
- /* Maximum power in mW according to IEEE 802.3-2022 Table 145-16 */
- #define MAX_PI_PW 99900
-+struct net_device;
- struct phy_device;
- struct pse_controller_dev;
- struct netlink_ext_ack;
-@@ -38,6 +41,19 @@ struct ethtool_c33_pse_pw_limit_range {
- };
- /**
-+ * struct pse_irq_desc - notification sender description for IRQ based events.
-+ *
-+ * @name: the visible name for the IRQ
-+ * @map_event: driver callback to map IRQ status into PSE devices with events.
-+ */
-+struct pse_irq_desc {
-+      const char *name;
-+      int (*map_event)(int irq, struct pse_controller_dev *pcdev,
-+                       unsigned long *notifs,
-+                       unsigned long *notifs_mask);
-+};
-+
-+/**
-  * struct pse_control_config - PSE control/channel configuration.
-  *
-  * @podl_admin_control: set PoDL PSE admin control as described in
-@@ -228,6 +244,7 @@ struct pse_pi {
-  * @types: types of the PSE controller
-  * @pi: table of PSE PIs described in this controller device
-  * @no_of_pse_pi: flag set if the pse_pis devicetree node is not used
-+ * @irq: PSE interrupt
-  */
- struct pse_controller_dev {
-       const struct pse_controller_ops *ops;
-@@ -241,6 +258,7 @@ struct pse_controller_dev {
-       enum ethtool_pse_types types;
-       struct pse_pi *pi;
-       bool no_of_pse_pi;
-+      int irq;
- };
- #if IS_ENABLED(CONFIG_PSE_CONTROLLER)
-@@ -249,6 +267,8 @@ void pse_controller_unregister(struct ps
- struct device;
- int devm_pse_controller_register(struct device *dev,
-                                struct pse_controller_dev *pcdev);
-+int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
-+                      int irq_flags, const struct pse_irq_desc *d);
- struct pse_control *of_pse_control_get(struct device_node *node,
-                                      struct phy_device *phydev);
---- a/net/ethtool/pse-pd.c
-+++ b/net/ethtool/pse-pd.c
-@@ -315,3 +315,42 @@ const struct ethnl_request_ops ethnl_pse
-       .set                    = ethnl_set_pse,
-       /* PSE has no notification */
- };
-+
-+void ethnl_pse_send_ntf(struct net_device *netdev, unsigned long notifs)
-+{
-+      void *reply_payload;
-+      struct sk_buff *skb;
-+      int reply_len;
-+      int ret;
-+
-+      ASSERT_RTNL();
-+
-+      if (!netdev || !notifs)
-+              return;
-+
-+      reply_len = ethnl_reply_header_size() +
-+                  nla_total_size(sizeof(u32)); /* _PSE_NTF_EVENTS */
-+
-+      skb = genlmsg_new(reply_len, GFP_KERNEL);
-+      if (!skb)
-+              return;
-+
-+      reply_payload = ethnl_bcastmsg_put(skb, ETHTOOL_MSG_PSE_NTF);
-+      if (!reply_payload)
-+              goto err_skb;
-+
-+      ret = ethnl_fill_reply_header(skb, netdev, ETHTOOL_A_PSE_NTF_HEADER);
-+      if (ret < 0)
-+              goto err_skb;
-+
-+      if (nla_put_uint(skb, ETHTOOL_A_PSE_NTF_EVENTS, notifs))
-+              goto err_skb;
-+
-+      genlmsg_end(skb, reply_payload);
-+      ethnl_multicast(skb, netdev);
-+      return;
-+
-+err_skb:
-+      nlmsg_free(skb);
-+}
-+EXPORT_SYMBOL_GPL(ethnl_pse_send_ntf);
diff --git a/target/linux/generic/backport-6.18/626-12-v6.17-net-pse-pd-tps23881-Add-support-for-PSE-events.patch b/target/linux/generic/backport-6.18/626-12-v6.17-net-pse-pd-tps23881-Add-support-for-PSE-events.patch
deleted file mode 100644 (file)
index 8afcb3f..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-From f5e7aecaa4efcd4c85477b6a62f94fea668031db Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:02 +0200
-Subject: [PATCH] net: pse-pd: tps23881: Add support for PSE events and
- interrupts
-
-Add support for PSE event reporting through interrupts. Set up the newly
-introduced devm_pse_irq_helper helper to register the interrupt. Events are
-reported for over-current and over-temperature conditions.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-3-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/tps23881.c | 189 +++++++++++++++++++++++++++++++++-
- 1 file changed, 187 insertions(+), 2 deletions(-)
-
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -16,7 +16,15 @@
- #include <linux/pse-pd/pse.h>
- #define TPS23881_MAX_CHANS 8
-+#define TPS23881_MAX_IRQ_RETRIES 10
-+#define TPS23881_REG_IT               0x0
-+#define TPS23881_REG_IT_MASK  0x1
-+#define TPS23881_REG_IT_IFAULT        BIT(5)
-+#define TPS23881_REG_IT_SUPF  BIT(7)
-+#define TPS23881_REG_FAULT    0x7
-+#define TPS23881_REG_SUPF_EVENT       0xb
-+#define TPS23881_REG_TSD      BIT(7)
- #define TPS23881_REG_PW_STATUS        0x10
- #define TPS23881_REG_OP_MODE  0x12
- #define TPS23881_OP_MODE_SEMIAUTO     0xaaaa
-@@ -24,6 +32,7 @@
- #define TPS23881_REG_DET_CLA_EN       0x14
- #define TPS23881_REG_GEN_MASK 0x17
- #define TPS23881_REG_NBITACC  BIT(5)
-+#define TPS23881_REG_INTEN    BIT(7)
- #define TPS23881_REG_PW_EN    0x19
- #define TPS23881_REG_2PAIR_POL1       0x1e
- #define TPS23881_REG_PORT_MAP 0x26
-@@ -51,6 +60,7 @@ struct tps23881_port_desc {
-       u8 chan[2];
-       bool is_4p;
-       int pw_pol;
-+      bool exist;
- };
- struct tps23881_priv {
-@@ -782,8 +792,10 @@ tps23881_write_port_matrix(struct tps238
-               hw_chan = port_matrix[i].hw_chan[0] % 4;
-               /* Set software port matrix for existing ports */
--              if (port_matrix[i].exist)
-+              if (port_matrix[i].exist) {
-                       priv->port[pi_id].chan[0] = lgcl_chan;
-+                      priv->port[pi_id].exist = true;
-+              }
-               /* Initialize power policy internal value */
-               priv->port[pi_id].pw_pol = -1;
-@@ -1017,6 +1029,173 @@ static int tps23881_flash_sram_fw(struct
-       return 0;
- }
-+/* Convert interrupt events to 0xff to be aligned with the chan
-+ * number.
-+ */
-+static u8 tps23881_irq_export_chans_helper(u16 reg_val, u8 field_offset)
-+{
-+      u8 val;
-+
-+      val = (reg_val >> (4 + field_offset) & 0xf0) |
-+            (reg_val >> field_offset & 0x0f);
-+
-+      return val;
-+}
-+
-+/* Convert chan number to port number */
-+static void tps23881_set_notifs_helper(struct tps23881_priv *priv,
-+                                     u8 chans,
-+                                     unsigned long *notifs,
-+                                     unsigned long *notifs_mask,
-+                                     enum ethtool_pse_event event)
-+{
-+      u8 chan;
-+      int i;
-+
-+      if (!chans)
-+              return;
-+
-+      for (i = 0; i < TPS23881_MAX_CHANS; i++) {
-+              if (!priv->port[i].exist)
-+                      continue;
-+              /* No need to look at the 2nd channel in case of PoE4 as
-+               * both registers are set.
-+               */
-+              chan = priv->port[i].chan[0];
-+
-+              if (BIT(chan) & chans) {
-+                      *notifs_mask |= BIT(i);
-+                      notifs[i] |= event;
-+              }
-+      }
-+}
-+
-+static void tps23881_irq_event_over_temp(struct tps23881_priv *priv,
-+                                       u16 reg_val,
-+                                       unsigned long *notifs,
-+                                       unsigned long *notifs_mask)
-+{
-+      int i;
-+
-+      if (reg_val & TPS23881_REG_TSD) {
-+              for (i = 0; i < TPS23881_MAX_CHANS; i++) {
-+                      if (!priv->port[i].exist)
-+                              continue;
-+
-+                      *notifs_mask |= BIT(i);
-+                      notifs[i] |= ETHTOOL_PSE_EVENT_OVER_TEMP;
-+              }
-+      }
-+}
-+
-+static void tps23881_irq_event_over_current(struct tps23881_priv *priv,
-+                                          u16 reg_val,
-+                                          unsigned long *notifs,
-+                                          unsigned long *notifs_mask)
-+{
-+      u8 chans;
-+
-+      chans = tps23881_irq_export_chans_helper(reg_val, 0);
-+      if (chans)
-+              tps23881_set_notifs_helper(priv, chans, notifs, notifs_mask,
-+                                         ETHTOOL_PSE_EVENT_OVER_CURRENT);
-+}
-+
-+static int tps23881_irq_event_handler(struct tps23881_priv *priv, u16 reg,
-+                                    unsigned long *notifs,
-+                                    unsigned long *notifs_mask)
-+{
-+      struct i2c_client *client = priv->client;
-+      int ret;
-+
-+      /* The Supply event bit is repeated twice so we only need to read
-+       * the one from the first byte.
-+       */
-+      if (reg & TPS23881_REG_IT_SUPF) {
-+              ret = i2c_smbus_read_word_data(client, TPS23881_REG_SUPF_EVENT);
-+              if (ret < 0)
-+                      return ret;
-+              tps23881_irq_event_over_temp(priv, ret, notifs, notifs_mask);
-+      }
-+
-+      if (reg & (TPS23881_REG_IT_IFAULT | TPS23881_REG_IT_IFAULT << 8)) {
-+              ret = i2c_smbus_read_word_data(client, TPS23881_REG_FAULT);
-+              if (ret < 0)
-+                      return ret;
-+              tps23881_irq_event_over_current(priv, ret, notifs, notifs_mask);
-+      }
-+
-+      return 0;
-+}
-+
-+static int tps23881_irq_handler(int irq, struct pse_controller_dev *pcdev,
-+                              unsigned long *notifs,
-+                              unsigned long *notifs_mask)
-+{
-+      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-+      struct i2c_client *client = priv->client;
-+      int ret, it_mask, retry;
-+
-+      /* Get interruption mask */
-+      ret = i2c_smbus_read_word_data(client, TPS23881_REG_IT_MASK);
-+      if (ret < 0)
-+              return ret;
-+      it_mask = ret;
-+
-+      /* Read interrupt register until it frees the interruption pin. */
-+      retry = 0;
-+      while (true) {
-+              if (retry > TPS23881_MAX_IRQ_RETRIES) {
-+                      dev_err(&client->dev, "interrupt never freed");
-+                      return -ETIMEDOUT;
-+              }
-+
-+              ret = i2c_smbus_read_word_data(client, TPS23881_REG_IT);
-+              if (ret < 0)
-+                      return ret;
-+
-+              /* No more relevant interruption */
-+              if (!(ret & it_mask))
-+                      return 0;
-+
-+              ret = tps23881_irq_event_handler(priv, (u16)ret, notifs,
-+                                               notifs_mask);
-+              if (ret)
-+                      return ret;
-+
-+              retry++;
-+      }
-+      return 0;
-+}
-+
-+static int tps23881_setup_irq(struct tps23881_priv *priv, int irq)
-+{
-+      struct i2c_client *client = priv->client;
-+      struct pse_irq_desc irq_desc = {
-+              .name = "tps23881-irq",
-+              .map_event = tps23881_irq_handler,
-+      };
-+      int ret;
-+      u16 val;
-+
-+      val = TPS23881_REG_IT_IFAULT | TPS23881_REG_IT_SUPF;
-+      val |= val << 8;
-+      ret = i2c_smbus_write_word_data(client, TPS23881_REG_IT_MASK, val);
-+      if (ret)
-+              return ret;
-+
-+      ret = i2c_smbus_read_word_data(client, TPS23881_REG_GEN_MASK);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = (u16)(ret | TPS23881_REG_INTEN | TPS23881_REG_INTEN << 8);
-+      ret = i2c_smbus_write_word_data(client, TPS23881_REG_GEN_MASK, val);
-+      if (ret < 0)
-+              return ret;
-+
-+      return devm_pse_irq_helper(&priv->pcdev, irq, 0, &irq_desc);
-+}
-+
- static int tps23881_i2c_probe(struct i2c_client *client)
- {
-       struct device *dev = &client->dev;
-@@ -1097,6 +1276,12 @@ static int tps23881_i2c_probe(struct i2c
-                                    "failed to register PSE controller\n");
-       }
-+      if (client->irq) {
-+              ret = tps23881_setup_irq(priv, client->irq);
-+              if (ret)
-+                      return ret;
-+      }
-+
-       return ret;
- }
diff --git a/target/linux/generic/backport-6.18/626-13-v6.17-net-pse-pd-Add-support-for-PSE-power-domains.patch b/target/linux/generic/backport-6.18/626-13-v6.17-net-pse-pd-Add-support-for-PSE-power-domains.patch
deleted file mode 100644 (file)
index a02bbbc..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-From 50f8b341d26826aa5fdccb8f497fbff2500934b3 Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:03 +0200
-Subject: [PATCH] net: pse-pd: Add support for PSE power domains
-
-Introduce PSE power domain support as groundwork for upcoming port
-priority features. Multiple PSE PIs can now be grouped under a single
-PSE power domain, enabling future enhancements like defining available
-power budgets, port priority modes, and disconnection policies. This
-setup will allow the system to assess whether activating a port would
-exceed the available power budget, preventing over-budget states
-proactively.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-4-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pse_core.c | 140 ++++++++++++++++++++++++++++++++++
- include/linux/pse-pd/pse.h    |   2 +
- 2 files changed, 142 insertions(+)
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -16,8 +16,12 @@
- #include <linux/rtnetlink.h>
- #include <net/net_trackers.h>
-+#define PSE_PW_D_LIMIT INT_MAX
-+
- static DEFINE_MUTEX(pse_list_mutex);
- static LIST_HEAD(pse_controller_list);
-+static DEFINE_XARRAY_ALLOC(pse_pw_d_map);
-+static DEFINE_MUTEX(pse_pw_d_mutex);
- /**
-  * struct pse_control - a PSE control
-@@ -38,6 +42,18 @@ struct pse_control {
-       struct phy_device *attached_phydev;
- };
-+/**
-+ * struct pse_power_domain - a PSE power domain
-+ * @id: ID of the power domain
-+ * @supply: Power supply the Power Domain
-+ * @refcnt: Number of gets of this pse_power_domain
-+ */
-+struct pse_power_domain {
-+      int id;
-+      struct regulator *supply;
-+      struct kref refcnt;
-+};
-+
- static int of_load_single_pse_pi_pairset(struct device_node *node,
-                                        struct pse_pi *pi,
-                                        int pairset_num)
-@@ -485,6 +501,125 @@ devm_pse_pi_regulator_register(struct ps
-       return 0;
- }
-+static void __pse_pw_d_release(struct kref *kref)
-+{
-+      struct pse_power_domain *pw_d = container_of(kref,
-+                                                   struct pse_power_domain,
-+                                                   refcnt);
-+
-+      regulator_put(pw_d->supply);
-+      xa_erase(&pse_pw_d_map, pw_d->id);
-+      mutex_unlock(&pse_pw_d_mutex);
-+}
-+
-+/**
-+ * pse_flush_pw_ds - flush all PSE power domains of a PSE
-+ * @pcdev: a pointer to the initialized PSE controller device
-+ */
-+static void pse_flush_pw_ds(struct pse_controller_dev *pcdev)
-+{
-+      struct pse_power_domain *pw_d;
-+      int i;
-+
-+      for (i = 0; i < pcdev->nr_lines; i++) {
-+              if (!pcdev->pi[i].pw_d)
-+                      continue;
-+
-+              pw_d = xa_load(&pse_pw_d_map, pcdev->pi[i].pw_d->id);
-+              if (!pw_d)
-+                      continue;
-+
-+              kref_put_mutex(&pw_d->refcnt, __pse_pw_d_release,
-+                             &pse_pw_d_mutex);
-+      }
-+}
-+
-+/**
-+ * devm_pse_alloc_pw_d - allocate a new PSE power domain for a device
-+ * @dev: device that is registering this PSE power domain
-+ *
-+ * Return: Pointer to the newly allocated PSE power domain or error pointers
-+ */
-+static struct pse_power_domain *devm_pse_alloc_pw_d(struct device *dev)
-+{
-+      struct pse_power_domain *pw_d;
-+      int index, ret;
-+
-+      pw_d = devm_kzalloc(dev, sizeof(*pw_d), GFP_KERNEL);
-+      if (!pw_d)
-+              return ERR_PTR(-ENOMEM);
-+
-+      ret = xa_alloc(&pse_pw_d_map, &index, pw_d, XA_LIMIT(1, PSE_PW_D_LIMIT),
-+                     GFP_KERNEL);
-+      if (ret)
-+              return ERR_PTR(ret);
-+
-+      kref_init(&pw_d->refcnt);
-+      pw_d->id = index;
-+      return pw_d;
-+}
-+
-+/**
-+ * pse_register_pw_ds - register the PSE power domains for a PSE
-+ * @pcdev: a pointer to the PSE controller device
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+static int pse_register_pw_ds(struct pse_controller_dev *pcdev)
-+{
-+      int i, ret = 0;
-+
-+      mutex_lock(&pse_pw_d_mutex);
-+      for (i = 0; i < pcdev->nr_lines; i++) {
-+              struct regulator_dev *rdev = pcdev->pi[i].rdev;
-+              struct pse_power_domain *pw_d;
-+              struct regulator *supply;
-+              bool present = false;
-+              unsigned long index;
-+
-+              /* No regulator or regulator parent supply registered.
-+               * We need a regulator parent to register a PSE power domain
-+               */
-+              if (!rdev || !rdev->supply)
-+                      continue;
-+
-+              xa_for_each(&pse_pw_d_map, index, pw_d) {
-+                      /* Power supply already registered as a PSE power
-+                       * domain.
-+                       */
-+                      if (regulator_is_equal(pw_d->supply, rdev->supply)) {
-+                              present = true;
-+                              pcdev->pi[i].pw_d = pw_d;
-+                              break;
-+                      }
-+              }
-+              if (present) {
-+                      kref_get(&pw_d->refcnt);
-+                      continue;
-+              }
-+
-+              pw_d = devm_pse_alloc_pw_d(pcdev->dev);
-+              if (IS_ERR(pw_d)) {
-+                      ret = PTR_ERR(pw_d);
-+                      goto out;
-+              }
-+
-+              supply = regulator_get(&rdev->dev, rdev->supply_name);
-+              if (IS_ERR(supply)) {
-+                      xa_erase(&pse_pw_d_map, pw_d->id);
-+                      ret = PTR_ERR(supply);
-+                      goto out;
-+              }
-+
-+              pw_d->supply = supply;
-+              pcdev->pi[i].pw_d = pw_d;
-+      }
-+
-+out:
-+      mutex_unlock(&pse_pw_d_mutex);
-+      return ret;
-+}
-+
- /**
-  * pse_controller_register - register a PSE controller device
-  * @pcdev: a pointer to the initialized PSE controller device
-@@ -544,6 +679,10 @@ int pse_controller_register(struct pse_c
-                       return ret;
-       }
-+      ret = pse_register_pw_ds(pcdev);
-+      if (ret)
-+              return ret;
-+
-       mutex_lock(&pse_list_mutex);
-       list_add(&pcdev->list, &pse_controller_list);
-       mutex_unlock(&pse_list_mutex);
-@@ -558,6 +697,7 @@ EXPORT_SYMBOL_GPL(pse_controller_registe
-  */
- void pse_controller_unregister(struct pse_controller_dev *pcdev)
- {
-+      pse_flush_pw_ds(pcdev);
-       pse_release_pis(pcdev);
-       mutex_lock(&pse_list_mutex);
-       list_del(&pcdev->list);
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -222,12 +222,14 @@ struct pse_pi_pairset {
-  * @np: device node pointer of the PSE PI node
-  * @rdev: regulator represented by the PSE PI
-  * @admin_state_enabled: PI enabled state
-+ * @pw_d: Power domain of the PSE PI
-  */
- struct pse_pi {
-       struct pse_pi_pairset pairset[2];
-       struct device_node *np;
-       struct regulator_dev *rdev;
-       bool admin_state_enabled;
-+      struct pse_power_domain *pw_d;
- };
- /**
diff --git a/target/linux/generic/backport-6.18/626-14-v6.17-net-pse-pd-ethtool-Add-support-for-power-domains-index.patch b/target/linux/generic/backport-6.18/626-14-v6.17-net-pse-pd-ethtool-Add-support-for-power-domains-index.patch
deleted file mode 100644 (file)
index 1124882..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-# ADAPTED FOR OPENWRT 6.12.67 - Documentation changes removed
-# Original commit: 1176978ed851
-From 1176978ed851952652ddea3685e2f71a0e5d61ff Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:04 +0200
-Subject: [PATCH] net: ethtool: Add support for new power domains index
- description
-
-Report the index of the newly introduced PSE power domain to the user,
-enabling improved management of the power budget for PSE devices.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-5-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- Documentation/netlink/specs/ethtool.yaml       | 5 +++++
- Documentation/networking/ethtool-netlink.rst   | 4 ++++
- drivers/net/pse-pd/pse_core.c                  | 3 +++
- include/linux/pse-pd/pse.h                     | 2 ++
- include/uapi/linux/ethtool_netlink_generated.h | 1 +
- net/ethtool/pse-pd.c                           | 7 +++++++
- 6 files changed, 22 insertions(+)
-
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -1098,6 +1098,9 @@ int pse_ethtool_get_status(struct pse_co
-       pcdev = psec->pcdev;
-       ops = pcdev->ops;
-       mutex_lock(&pcdev->lock);
-+      if (pcdev->pi[psec->id].pw_d)
-+              status->pw_d_id = pcdev->pi[psec->id].pw_d->id;
-+
-       ret = ops->pi_get_admin_state(pcdev, psec->id, &admin_state);
-       if (ret)
-               goto out;
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -114,6 +114,7 @@ struct pse_pw_limit_ranges {
- /**
-  * struct ethtool_pse_control_status - PSE control/channel status.
-  *
-+ * @pw_d_id: PSE power domain index.
-  * @podl_admin_state: operational state of the PoDL PSE
-  *    functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
-  * @podl_pw_status: power detection status of the PoDL PSE.
-@@ -135,6 +136,7 @@ struct pse_pw_limit_ranges {
-  *    ranges
-  */
- struct ethtool_pse_control_status {
-+      u32 pw_d_id;
-       enum ethtool_podl_pse_admin_state podl_admin_state;
-       enum ethtool_podl_pse_pw_d_status podl_pw_status;
-       enum ethtool_c33_pse_admin_state c33_admin_state;
---- a/net/ethtool/pse-pd.c
-+++ b/net/ethtool/pse-pd.c
-@@ -83,6 +83,8 @@ static int pse_reply_size(const struct e
-       const struct ethtool_pse_control_status *st = &data->status;
-       int len = 0;
-+      if (st->pw_d_id)
-+              len += nla_total_size(sizeof(u32)); /* _PSE_PW_D_ID */
-       if (st->podl_admin_state > 0)
-               len += nla_total_size(sizeof(u32)); /* _PODL_PSE_ADMIN_STATE */
-       if (st->podl_pw_status > 0)
-@@ -148,6 +150,11 @@ static int pse_fill_reply(struct sk_buff
-       const struct pse_reply_data *data = PSE_REPDATA(reply_base);
-       const struct ethtool_pse_control_status *st = &data->status;
-+      if (st->pw_d_id &&
-+          nla_put_u32(skb, ETHTOOL_A_PSE_PW_D_ID,
-+                      st->pw_d_id))
-+              return -EMSGSIZE;
-+
-       if (st->podl_admin_state > 0 &&
-           nla_put_u32(skb, ETHTOOL_A_PODL_PSE_ADMIN_STATE,
-                       st->podl_admin_state))
diff --git a/target/linux/generic/backport-6.18/626-15-v6.17-net-pse-pd-Add-helper-to-report-hw-enable-status.patch b/target/linux/generic/backport-6.18/626-15-v6.17-net-pse-pd-Add-helper-to-report-hw-enable-status.patch
deleted file mode 100644 (file)
index ed51289..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-From c394e757dedd9cf947f9ac470d615d28fd2b07d1 Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:05 +0200
-Subject: [PATCH] net: pse-pd: Add helper to report hardware enable status of
- the PI
-
-Refactor code by introducing a helper function to retrieve the hardware
-enabled state of the PI, avoiding redundant implementations in the
-future.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-6-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pse_core.c | 36 +++++++++++++++++++++++++----------
- 1 file changed, 26 insertions(+), 10 deletions(-)
-
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -272,10 +272,34 @@ static struct net_device *pse_control_ge
-       return psec->attached_phydev->attached_dev;
- }
-+/**
-+ * pse_pi_is_hw_enabled - Is PI enabled at the hardware level
-+ * @pcdev: a pointer to the PSE controller device
-+ * @id: Index of the PI
-+ *
-+ * Return: 1 if the PI is enabled at the hardware level, 0 if not, and
-+ *       a failure value on error
-+ */
-+static int pse_pi_is_hw_enabled(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct pse_admin_state admin_state = {0};
-+      int ret;
-+
-+      ret = pcdev->ops->pi_get_admin_state(pcdev, id, &admin_state);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* PI is well enabled at the hardware level */
-+      if (admin_state.podl_admin_state == ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED ||
-+          admin_state.c33_admin_state == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED)
-+              return 1;
-+
-+      return 0;
-+}
-+
- static int pse_pi_is_enabled(struct regulator_dev *rdev)
- {
-       struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
--      struct pse_admin_state admin_state = {0};
-       const struct pse_controller_ops *ops;
-       int id, ret;
-@@ -285,15 +309,7 @@ static int pse_pi_is_enabled(struct regu
-       id = rdev_get_id(rdev);
-       mutex_lock(&pcdev->lock);
--      ret = ops->pi_get_admin_state(pcdev, id, &admin_state);
--      if (ret)
--              goto out;
--
--      if (admin_state.podl_admin_state == ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED ||
--          admin_state.c33_admin_state == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED)
--              ret = 1;
--
--out:
-+      ret = pse_pi_is_hw_enabled(pcdev, id);
-       mutex_unlock(&pcdev->lock);
-       return ret;
diff --git a/target/linux/generic/backport-6.18/626-16-v6.17-net-pse-pd-Add-support-for-budget-evaluation-strategies.patch b/target/linux/generic/backport-6.18/626-16-v6.17-net-pse-pd-Add-support-for-budget-evaluation-strategies.patch
deleted file mode 100644 (file)
index c95d8f0..0000000
+++ /dev/null
@@ -1,1104 +0,0 @@
-From ffef61d6d27374542f1bce4452200d9bdd2e1edd Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:06 +0200
-Subject: [PATCH] net: pse-pd: Add support for budget evaluation strategies
-
-ADAPTED FOR OPENWRT 6.12.67 - Documentation and ethtool_netlink_generated.h changes removed
-
-This patch introduces the ability to configure the PSE PI budget evaluation
-strategies. Budget evaluation strategies is utilized by PSE controllers to
-determine which ports to turn off first in scenarios such as power budget
-exceedance.
-
-The pis_prio_max value is used to define the maximum priority level
-supported by the controller. Both the current priority and the maximum
-priority are exposed to the user through the pse_ethtool_get_status call.
-
-This patch add support for two mode of budget evaluation strategies.
-1. Static Method:
-   This method involves distributing power based on PD classification.
-
-2. Dynamic Method:
-   Budget evaluation strategy based on the current consumption per ports
-   compared to the total power budget.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-7-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pse_core.c | 729 +++++++++++++++++++++++++++++++++-
- include/linux/pse-pd/pse.h    |  76 ++++
- 2 files changed, 791 insertions(+), 14 deletions(-)
-
---- a/drivers/net/pse-pd/pse_core.c
-+++ b/drivers/net/pse-pd/pse_core.c
-@@ -47,11 +47,14 @@ struct pse_control {
-  * @id: ID of the power domain
-  * @supply: Power supply the Power Domain
-  * @refcnt: Number of gets of this pse_power_domain
-+ * @budget_eval_strategy: Current power budget evaluation strategy of the
-+ *                      power domain
-  */
- struct pse_power_domain {
-       int id;
-       struct regulator *supply;
-       struct kref refcnt;
-+      u32 budget_eval_strategy;
- };
- static int of_load_single_pse_pi_pairset(struct device_node *node,
-@@ -297,6 +300,115 @@ static int pse_pi_is_hw_enabled(struct p
-       return 0;
- }
-+/**
-+ * pse_pi_is_admin_enable_pending - Check if PI is in admin enable pending state
-+ *                                which mean the power is not yet being
-+ *                                delivered
-+ * @pcdev: a pointer to the PSE controller device
-+ * @id: Index of the PI
-+ *
-+ * Detects if a PI is enabled in software with a PD detected, but the hardware
-+ * admin state hasn't been applied yet.
-+ *
-+ * This function is used in the power delivery and retry mechanisms to determine
-+ * which PIs need to have power delivery attempted again.
-+ *
-+ * Return: true if the PI has admin enable flag set in software but not yet
-+ *       reflected in the hardware admin state, false otherwise.
-+ */
-+static bool
-+pse_pi_is_admin_enable_pending(struct pse_controller_dev *pcdev, int id)
-+{
-+      int ret;
-+
-+      /* PI not enabled or nothing is plugged */
-+      if (!pcdev->pi[id].admin_state_enabled ||
-+          !pcdev->pi[id].isr_pd_detected)
-+              return false;
-+
-+      ret = pse_pi_is_hw_enabled(pcdev, id);
-+      /* PSE PI is already enabled at hardware level */
-+      if (ret == 1)
-+              return false;
-+
-+      return true;
-+}
-+
-+static int _pse_pi_delivery_power_sw_pw_ctrl(struct pse_controller_dev *pcdev,
-+                                           int id,
-+                                           struct netlink_ext_ack *extack);
-+
-+/**
-+ * pse_pw_d_retry_power_delivery - Retry power delivery for pending ports in a
-+ *                               PSE power domain
-+ * @pcdev: a pointer to the PSE controller device
-+ * @pw_d: a pointer to the PSE power domain
-+ *
-+ * Scans all ports in the specified power domain and attempts to enable power
-+ * delivery to any ports that have admin enable state set but don't yet have
-+ * hardware power enabled. Used when there are changes in connection status,
-+ * admin state, or priority that might allow previously unpowered ports to
-+ * receive power, especially in over-budget conditions.
-+ */
-+static void pse_pw_d_retry_power_delivery(struct pse_controller_dev *pcdev,
-+                                        struct pse_power_domain *pw_d)
-+{
-+      int i, ret = 0;
-+
-+      for (i = 0; i < pcdev->nr_lines; i++) {
-+              int prio_max = pcdev->nr_lines;
-+              struct netlink_ext_ack extack;
-+
-+              if (pcdev->pi[i].pw_d != pw_d)
-+                      continue;
-+
-+              if (!pse_pi_is_admin_enable_pending(pcdev, i))
-+                      continue;
-+
-+              /* Do not try to enable PI with a lower prio (higher value)
-+               * than one which already can't be enabled.
-+               */
-+              if (pcdev->pi[i].prio > prio_max)
-+                      continue;
-+
-+              ret = _pse_pi_delivery_power_sw_pw_ctrl(pcdev, i, &extack);
-+              if (ret == -ERANGE)
-+                      prio_max = pcdev->pi[i].prio;
-+      }
-+}
-+
-+/**
-+ * pse_pw_d_is_sw_pw_control - Determine if power control is software managed
-+ * @pcdev: a pointer to the PSE controller device
-+ * @pw_d: a pointer to the PSE power domain
-+ *
-+ * This function determines whether the power control for a specific power
-+ * domain is managed by software in the interrupt handler rather than directly
-+ * by hardware.
-+ *
-+ * Software power control is active in the following cases:
-+ * - When the budget evaluation strategy is set to static
-+ * - When the budget evaluation strategy is disabled but the PSE controller
-+ *   has an interrupt handler that can report if a Powered Device is connected
-+ *
-+ * Return: true if the power control of the power domain is managed by software,
-+ *         false otherwise
-+ */
-+static bool pse_pw_d_is_sw_pw_control(struct pse_controller_dev *pcdev,
-+                                    struct pse_power_domain *pw_d)
-+{
-+      if (!pw_d)
-+              return false;
-+
-+      if (pw_d->budget_eval_strategy == PSE_BUDGET_EVAL_STRAT_STATIC)
-+              return true;
-+      if (pw_d->budget_eval_strategy == PSE_BUDGET_EVAL_STRAT_DISABLED &&
-+          pcdev->ops->pi_enable && pcdev->irq)
-+              return true;
-+
-+      return false;
-+}
-+
- static int pse_pi_is_enabled(struct regulator_dev *rdev)
- {
-       struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
-@@ -309,17 +421,252 @@ static int pse_pi_is_enabled(struct regu
-       id = rdev_get_id(rdev);
-       mutex_lock(&pcdev->lock);
-+      if (pse_pw_d_is_sw_pw_control(pcdev, pcdev->pi[id].pw_d)) {
-+              ret = pcdev->pi[id].admin_state_enabled;
-+              goto out;
-+      }
-+
-       ret = pse_pi_is_hw_enabled(pcdev, id);
-+
-+out:
-       mutex_unlock(&pcdev->lock);
-       return ret;
- }
-+/**
-+ * pse_pi_deallocate_pw_budget - Deallocate power budget of the PI
-+ * @pi: a pointer to the PSE PI
-+ */
-+static void pse_pi_deallocate_pw_budget(struct pse_pi *pi)
-+{
-+      if (!pi->pw_d || !pi->pw_allocated_mW)
-+              return;
-+
-+      regulator_free_power_budget(pi->pw_d->supply, pi->pw_allocated_mW);
-+      pi->pw_allocated_mW = 0;
-+}
-+
-+/**
-+ * _pse_pi_disable - Call disable operation. Assumes the PSE lock has been
-+ *                 acquired.
-+ * @pcdev: a pointer to the PSE
-+ * @id: index of the PSE control
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+static int _pse_pi_disable(struct pse_controller_dev *pcdev, int id)
-+{
-+      const struct pse_controller_ops *ops = pcdev->ops;
-+      int ret;
-+
-+      if (!ops->pi_disable)
-+              return -EOPNOTSUPP;
-+
-+      ret = ops->pi_disable(pcdev, id);
-+      if (ret)
-+              return ret;
-+
-+      pse_pi_deallocate_pw_budget(&pcdev->pi[id]);
-+
-+      if (pse_pw_d_is_sw_pw_control(pcdev, pcdev->pi[id].pw_d))
-+              pse_pw_d_retry_power_delivery(pcdev, pcdev->pi[id].pw_d);
-+
-+      return 0;
-+}
-+
-+/**
-+ * pse_disable_pi_pol - Disable a PI on a power budget policy
-+ * @pcdev: a pointer to the PSE
-+ * @id: index of the PSE PI
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+static int pse_disable_pi_pol(struct pse_controller_dev *pcdev, int id)
-+{
-+      unsigned long notifs = ETHTOOL_PSE_EVENT_OVER_BUDGET;
-+      struct pse_ntf ntf = {};
-+      int ret;
-+
-+      dev_dbg(pcdev->dev, "Disabling PI %d to free power budget\n", id);
-+
-+      ret = _pse_pi_disable(pcdev, id);
-+      if (ret)
-+              notifs |= ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR;
-+
-+      ntf.notifs = notifs;
-+      ntf.id = id;
-+      kfifo_in_spinlocked(&pcdev->ntf_fifo, &ntf, 1, &pcdev->ntf_fifo_lock);
-+      schedule_work(&pcdev->ntf_work);
-+
-+      return ret;
-+}
-+
-+/**
-+ * pse_disable_pi_prio - Disable all PIs of a given priority inside a PSE
-+ *                     power domain
-+ * @pcdev: a pointer to the PSE
-+ * @pw_d: a pointer to the PSE power domain
-+ * @prio: priority
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+static int pse_disable_pi_prio(struct pse_controller_dev *pcdev,
-+                             struct pse_power_domain *pw_d,
-+                             int prio)
-+{
-+      int i;
-+
-+      for (i = 0; i < pcdev->nr_lines; i++) {
-+              int ret;
-+
-+              if (pcdev->pi[i].prio != prio ||
-+                  pcdev->pi[i].pw_d != pw_d ||
-+                  pse_pi_is_hw_enabled(pcdev, i) <= 0)
-+                      continue;
-+
-+              ret = pse_disable_pi_pol(pcdev, i);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ * pse_pi_allocate_pw_budget_static_prio - Allocate power budget for the PI
-+ *                                       when the budget eval strategy is
-+ *                                       static
-+ * @pcdev: a pointer to the PSE
-+ * @id: index of the PSE control
-+ * @pw_req: power requested in mW
-+ * @extack: extack for error reporting
-+ *
-+ * Allocates power using static budget evaluation strategy, where allocation
-+ * is based on PD classification. When insufficient budget is available,
-+ * lower-priority ports (higher priority numbers) are turned off first.
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+static int
-+pse_pi_allocate_pw_budget_static_prio(struct pse_controller_dev *pcdev, int id,
-+                                    int pw_req, struct netlink_ext_ack *extack)
-+{
-+      struct pse_pi *pi = &pcdev->pi[id];
-+      int ret, _prio;
-+
-+      _prio = pcdev->nr_lines;
-+      while (regulator_request_power_budget(pi->pw_d->supply, pw_req) == -ERANGE) {
-+              if (_prio <= pi->prio) {
-+                      NL_SET_ERR_MSG_FMT(extack,
-+                                         "PI %d: not enough power budget available",
-+                                         id);
-+                      return -ERANGE;
-+              }
-+
-+              ret = pse_disable_pi_prio(pcdev, pi->pw_d, _prio);
-+              if (ret < 0)
-+                      return ret;
-+
-+              _prio--;
-+      }
-+
-+      pi->pw_allocated_mW = pw_req;
-+      return 0;
-+}
-+
-+/**
-+ * pse_pi_allocate_pw_budget - Allocate power budget for the PI
-+ * @pcdev: a pointer to the PSE
-+ * @id: index of the PSE control
-+ * @pw_req: power requested in mW
-+ * @extack: extack for error reporting
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+static int pse_pi_allocate_pw_budget(struct pse_controller_dev *pcdev, int id,
-+                                   int pw_req, struct netlink_ext_ack *extack)
-+{
-+      struct pse_pi *pi = &pcdev->pi[id];
-+
-+      if (!pi->pw_d)
-+              return 0;
-+
-+      /* PSE_BUDGET_EVAL_STRAT_STATIC */
-+      if (pi->pw_d->budget_eval_strategy == PSE_BUDGET_EVAL_STRAT_STATIC)
-+              return pse_pi_allocate_pw_budget_static_prio(pcdev, id, pw_req,
-+                                                           extack);
-+
-+      return 0;
-+}
-+
-+/**
-+ * _pse_pi_delivery_power_sw_pw_ctrl - Enable PSE PI in case of software power
-+ *                                   control. Assumes the PSE lock has been
-+ *                                   acquired.
-+ * @pcdev: a pointer to the PSE
-+ * @id: index of the PSE control
-+ * @extack: extack for error reporting
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+static int _pse_pi_delivery_power_sw_pw_ctrl(struct pse_controller_dev *pcdev,
-+                                           int id,
-+                                           struct netlink_ext_ack *extack)
-+{
-+      const struct pse_controller_ops *ops = pcdev->ops;
-+      struct pse_pi *pi = &pcdev->pi[id];
-+      int ret, pw_req;
-+
-+      if (!ops->pi_get_pw_req) {
-+              /* No power allocation management */
-+              ret = ops->pi_enable(pcdev, id);
-+              if (ret)
-+                      NL_SET_ERR_MSG_FMT(extack,
-+                                         "PI %d: enable error %d",
-+                                         id, ret);
-+              return ret;
-+      }
-+
-+      ret = ops->pi_get_pw_req(pcdev, id);
-+      if (ret < 0)
-+              return ret;
-+
-+      pw_req = ret;
-+
-+      /* Compare requested power with port power limit and use the lowest
-+       * one.
-+       */
-+      if (ops->pi_get_pw_limit) {
-+              ret = ops->pi_get_pw_limit(pcdev, id);
-+              if (ret < 0)
-+                      return ret;
-+
-+              if (ret < pw_req)
-+                      pw_req = ret;
-+      }
-+
-+      ret = pse_pi_allocate_pw_budget(pcdev, id, pw_req, extack);
-+      if (ret)
-+              return ret;
-+
-+      ret = ops->pi_enable(pcdev, id);
-+      if (ret) {
-+              pse_pi_deallocate_pw_budget(pi);
-+              NL_SET_ERR_MSG_FMT(extack,
-+                                 "PI %d: enable error %d",
-+                                 id, ret);
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
- static int pse_pi_enable(struct regulator_dev *rdev)
- {
-       struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
-       const struct pse_controller_ops *ops;
--      int id, ret;
-+      int id, ret = 0;
-       ops = pcdev->ops;
-       if (!ops->pi_enable)
-@@ -327,6 +674,23 @@ static int pse_pi_enable(struct regulato
-       id = rdev_get_id(rdev);
-       mutex_lock(&pcdev->lock);
-+      if (pse_pw_d_is_sw_pw_control(pcdev, pcdev->pi[id].pw_d)) {
-+              /* Manage enabled status by software.
-+               * Real enable process will happen if a port is connected.
-+               */
-+              if (pcdev->pi[id].isr_pd_detected) {
-+                      struct netlink_ext_ack extack;
-+
-+                      ret = _pse_pi_delivery_power_sw_pw_ctrl(pcdev, id, &extack);
-+              }
-+              if (!ret || ret == -ERANGE) {
-+                      pcdev->pi[id].admin_state_enabled = 1;
-+                      ret = 0;
-+              }
-+              mutex_unlock(&pcdev->lock);
-+              return ret;
-+      }
-+
-       ret = ops->pi_enable(pcdev, id);
-       if (!ret)
-               pcdev->pi[id].admin_state_enabled = 1;
-@@ -338,21 +702,18 @@ static int pse_pi_enable(struct regulato
- static int pse_pi_disable(struct regulator_dev *rdev)
- {
-       struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
--      const struct pse_controller_ops *ops;
-+      struct pse_pi *pi;
-       int id, ret;
--      ops = pcdev->ops;
--      if (!ops->pi_disable)
--              return -EOPNOTSUPP;
--
-       id = rdev_get_id(rdev);
-+      pi = &pcdev->pi[id];
-       mutex_lock(&pcdev->lock);
--      ret = ops->pi_disable(pcdev, id);
-+      ret = _pse_pi_disable(pcdev, id);
-       if (!ret)
--              pcdev->pi[id].admin_state_enabled = 0;
--      mutex_unlock(&pcdev->lock);
-+              pi->admin_state_enabled = 0;
--      return ret;
-+      mutex_unlock(&pcdev->lock);
-+      return 0;
- }
- static int _pse_pi_get_voltage(struct regulator_dev *rdev)
-@@ -628,6 +989,11 @@ static int pse_register_pw_ds(struct pse
-               }
-               pw_d->supply = supply;
-+              if (pcdev->supp_budget_eval_strategies)
-+                      pw_d->budget_eval_strategy = pcdev->supp_budget_eval_strategies;
-+              else
-+                      pw_d->budget_eval_strategy = PSE_BUDGET_EVAL_STRAT_DISABLED;
-+              kref_init(&pw_d->refcnt);
-               pcdev->pi[i].pw_d = pw_d;
-       }
-@@ -637,6 +1003,34 @@ out:
- }
- /**
-+ * pse_send_ntf_worker - Worker to send PSE notifications
-+ * @work: work object
-+ *
-+ * Manage and send PSE netlink notifications using a workqueue to avoid
-+ * deadlock between pcdev_lock and pse_list_mutex.
-+ */
-+static void pse_send_ntf_worker(struct work_struct *work)
-+{
-+      struct pse_controller_dev *pcdev;
-+      struct pse_ntf ntf;
-+
-+      pcdev = container_of(work, struct pse_controller_dev, ntf_work);
-+
-+      while (kfifo_out(&pcdev->ntf_fifo, &ntf, 1)) {
-+              struct net_device *netdev;
-+              struct pse_control *psec;
-+
-+              psec = pse_control_find_by_id(pcdev, ntf.id);
-+              rtnl_lock();
-+              netdev = pse_control_get_netdev(psec);
-+              if (netdev)
-+                      ethnl_pse_send_ntf(netdev, ntf.notifs);
-+              rtnl_unlock();
-+              pse_control_put(psec);
-+      }
-+}
-+
-+/**
-  * pse_controller_register - register a PSE controller device
-  * @pcdev: a pointer to the initialized PSE controller device
-  *
-@@ -649,6 +1043,13 @@ int pse_controller_register(struct pse_c
-       mutex_init(&pcdev->lock);
-       INIT_LIST_HEAD(&pcdev->pse_control_head);
-+      spin_lock_init(&pcdev->ntf_fifo_lock);
-+      ret = kfifo_alloc(&pcdev->ntf_fifo, pcdev->nr_lines, GFP_KERNEL);
-+      if (ret) {
-+              dev_err(pcdev->dev, "failed to allocate kfifo notifications\n");
-+              return ret;
-+      }
-+      INIT_WORK(&pcdev->ntf_work, pse_send_ntf_worker);
-       if (!pcdev->nr_lines)
-               pcdev->nr_lines = 1;
-@@ -715,6 +1116,10 @@ void pse_controller_unregister(struct ps
- {
-       pse_flush_pw_ds(pcdev);
-       pse_release_pis(pcdev);
-+      if (pcdev->irq)
-+              disable_irq(pcdev->irq);
-+      cancel_work_sync(&pcdev->ntf_work);
-+      kfifo_free(&pcdev->ntf_fifo);
-       mutex_lock(&pse_list_mutex);
-       list_del(&pcdev->list);
-       mutex_unlock(&pse_list_mutex);
-@@ -787,6 +1192,52 @@ static unsigned long pse_to_regulator_no
- }
- /**
-+ * pse_set_config_isr - Set PSE control config according to the PSE
-+ *                    notifications
-+ * @pcdev: a pointer to the PSE
-+ * @id: index of the PSE control
-+ * @notifs: PSE event notifications
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+static int pse_set_config_isr(struct pse_controller_dev *pcdev, int id,
-+                            unsigned long notifs)
-+{
-+      int ret = 0;
-+
-+      if (notifs & PSE_BUDGET_EVAL_STRAT_DYNAMIC)
-+              return 0;
-+
-+      if ((notifs & ETHTOOL_C33_PSE_EVENT_DISCONNECTION) &&
-+          ((notifs & ETHTOOL_C33_PSE_EVENT_DETECTION) ||
-+           (notifs & ETHTOOL_C33_PSE_EVENT_CLASSIFICATION))) {
-+              dev_dbg(pcdev->dev,
-+                      "PI %d: error, connection and disconnection reported simultaneously",
-+                      id);
-+              return -EINVAL;
-+      }
-+
-+      if (notifs & ETHTOOL_C33_PSE_EVENT_CLASSIFICATION) {
-+              struct netlink_ext_ack extack;
-+
-+              pcdev->pi[id].isr_pd_detected = true;
-+              if (pcdev->pi[id].admin_state_enabled) {
-+                      ret = _pse_pi_delivery_power_sw_pw_ctrl(pcdev, id,
-+                                                              &extack);
-+                      if (ret == -ERANGE)
-+                              ret = 0;
-+              }
-+      } else if (notifs & ETHTOOL_C33_PSE_EVENT_DISCONNECTION) {
-+              if (pcdev->pi[id].admin_state_enabled &&
-+                  pcdev->pi[id].isr_pd_detected)
-+                      ret = _pse_pi_disable(pcdev, id);
-+              pcdev->pi[id].isr_pd_detected = false;
-+      }
-+
-+      return ret;
-+}
-+
-+/**
-  * pse_isr - IRQ handler for PSE
-  * @irq: irq number
-  * @data: pointer to user interrupt structure
-@@ -808,36 +1259,42 @@ static irqreturn_t pse_isr(int irq, void
-       memset(h->notifs, 0, pcdev->nr_lines * sizeof(*h->notifs));
-       mutex_lock(&pcdev->lock);
-       ret = desc->map_event(irq, pcdev, h->notifs, &notifs_mask);
--      mutex_unlock(&pcdev->lock);
--      if (ret || !notifs_mask)
-+      if (ret || !notifs_mask) {
-+              mutex_unlock(&pcdev->lock);
-               return IRQ_NONE;
-+      }
-       for_each_set_bit(i, &notifs_mask, pcdev->nr_lines) {
-               unsigned long notifs, rnotifs;
--              struct net_device *netdev;
--              struct pse_control *psec;
-+              struct pse_ntf ntf = {};
-               /* Do nothing PI not described */
-               if (!pcdev->pi[i].rdev)
-                       continue;
-               notifs = h->notifs[i];
-+              if (pse_pw_d_is_sw_pw_control(pcdev, pcdev->pi[i].pw_d)) {
-+                      ret = pse_set_config_isr(pcdev, i, notifs);
-+                      if (ret)
-+                              notifs |= ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR;
-+              }
-+
-               dev_dbg(h->pcdev->dev,
-                       "Sending PSE notification EVT 0x%lx\n", notifs);
--              psec = pse_control_find_by_id(pcdev, i);
--              rtnl_lock();
--              netdev = pse_control_get_netdev(psec);
--              if (netdev)
--                      ethnl_pse_send_ntf(netdev, notifs);
--              rtnl_unlock();
--              pse_control_put(psec);
-+              ntf.notifs = notifs;
-+              ntf.id = i;
-+              kfifo_in_spinlocked(&pcdev->ntf_fifo, &ntf, 1,
-+                                  &pcdev->ntf_fifo_lock);
-+              schedule_work(&pcdev->ntf_work);
-               rnotifs = pse_to_regulator_notifs(notifs);
-               regulator_notifier_call_chain(pcdev->pi[i].rdev, rnotifs,
-                                             NULL);
-       }
-+      mutex_unlock(&pcdev->lock);
-+
-       return IRQ_HANDLED;
- }
-@@ -960,6 +1417,20 @@ pse_control_get_internal(struct pse_cont
-               goto free_psec;
-       }
-+      if (!pcdev->ops->pi_get_admin_state) {
-+              ret = -EOPNOTSUPP;
-+              goto free_psec;
-+      }
-+
-+      /* Initialize admin_state_enabled before the regulator_get. This
-+       * aims to have the right value reported in the first is_enabled
-+       * call in case of control managed by software.
-+       */
-+      ret = pse_pi_is_hw_enabled(pcdev, index);
-+      if (ret < 0)
-+              goto free_psec;
-+
-+      pcdev->pi[index].admin_state_enabled = ret;
-       psec->ps = devm_regulator_get_exclusive(pcdev->dev,
-                                               rdev_get_name(pcdev->pi[index].rdev));
-       if (IS_ERR(psec->ps)) {
-@@ -967,12 +1438,6 @@ pse_control_get_internal(struct pse_cont
-               goto put_module;
-       }
--      ret = regulator_is_enabled(psec->ps);
--      if (ret < 0)
--              goto regulator_put;
--
--      pcdev->pi[index].admin_state_enabled = ret;
--
-       psec->pcdev = pcdev;
-       list_add(&psec->list, &pcdev->pse_control_head);
-       psec->id = index;
-@@ -981,8 +1446,6 @@ pse_control_get_internal(struct pse_cont
-       return psec;
--regulator_put:
--      devm_regulator_put(psec->ps);
- put_module:
-       module_put(pcdev->owner);
- free_psec:
-@@ -1094,6 +1557,35 @@ out:
- EXPORT_SYMBOL_GPL(of_pse_control_get);
- /**
-+ * pse_get_sw_admin_state - Convert the software admin state to c33 or podl
-+ *                        admin state value used in the standard
-+ * @psec: PSE control pointer
-+ * @admin_state: a pointer to the admin_state structure
-+ */
-+static void pse_get_sw_admin_state(struct pse_control *psec,
-+                                 struct pse_admin_state *admin_state)
-+{
-+      struct pse_pi *pi = &psec->pcdev->pi[psec->id];
-+
-+      if (pse_has_podl(psec)) {
-+              if (pi->admin_state_enabled)
-+                      admin_state->podl_admin_state =
-+                              ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED;
-+              else
-+                      admin_state->podl_admin_state =
-+                              ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED;
-+      }
-+      if (pse_has_c33(psec)) {
-+              if (pi->admin_state_enabled)
-+                      admin_state->c33_admin_state =
-+                              ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
-+              else
-+                      admin_state->c33_admin_state =
-+                              ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
-+      }
-+}
-+
-+/**
-  * pse_ethtool_get_status - get status of PSE control
-  * @psec: PSE control pointer
-  * @extack: extack for reporting useful error messages
-@@ -1109,19 +1601,46 @@ int pse_ethtool_get_status(struct pse_co
-       struct pse_pw_status pw_status = {0};
-       const struct pse_controller_ops *ops;
-       struct pse_controller_dev *pcdev;
-+      struct pse_pi *pi;
-       int ret;
-       pcdev = psec->pcdev;
-       ops = pcdev->ops;
-+
-+      pi = &pcdev->pi[psec->id];
-       mutex_lock(&pcdev->lock);
--      if (pcdev->pi[psec->id].pw_d)
--              status->pw_d_id = pcdev->pi[psec->id].pw_d->id;
-+      if (pi->pw_d) {
-+              status->pw_d_id = pi->pw_d->id;
-+              if (pse_pw_d_is_sw_pw_control(pcdev, pi->pw_d)) {
-+                      pse_get_sw_admin_state(psec, &admin_state);
-+              } else {
-+                      ret = ops->pi_get_admin_state(pcdev, psec->id,
-+                                                    &admin_state);
-+                      if (ret)
-+                              goto out;
-+              }
-+              status->podl_admin_state = admin_state.podl_admin_state;
-+              status->c33_admin_state = admin_state.c33_admin_state;
--      ret = ops->pi_get_admin_state(pcdev, psec->id, &admin_state);
--      if (ret)
--              goto out;
--      status->podl_admin_state = admin_state.podl_admin_state;
--      status->c33_admin_state = admin_state.c33_admin_state;
-+              switch (pi->pw_d->budget_eval_strategy) {
-+              case PSE_BUDGET_EVAL_STRAT_STATIC:
-+                      status->prio_max = pcdev->nr_lines - 1;
-+                      status->prio = pi->prio;
-+                      break;
-+              case PSE_BUDGET_EVAL_STRAT_DYNAMIC:
-+                      status->prio_max = pcdev->pis_prio_max;
-+                      if (ops->pi_get_prio) {
-+                              ret = ops->pi_get_prio(pcdev, psec->id);
-+                              if (ret < 0)
-+                                      goto out;
-+
-+                              status->prio = ret;
-+                      }
-+                      break;
-+              default:
-+                      break;
-+              }
-+      }
-       ret = ops->pi_get_pw_status(pcdev, psec->id, &pw_status);
-       if (ret)
-@@ -1271,6 +1790,52 @@ int pse_ethtool_set_config(struct pse_co
- EXPORT_SYMBOL_GPL(pse_ethtool_set_config);
- /**
-+ * pse_pi_update_pw_budget - Update PSE power budget allocated with new
-+ *                         power in mW
-+ * @pcdev: a pointer to the PSE controller device
-+ * @id: index of the PSE PI
-+ * @pw_req: power requested
-+ * @extack: extack for reporting useful error messages
-+ *
-+ * Return: Previous power allocated on success and failure value on error
-+ */
-+static int pse_pi_update_pw_budget(struct pse_controller_dev *pcdev, int id,
-+                                 const unsigned int pw_req,
-+                                 struct netlink_ext_ack *extack)
-+{
-+      struct pse_pi *pi = &pcdev->pi[id];
-+      int previous_pw_allocated;
-+      int pw_diff, ret = 0;
-+
-+      /* We don't want pw_allocated_mW value change in the middle of an
-+       * power budget update
-+       */
-+      mutex_lock(&pcdev->lock);
-+      previous_pw_allocated = pi->pw_allocated_mW;
-+      pw_diff = pw_req - previous_pw_allocated;
-+      if (!pw_diff) {
-+              goto out;
-+      } else if (pw_diff > 0) {
-+              ret = regulator_request_power_budget(pi->pw_d->supply, pw_diff);
-+              if (ret) {
-+                      NL_SET_ERR_MSG_FMT(extack,
-+                                         "PI %d: not enough power budget available",
-+                                         id);
-+                      goto out;
-+              }
-+
-+      } else {
-+              regulator_free_power_budget(pi->pw_d->supply, -pw_diff);
-+      }
-+      pi->pw_allocated_mW = pw_req;
-+      ret = previous_pw_allocated;
-+
-+out:
-+      mutex_unlock(&pcdev->lock);
-+      return ret;
-+}
-+
-+/**
-  * pse_ethtool_set_pw_limit - set PSE control power limit
-  * @psec: PSE control pointer
-  * @extack: extack for reporting useful error messages
-@@ -1282,7 +1847,7 @@ int pse_ethtool_set_pw_limit(struct pse_
-                            struct netlink_ext_ack *extack,
-                            const unsigned int pw_limit)
- {
--      int uV, uA, ret;
-+      int uV, uA, ret, previous_pw_allocated = 0;
-       s64 tmp_64;
-       if (pw_limit > MAX_PI_PW)
-@@ -1306,10 +1871,100 @@ int pse_ethtool_set_pw_limit(struct pse_
-       /* uA = mW * 1000000000 / uV */
-       uA = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);
--      return regulator_set_current_limit(psec->ps, 0, uA);
-+      /* Update power budget only in software power control case and
-+       * if a Power Device is powered.
-+       */
-+      if (pse_pw_d_is_sw_pw_control(psec->pcdev,
-+                                    psec->pcdev->pi[psec->id].pw_d) &&
-+          psec->pcdev->pi[psec->id].admin_state_enabled &&
-+          psec->pcdev->pi[psec->id].isr_pd_detected) {
-+              ret = pse_pi_update_pw_budget(psec->pcdev, psec->id,
-+                                            pw_limit, extack);
-+              if (ret < 0)
-+                      return ret;
-+              previous_pw_allocated = ret;
-+      }
-+
-+      ret = regulator_set_current_limit(psec->ps, 0, uA);
-+      if (ret < 0 && previous_pw_allocated) {
-+              pse_pi_update_pw_budget(psec->pcdev, psec->id,
-+                                      previous_pw_allocated, extack);
-+      }
-+
-+      return ret;
- }
- EXPORT_SYMBOL_GPL(pse_ethtool_set_pw_limit);
-+/**
-+ * pse_ethtool_set_prio - Set PSE PI priority according to the budget
-+ *                      evaluation strategy
-+ * @psec: PSE control pointer
-+ * @extack: extack for reporting useful error messages
-+ * @prio: priovity value
-+ *
-+ * Return: 0 on success and failure value on error
-+ */
-+int pse_ethtool_set_prio(struct pse_control *psec,
-+                       struct netlink_ext_ack *extack,
-+                       unsigned int prio)
-+{
-+      struct pse_controller_dev *pcdev = psec->pcdev;
-+      const struct pse_controller_ops *ops;
-+      int ret = 0;
-+
-+      if (!pcdev->pi[psec->id].pw_d) {
-+              NL_SET_ERR_MSG(extack, "no power domain attached");
-+              return -EOPNOTSUPP;
-+      }
-+
-+      /* We don't want priority change in the middle of an
-+       * enable/disable call or a priority mode change
-+       */
-+      mutex_lock(&pcdev->lock);
-+      switch (pcdev->pi[psec->id].pw_d->budget_eval_strategy) {
-+      case PSE_BUDGET_EVAL_STRAT_STATIC:
-+              if (prio >= pcdev->nr_lines) {
-+                      NL_SET_ERR_MSG_FMT(extack,
-+                                         "priority %d exceed priority max %d",
-+                                         prio, pcdev->nr_lines);
-+                      ret = -ERANGE;
-+                      goto out;
-+              }
-+
-+              pcdev->pi[psec->id].prio = prio;
-+              pse_pw_d_retry_power_delivery(pcdev, pcdev->pi[psec->id].pw_d);
-+              break;
-+
-+      case PSE_BUDGET_EVAL_STRAT_DYNAMIC:
-+              ops = psec->pcdev->ops;
-+              if (!ops->pi_set_prio) {
-+                      NL_SET_ERR_MSG(extack,
-+                                     "pse driver does not support setting port priority");
-+                      ret = -EOPNOTSUPP;
-+                      goto out;
-+              }
-+
-+              if (prio > pcdev->pis_prio_max) {
-+                      NL_SET_ERR_MSG_FMT(extack,
-+                                         "priority %d exceed priority max %d",
-+                                         prio, pcdev->pis_prio_max);
-+                      ret = -ERANGE;
-+                      goto out;
-+              }
-+
-+              ret = ops->pi_set_prio(pcdev, psec->id, prio);
-+              break;
-+
-+      default:
-+              ret = -EOPNOTSUPP;
-+      }
-+
-+out:
-+      mutex_unlock(&pcdev->lock);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(pse_ethtool_set_prio);
-+
- bool pse_has_podl(struct pse_control *psec)
- {
-       return psec->pcdev->types & ETHTOOL_PSE_PODL;
---- a/include/linux/pse-pd/pse.h
-+++ b/include/linux/pse-pd/pse.h
-@@ -6,6 +6,8 @@
- #define _LINUX_PSE_CONTROLLER_H
- #include <linux/list.h>
-+#include <linux/netlink.h>
-+#include <linux/kfifo.h>
- #include <uapi/linux/ethtool.h>
- #include <uapi/linux/ethtool_netlink_generated.h>
- #include <linux/regulator/driver.h>
-@@ -134,6 +136,9 @@ struct pse_pw_limit_ranges {
-  *    is in charge of the memory allocation
-  * @c33_pw_limit_nb_ranges: number of supported power limit configuration
-  *    ranges
-+ * @prio_max: max priority allowed for the c33_prio variable value.
-+ * @prio: priority of the PSE. Managed by PSE core in case of static budget
-+ *    evaluation strategy.
-  */
- struct ethtool_pse_control_status {
-       u32 pw_d_id;
-@@ -147,6 +152,8 @@ struct ethtool_pse_control_status {
-       u32 c33_avail_pw_limit;
-       struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges;
-       u32 c33_pw_limit_nb_ranges;
-+      u32 prio_max;
-+      u32 prio;
- };
- /**
-@@ -170,6 +177,11 @@ struct ethtool_pse_control_status {
-  *                        range. The driver is in charge of the memory
-  *                        allocation and should return the number of
-  *                        ranges.
-+ * @pi_get_prio: Get the PSE PI priority.
-+ * @pi_set_prio: Configure the PSE PI priority.
-+ * @pi_get_pw_req: Get the power requested by a PD before enabling the PSE PI.
-+ *               This is only relevant when an interrupt is registered using
-+ *               devm_pse_irq_helper helper.
-  */
- struct pse_controller_ops {
-       int (*setup_pi_matrix)(struct pse_controller_dev *pcdev);
-@@ -190,6 +202,10 @@ struct pse_controller_ops {
-                              int id, int max_mW);
-       int (*pi_get_pw_limit_ranges)(struct pse_controller_dev *pcdev, int id,
-                                     struct pse_pw_limit_ranges *pw_limit_ranges);
-+      int (*pi_get_prio)(struct pse_controller_dev *pcdev, int id);
-+      int (*pi_set_prio)(struct pse_controller_dev *pcdev, int id,
-+                         unsigned int prio);
-+      int (*pi_get_pw_req)(struct pse_controller_dev *pcdev, int id);
- };
- struct module;
-@@ -225,6 +241,13 @@ struct pse_pi_pairset {
-  * @rdev: regulator represented by the PSE PI
-  * @admin_state_enabled: PI enabled state
-  * @pw_d: Power domain of the PSE PI
-+ * @prio: Priority of the PSE PI. Used in static budget evaluation strategy
-+ * @isr_pd_detected: PSE PI detection status managed by the interruption
-+ *                 handler. This variable is relevant when the power enabled
-+ *                 management is managed in software like the static
-+ *                 budget evaluation strategy.
-+ * @pw_allocated_mW: Power allocated to a PSE PI to manage power budget in
-+ *                 static budget evaluation strategy.
-  */
- struct pse_pi {
-       struct pse_pi_pairset pairset[2];
-@@ -232,6 +255,20 @@ struct pse_pi {
-       struct regulator_dev *rdev;
-       bool admin_state_enabled;
-       struct pse_power_domain *pw_d;
-+      int prio;
-+      bool isr_pd_detected;
-+      int pw_allocated_mW;
-+};
-+
-+/**
-+ * struct pse_ntf - PSE notification element
-+ *
-+ * @id: ID of the PSE control
-+ * @notifs: PSE notifications to be reported
-+ */
-+struct pse_ntf {
-+      int id;
-+      unsigned long notifs;
- };
- /**
-@@ -249,6 +286,12 @@ struct pse_pi {
-  * @pi: table of PSE PIs described in this controller device
-  * @no_of_pse_pi: flag set if the pse_pis devicetree node is not used
-  * @irq: PSE interrupt
-+ * @pis_prio_max: Maximum value allowed for the PSE PIs priority
-+ * @supp_budget_eval_strategies: budget evaluation strategies supported
-+ *                             by the PSE
-+ * @ntf_work: workqueue for PSE notification management
-+ * @ntf_fifo: PSE notifications FIFO
-+ * @ntf_fifo_lock: protect @ntf_fifo writer
-  */
- struct pse_controller_dev {
-       const struct pse_controller_ops *ops;
-@@ -263,6 +306,29 @@ struct pse_controller_dev {
-       struct pse_pi *pi;
-       bool no_of_pse_pi;
-       int irq;
-+      unsigned int pis_prio_max;
-+      u32 supp_budget_eval_strategies;
-+      struct work_struct ntf_work;
-+      DECLARE_KFIFO_PTR(ntf_fifo, struct pse_ntf);
-+      spinlock_t ntf_fifo_lock; /* Protect @ntf_fifo writer */
-+};
-+
-+/**
-+ * enum pse_budget_eval_strategies - PSE budget evaluation strategies.
-+ * @PSE_BUDGET_EVAL_STRAT_DISABLED: Budget evaluation strategy disabled.
-+ * @PSE_BUDGET_EVAL_STRAT_STATIC: PSE static budget evaluation strategy.
-+ *    Budget evaluation strategy based on the power requested during PD
-+ *    classification. This strategy is managed by the PSE core.
-+ * @PSE_BUDGET_EVAL_STRAT_DYNAMIC: PSE dynamic budget evaluation
-+ *    strategy. Budget evaluation strategy based on the current consumption
-+ *    per ports compared to the total power budget. This mode is managed by
-+ *    the PSE controller.
-+ */
-+
-+enum pse_budget_eval_strategies {
-+      PSE_BUDGET_EVAL_STRAT_DISABLED  = 1 << 0,
-+      PSE_BUDGET_EVAL_STRAT_STATIC    = 1 << 1,
-+      PSE_BUDGET_EVAL_STRAT_DYNAMIC   = 1 << 2,
- };
- #if IS_ENABLED(CONFIG_PSE_CONTROLLER)
-@@ -287,6 +353,9 @@ int pse_ethtool_set_config(struct pse_co
- int pse_ethtool_set_pw_limit(struct pse_control *psec,
-                            struct netlink_ext_ack *extack,
-                            const unsigned int pw_limit);
-+int pse_ethtool_set_prio(struct pse_control *psec,
-+                       struct netlink_ext_ack *extack,
-+                       unsigned int prio);
- int pse_ethtool_get_pw_limit(struct pse_control *psec,
-                            struct netlink_ext_ack *extack);
-@@ -331,6 +400,13 @@ static inline int pse_ethtool_get_pw_lim
- {
-       return -EOPNOTSUPP;
- }
-+
-+static inline int pse_ethtool_set_prio(struct pse_control *psec,
-+                                     struct netlink_ext_ack *extack,
-+                                     unsigned int prio)
-+{
-+      return -EOPNOTSUPP;
-+}
- static inline bool pse_has_podl(struct pse_control *psec)
- {
diff --git a/target/linux/generic/backport-6.18/626-16b-v6.17-regulator-Add-support-for-power-budget.patch b/target/linux/generic/backport-6.18/626-16b-v6.17-regulator-Add-support-for-power-budget.patch
deleted file mode 100644 (file)
index b77f96d..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-From 42d7c87b4e1251f36eceac987e74623e7cda8577 Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Wed, 15 Jan 2025 15:41:57 +0100
-Subject: [PATCH] regulator: Add support for power budget
-
-Introduce power budget management for the regulator device. Enable tracking
-of available power capacity by providing helpers to request and release
-power budget allocations.
-
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Link: https://patch.msgid.link/20250115-feature_regulator_pw_budget-v2-1-0a44b949e6bc@bootlin.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: Bevan Weiss <bevan.weiss@gmail.com>
----
- drivers/regulator/core.c           | 114 +++++++++++++++++++++++++++++
- drivers/regulator/of_regulator.c   |   3 +
- include/linux/regulator/consumer.h |  21 ++++++
- include/linux/regulator/driver.h   |   2 +
- include/linux/regulator/machine.h  |   2 +
- 5 files changed, 142 insertions(+)
-
---- a/drivers/regulator/core.c
-+++ b/drivers/regulator/core.c
-@@ -916,6 +916,26 @@ static ssize_t bypass_show(struct device
- }
- static DEVICE_ATTR_RO(bypass);
-+static ssize_t power_budget_milliwatt_show(struct device *dev,
-+                                         struct device_attribute *attr,
-+                                         char *buf)
-+{
-+      struct regulator_dev *rdev = dev_get_drvdata(dev);
-+
-+      return sprintf(buf, "%d\n", rdev->constraints->pw_budget_mW);
-+}
-+static DEVICE_ATTR_RO(power_budget_milliwatt);
-+
-+static ssize_t power_requested_milliwatt_show(struct device *dev,
-+                                            struct device_attribute *attr,
-+                                            char *buf)
-+{
-+      struct regulator_dev *rdev = dev_get_drvdata(dev);
-+
-+      return sprintf(buf, "%d\n", rdev->pw_requested_mW);
-+}
-+static DEVICE_ATTR_RO(power_requested_milliwatt);
-+
- #define REGULATOR_ERROR_ATTR(name, bit)                                                       \
-       static ssize_t name##_show(struct device *dev, struct device_attribute *attr,   \
-                                  char *buf)                                           \
-@@ -1148,6 +1168,10 @@ static void print_constraints_debug(stru
-       if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
-               count += scnprintf(buf + count, len - count, "standby ");
-+      if (constraints->pw_budget_mW)
-+              count += scnprintf(buf + count, len - count, "%d mW budget",
-+                                 constraints->pw_budget_mW);
-+
-       if (!count)
-               count = scnprintf(buf, len, "no parameters");
-       else
-@@ -1636,6 +1660,9 @@ static int set_machine_constraints(struc
-               rdev->last_off = ktime_get();
-       }
-+      if (!rdev->constraints->pw_budget_mW)
-+              rdev->constraints->pw_budget_mW = INT_MAX;
-+
-       print_constraints(rdev);
-       return 0;
- }
-@@ -4651,6 +4678,87 @@ int regulator_get_current_limit(struct r
- EXPORT_SYMBOL_GPL(regulator_get_current_limit);
- /**
-+ * regulator_get_unclaimed_power_budget - get regulator unclaimed power budget
-+ * @regulator: regulator source
-+ *
-+ * Return: Unclaimed power budget of the regulator in mW.
-+ */
-+int regulator_get_unclaimed_power_budget(struct regulator *regulator)
-+{
-+      return regulator->rdev->constraints->pw_budget_mW -
-+             regulator->rdev->pw_requested_mW;
-+}
-+EXPORT_SYMBOL_GPL(regulator_get_unclaimed_power_budget);
-+
-+/**
-+ * regulator_request_power_budget - request power budget on a regulator
-+ * @regulator: regulator source
-+ * @pw_req: Power requested
-+ *
-+ * Return: 0 on success or a negative error number on failure.
-+ */
-+int regulator_request_power_budget(struct regulator *regulator,
-+                                 unsigned int pw_req)
-+{
-+      struct regulator_dev *rdev = regulator->rdev;
-+      int ret = 0, pw_tot_req;
-+
-+      regulator_lock(rdev);
-+      if (rdev->supply) {
-+              ret = regulator_request_power_budget(rdev->supply, pw_req);
-+              if (ret < 0)
-+                      goto out;
-+      }
-+
-+      pw_tot_req = rdev->pw_requested_mW + pw_req;
-+      if (pw_tot_req > rdev->constraints->pw_budget_mW) {
-+              rdev_warn(rdev, "power requested %d mW out of budget %d mW",
-+                        pw_req,
-+                        rdev->constraints->pw_budget_mW - rdev->pw_requested_mW);
-+              regulator_notifier_call_chain(rdev,
-+                                            REGULATOR_EVENT_OVER_CURRENT_WARN,
-+                                            NULL);
-+              ret = -ERANGE;
-+              goto out;
-+      }
-+
-+      rdev->pw_requested_mW = pw_tot_req;
-+out:
-+      regulator_unlock(rdev);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(regulator_request_power_budget);
-+
-+/**
-+ * regulator_free_power_budget - free power budget on a regulator
-+ * @regulator: regulator source
-+ * @pw: Power to be released.
-+ *
-+ * Return: Power budget of the regulator in mW.
-+ */
-+void regulator_free_power_budget(struct regulator *regulator,
-+                               unsigned int pw)
-+{
-+      struct regulator_dev *rdev = regulator->rdev;
-+      int pw_tot_req;
-+
-+      regulator_lock(rdev);
-+      if (rdev->supply)
-+              regulator_free_power_budget(rdev->supply, pw);
-+
-+      pw_tot_req = rdev->pw_requested_mW - pw;
-+      if (pw_tot_req >= 0)
-+              rdev->pw_requested_mW = pw_tot_req;
-+      else
-+              rdev_warn(rdev,
-+                        "too much power freed %d mW (already requested %d mW)",
-+                        pw, rdev->pw_requested_mW);
-+
-+      regulator_unlock(rdev);
-+}
-+EXPORT_SYMBOL_GPL(regulator_free_power_budget);
-+
-+/**
-  * regulator_set_mode - set regulator operating mode
-  * @regulator: regulator source
-  * @mode: operating mode - one of the REGULATOR_MODE constants
-@@ -5288,6 +5396,8 @@ static struct attribute *regulator_dev_a
-       &dev_attr_suspend_standby_mode.attr,
-       &dev_attr_suspend_mem_mode.attr,
-       &dev_attr_suspend_disk_mode.attr,
-+      &dev_attr_power_budget_milliwatt.attr,
-+      &dev_attr_power_requested_milliwatt.attr,
-       NULL
- };
-@@ -5369,6 +5479,10 @@ static umode_t regulator_attr_is_visible
-           attr == &dev_attr_suspend_disk_mode.attr)
-               return ops->set_suspend_mode ? mode : 0;
-+      if (attr == &dev_attr_power_budget_milliwatt.attr ||
-+          attr == &dev_attr_power_requested_milliwatt.attr)
-+              return rdev->constraints->pw_budget_mW != INT_MAX ? mode : 0;
-+
-       return mode;
- }
---- a/drivers/regulator/of_regulator.c
-+++ b/drivers/regulator/of_regulator.c
-@@ -125,6 +125,9 @@ static int of_get_regulation_constraints
-       if (constraints->min_uA != constraints->max_uA)
-               constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
-+      if (!of_property_read_u32(np, "regulator-power-budget-milliwatt", &pval))
-+              constraints->pw_budget_mW = pval;
-+
-       constraints->boot_on = of_property_read_bool(np, "regulator-boot-on");
-       constraints->always_on = of_property_read_bool(np, "regulator-always-on");
-       if (!constraints->always_on) /* status change should be possible. */
---- a/include/linux/regulator/consumer.h
-+++ b/include/linux/regulator/consumer.h
-@@ -235,6 +235,11 @@ int regulator_sync_voltage(struct regula
- int regulator_set_current_limit(struct regulator *regulator,
-                              int min_uA, int max_uA);
- int regulator_get_current_limit(struct regulator *regulator);
-+int regulator_get_unclaimed_power_budget(struct regulator *regulator);
-+int regulator_request_power_budget(struct regulator *regulator,
-+                                 unsigned int pw_req);
-+void regulator_free_power_budget(struct regulator *regulator,
-+                               unsigned int pw);
- int regulator_set_mode(struct regulator *regulator, unsigned int mode);
- unsigned int regulator_get_mode(struct regulator *regulator);
-@@ -534,6 +539,22 @@ static inline int regulator_get_current_
-       return 0;
- }
-+static inline int regulator_get_unclaimed_power_budget(struct regulator *regulator)
-+{
-+      return INT_MAX;
-+}
-+
-+static inline int regulator_request_power_budget(struct regulator *regulator,
-+                                               unsigned int pw_req)
-+{
-+      return -EOPNOTSUPP;
-+}
-+
-+static inline void regulator_free_power_budget(struct regulator *regulator,
-+                                             unsigned int pw)
-+{
-+}
-+
- static inline int regulator_set_mode(struct regulator *regulator,
-       unsigned int mode)
- {
---- a/include/linux/regulator/driver.h
-+++ b/include/linux/regulator/driver.h
-@@ -649,6 +649,8 @@ struct regulator_dev {
-       int cached_err;
-       bool use_cached_err;
-       spinlock_t err_lock;
-+
-+      int pw_requested_mW;
- };
- /*
---- a/include/linux/regulator/machine.h
-+++ b/include/linux/regulator/machine.h
-@@ -113,6 +113,7 @@ struct notification_limit {
-  * @min_uA: Smallest current consumers may set.
-  * @max_uA: Largest current consumers may set.
-  * @ilim_uA: Maximum input current.
-+ * @pw_budget_mW: Power budget for the regulator in mW.
-  * @system_load: Load that isn't captured by any consumer requests.
-  *
-  * @over_curr_limits:         Limits for acting on over current.
-@@ -185,6 +186,7 @@ struct regulation_constraints {
-       int max_uA;
-       int ilim_uA;
-+      int pw_budget_mW;
-       int system_load;
-       /* used for coupled regulators */
diff --git a/target/linux/generic/backport-6.18/626-17-v6.17-net-pse-pd-pd692x0-Add-PSE-PI-priority-feature.patch b/target/linux/generic/backport-6.18/626-17-v6.17-net-pse-pd-pd692x0-Add-PSE-PI-priority-feature.patch
deleted file mode 100644 (file)
index 6e1f2d6..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-From 359754013e6a7fc81af6735ebbfedd4a01999f68 Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:08 +0200
-Subject: [PATCH] net: pse-pd: pd692x0: Add support for PSE PI priority feature
-
-This patch extends the PSE callbacks by adding support for the newly
-introduced pi_set_prio() callback, enabling the configuration of PSE PI
-priorities. The current port priority is now also included in the status
-information returned to users.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-9-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pd692x0.c | 205 +++++++++++++++++++++++++++++++++++
- 1 file changed, 205 insertions(+)
-
---- a/drivers/net/pse-pd/pd692x0.c
-+++ b/drivers/net/pse-pd/pd692x0.c
-@@ -12,6 +12,8 @@
- #include <linux/of.h>
- #include <linux/platform_device.h>
- #include <linux/pse-pd/pse.h>
-+#include <linux/regulator/driver.h>
-+#include <linux/regulator/machine.h>
- #define PD692X0_PSE_NAME "pd692x0_pse"
-@@ -76,6 +78,8 @@ enum {
-       PD692X0_MSG_GET_PORT_CLASS,
-       PD692X0_MSG_GET_PORT_MEAS,
-       PD692X0_MSG_GET_PORT_PARAM,
-+      PD692X0_MSG_GET_POWER_BANK,
-+      PD692X0_MSG_SET_POWER_BANK,
-       /* add new message above here */
-       PD692X0_MSG_CNT
-@@ -95,6 +99,8 @@ struct pd692x0_priv {
-       unsigned long last_cmd_key_time;
-       enum ethtool_c33_pse_admin_state admin_state[PD692X0_MAX_PIS];
-+      struct regulator_dev *manager_reg[PD692X0_MAX_MANAGERS];
-+      int manager_pw_budget[PD692X0_MAX_MANAGERS];
- };
- /* Template list of communication messages. The non-null bytes defined here
-@@ -170,6 +176,16 @@ static const struct pd692x0_msg pd692x0_
-               .data = {0x4e, 0x4e, 0x4e, 0x4e,
-                        0x4e, 0x4e, 0x4e, 0x4e},
-       },
-+      [PD692X0_MSG_GET_POWER_BANK] = {
-+              .key = PD692X0_KEY_REQ,
-+              .sub = {0x07, 0x0b, 0x57},
-+              .data = {   0, 0x4e, 0x4e, 0x4e,
-+                       0x4e, 0x4e, 0x4e, 0x4e},
-+      },
-+      [PD692X0_MSG_SET_POWER_BANK] = {
-+              .key = PD692X0_KEY_CMD,
-+              .sub = {0x07, 0x0b, 0x57},
-+      },
- };
- static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo)
-@@ -739,6 +755,29 @@ pd692x0_pi_get_actual_pw(struct pse_cont
-       return (buf.data[0] << 4 | buf.data[1]) * 100;
- }
-+static int
-+pd692x0_pi_get_prio(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-+      struct pd692x0_msg msg, buf = {0};
-+      int ret;
-+
-+      ret = pd692x0_fw_unavailable(priv);
-+      if (ret)
-+              return ret;
-+
-+      msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
-+      msg.sub[2] = id;
-+      ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
-+      if (ret < 0)
-+              return ret;
-+      if (!buf.data[2] || buf.data[2] > pcdev->pis_prio_max + 1)
-+              return -ERANGE;
-+
-+      /* PSE core priority start at 0 */
-+      return buf.data[2] - 1;
-+}
-+
- static struct pd692x0_msg_ver pd692x0_get_sw_version(struct pd692x0_priv *priv)
- {
-       struct device *dev = &priv->client->dev;
-@@ -766,6 +805,7 @@ static struct pd692x0_msg_ver pd692x0_ge
- struct pd692x0_manager {
-       struct device_node *port_node[PD692X0_MAX_MANAGER_PORTS];
-+      struct device_node *node;
-       int nports;
- };
-@@ -857,6 +897,8 @@ pd692x0_of_get_managers(struct pd692x0_p
-               if (ret)
-                       goto out;
-+              of_node_get(node);
-+              manager[manager_id].node = node;
-               nmanagers++;
-       }
-@@ -869,6 +911,8 @@ out:
-                       of_node_put(manager[i].port_node[j]);
-                       manager[i].port_node[j] = NULL;
-               }
-+              of_node_put(manager[i].node);
-+              manager[i].node = NULL;
-       }
-       of_node_put(node);
-@@ -876,6 +920,130 @@ out:
-       return ret;
- }
-+static const struct regulator_ops dummy_ops;
-+
-+static struct regulator_dev *
-+pd692x0_register_manager_regulator(struct device *dev, char *reg_name,
-+                                 struct device_node *node)
-+{
-+      struct regulator_init_data *rinit_data;
-+      struct regulator_config rconfig = {0};
-+      struct regulator_desc *rdesc;
-+      struct regulator_dev *rdev;
-+
-+      rinit_data = devm_kzalloc(dev, sizeof(*rinit_data),
-+                                GFP_KERNEL);
-+      if (!rinit_data)
-+              return ERR_PTR(-ENOMEM);
-+
-+      rdesc = devm_kzalloc(dev, sizeof(*rdesc), GFP_KERNEL);
-+      if (!rdesc)
-+              return ERR_PTR(-ENOMEM);
-+
-+      rdesc->name = reg_name;
-+      rdesc->type = REGULATOR_VOLTAGE;
-+      rdesc->ops = &dummy_ops;
-+      rdesc->owner = THIS_MODULE;
-+
-+      rinit_data->supply_regulator = "vmain";
-+
-+      rconfig.dev = dev;
-+      rconfig.init_data = rinit_data;
-+      rconfig.of_node = node;
-+
-+      rdev = devm_regulator_register(dev, rdesc, &rconfig);
-+      if (IS_ERR(rdev)) {
-+              dev_err_probe(dev, PTR_ERR(rdev),
-+                            "Failed to register regulator\n");
-+              return rdev;
-+      }
-+
-+      return rdev;
-+}
-+
-+static int
-+pd692x0_register_managers_regulator(struct pd692x0_priv *priv,
-+                                  const struct pd692x0_manager *manager,
-+                                  int nmanagers)
-+{
-+      struct device *dev = &priv->client->dev;
-+      size_t reg_name_len;
-+      int i;
-+
-+      /* Each regulator name len is dev name + 12 char +
-+       * int max digit number (10) + 1
-+       */
-+      reg_name_len = strlen(dev_name(dev)) + 23;
-+
-+      for (i = 0; i < nmanagers; i++) {
-+              struct regulator_dev *rdev;
-+              char *reg_name;
-+
-+              reg_name = devm_kzalloc(dev, reg_name_len, GFP_KERNEL);
-+              if (!reg_name)
-+                      return -ENOMEM;
-+              snprintf(reg_name, 26, "pse-%s-manager%d", dev_name(dev), i);
-+              rdev = pd692x0_register_manager_regulator(dev, reg_name,
-+                                                        manager[i].node);
-+              if (IS_ERR(rdev))
-+                      return PTR_ERR(rdev);
-+
-+              priv->manager_reg[i] = rdev;
-+      }
-+
-+      return 0;
-+}
-+
-+static int
-+pd692x0_conf_manager_power_budget(struct pd692x0_priv *priv, int id, int pw)
-+{
-+      struct pd692x0_msg msg, buf;
-+      int ret, pw_mW = pw / 1000;
-+
-+      msg = pd692x0_msg_template_list[PD692X0_MSG_GET_POWER_BANK];
-+      msg.data[0] = id;
-+      ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
-+      if (ret < 0)
-+              return ret;
-+
-+      msg = pd692x0_msg_template_list[PD692X0_MSG_SET_POWER_BANK];
-+      msg.data[0] = id;
-+      msg.data[1] = pw_mW >> 8;
-+      msg.data[2] = pw_mW & 0xff;
-+      msg.data[3] = buf.sub[2];
-+      msg.data[4] = buf.data[0];
-+      msg.data[5] = buf.data[1];
-+      msg.data[6] = buf.data[2];
-+      msg.data[7] = buf.data[3];
-+      return pd692x0_sendrecv_msg(priv, &msg, &buf);
-+}
-+
-+static int
-+pd692x0_configure_managers(struct pd692x0_priv *priv, int nmanagers)
-+{
-+      int i, ret;
-+
-+      for (i = 0; i < nmanagers; i++) {
-+              struct regulator *supply = priv->manager_reg[i]->supply;
-+              int pw_budget;
-+
-+              pw_budget = regulator_get_unclaimed_power_budget(supply);
-+              /* Max power budget per manager */
-+              if (pw_budget > 6000000)
-+                      pw_budget = 6000000;
-+              ret = regulator_request_power_budget(supply, pw_budget);
-+              if (ret < 0)
-+                      return ret;
-+
-+              priv->manager_pw_budget[i] = pw_budget;
-+              ret = pd692x0_conf_manager_power_budget(priv, i, pw_budget);
-+              if (ret < 0)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
- static int
- pd692x0_set_port_matrix(const struct pse_pi_pairset *pairset,
-                       const struct pd692x0_manager *manager,
-@@ -998,6 +1166,14 @@ static int pd692x0_setup_pi_matrix(struc
-               return ret;
-       nmanagers = ret;
-+      ret = pd692x0_register_managers_regulator(priv, manager, nmanagers);
-+      if (ret)
-+              goto out;
-+
-+      ret = pd692x0_configure_managers(priv, nmanagers);
-+      if (ret)
-+              goto out;
-+
-       ret = pd692x0_set_ports_matrix(priv, manager, nmanagers, port_matrix);
-       if (ret)
-               goto out;
-@@ -1008,8 +1184,14 @@ static int pd692x0_setup_pi_matrix(struc
- out:
-       for (i = 0; i < nmanagers; i++) {
-+              struct regulator *supply = priv->manager_reg[i]->supply;
-+
-+              regulator_free_power_budget(supply,
-+                                          priv->manager_pw_budget[i]);
-+
-               for (j = 0; j < manager[i].nports; j++)
-                       of_node_put(manager[i].port_node[j]);
-+              of_node_put(manager[i].node);
-       }
-       return ret;
- }
-@@ -1071,6 +1253,25 @@ static int pd692x0_pi_set_pw_limit(struc
-       return pd692x0_sendrecv_msg(priv, &msg, &buf);
- }
-+static int pd692x0_pi_set_prio(struct pse_controller_dev *pcdev, int id,
-+                             unsigned int prio)
-+{
-+      struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-+      struct pd692x0_msg msg, buf = {0};
-+      int ret;
-+
-+      ret = pd692x0_fw_unavailable(priv);
-+      if (ret)
-+              return ret;
-+
-+      msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
-+      msg.sub[2] = id;
-+      /* Controller priority from 1 to 3 */
-+      msg.data[4] = prio + 1;
-+
-+      return pd692x0_sendrecv_msg(priv, &msg, &buf);
-+}
-+
- static const struct pse_controller_ops pd692x0_ops = {
-       .setup_pi_matrix = pd692x0_setup_pi_matrix,
-       .pi_get_admin_state = pd692x0_pi_get_admin_state,
-@@ -1084,6 +1285,8 @@ static const struct pse_controller_ops p
-       .pi_get_pw_limit = pd692x0_pi_get_pw_limit,
-       .pi_set_pw_limit = pd692x0_pi_set_pw_limit,
-       .pi_get_pw_limit_ranges = pd692x0_pi_get_pw_limit_ranges,
-+      .pi_get_prio = pd692x0_pi_get_prio,
-+      .pi_set_prio = pd692x0_pi_set_prio,
- };
- #define PD692X0_FW_LINE_MAX_SZ 0xff
-@@ -1500,6 +1703,8 @@ static int pd692x0_i2c_probe(struct i2c_
-       priv->pcdev.ops = &pd692x0_ops;
-       priv->pcdev.dev = dev;
-       priv->pcdev.types = ETHTOOL_PSE_C33;
-+      priv->pcdev.supp_budget_eval_strategies = PSE_BUDGET_EVAL_STRAT_DYNAMIC;
-+      priv->pcdev.pis_prio_max = 2;
-       ret = devm_pse_controller_register(dev, &priv->pcdev);
-       if (ret)
-               return dev_err_probe(dev, ret,
diff --git a/target/linux/generic/backport-6.18/626-18-v6.17-net-pse-pd-pd692x0-Add-controller-and-manager-power.patch b/target/linux/generic/backport-6.18/626-18-v6.17-net-pse-pd-pd692x0-Add-controller-and-manager-power.patch
deleted file mode 100644 (file)
index a93dca0..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-From 24a4e3a05dd0eadd0c9585c411880e5dcb6be97f Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:09 +0200
-Subject: [PATCH] net: pse-pd: pd692x0: Add support for controller and manager
- power supplies
-
-Add support for managing the VDD and VDDA power supplies for the PD692x0
-PSE controller, as well as the VAUX5 and VAUX3P3 power supplies for the
-PD6920x PSE managers.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-10-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pd692x0.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/drivers/net/pse-pd/pd692x0.c
-+++ b/drivers/net/pse-pd/pd692x0.c
-@@ -976,8 +976,10 @@ pd692x0_register_managers_regulator(stru
-       reg_name_len = strlen(dev_name(dev)) + 23;
-       for (i = 0; i < nmanagers; i++) {
-+              static const char * const regulators[] = { "vaux5", "vaux3p3" };
-               struct regulator_dev *rdev;
-               char *reg_name;
-+              int ret;
-               reg_name = devm_kzalloc(dev, reg_name_len, GFP_KERNEL);
-               if (!reg_name)
-@@ -988,6 +990,17 @@ pd692x0_register_managers_regulator(stru
-               if (IS_ERR(rdev))
-                       return PTR_ERR(rdev);
-+              /* VMAIN is described as main supply for the manager.
-+               * Add other VAUX power supplies and link them to the
-+               * virtual device rdev->dev.
-+               */
-+              ret = devm_regulator_bulk_get_enable(&rdev->dev,
-+                                                   ARRAY_SIZE(regulators),
-+                                                   regulators);
-+              if (ret)
-+                      return dev_err_probe(&rdev->dev, ret,
-+                                           "Failed to enable regulators\n");
-+
-               priv->manager_reg[i] = rdev;
-       }
-@@ -1640,6 +1653,7 @@ static const struct fw_upload_ops pd692x
- static int pd692x0_i2c_probe(struct i2c_client *client)
- {
-+      static const char * const regulators[] = { "vdd", "vdda" };
-       struct pd692x0_msg msg, buf = {0}, zero = {0};
-       struct device *dev = &client->dev;
-       struct pd692x0_msg_ver ver;
-@@ -1647,6 +1661,12 @@ static int pd692x0_i2c_probe(struct i2c_
-       struct fw_upload *fwl;
-       int ret;
-+      ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators),
-+                                           regulators);
-+      if (ret)
-+              return dev_err_probe(dev, ret,
-+                                   "Failed to enable regulators\n");
-+
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-               dev_err(dev, "i2c check functionality failed\n");
-               return -ENXIO;
diff --git a/target/linux/generic/backport-6.18/626-19-v6.17-net-pse-pd-tps23881-Add-static-port-priority-feature.patch b/target/linux/generic/backport-6.18/626-19-v6.17-net-pse-pd-tps23881-Add-static-port-priority-feature.patch
deleted file mode 100644 (file)
index 739233a..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-From 56cfc97635e9164395c9242f72746454347155ab Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:11 +0200
-Subject: [PATCH] net: pse-pd: tps23881: Add support for static port priority
- feature
-
-This patch enhances PSE callbacks by introducing support for the static
-port priority feature. It extends interrupt management to handle and report
-detection, classification, and disconnection events. Additionally, it
-introduces the pi_get_pw_req() callback, which provides information about
-the power requested by the Powered Devices.
-
-Interrupt support is essential for the proper functioning of the TPS23881
-controller. Without it, after a power-on (PWON), the controller will
-no longer perform detection and classification. This could lead to
-potential hazards, such as connecting a non-PoE device after a PoE device,
-which might result in magic smoke.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-12-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/tps23881.c | 244 +++++++++++++++++++++++++++++++---
- 1 file changed, 228 insertions(+), 16 deletions(-)
-
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -20,20 +20,30 @@
- #define TPS23881_REG_IT               0x0
- #define TPS23881_REG_IT_MASK  0x1
-+#define TPS23881_REG_IT_DISF  BIT(2)
-+#define TPS23881_REG_IT_DETC  BIT(3)
-+#define TPS23881_REG_IT_CLASC BIT(4)
- #define TPS23881_REG_IT_IFAULT        BIT(5)
- #define TPS23881_REG_IT_SUPF  BIT(7)
-+#define TPS23881_REG_DET_EVENT        0x5
- #define TPS23881_REG_FAULT    0x7
- #define TPS23881_REG_SUPF_EVENT       0xb
- #define TPS23881_REG_TSD      BIT(7)
-+#define TPS23881_REG_DISC     0xc
- #define TPS23881_REG_PW_STATUS        0x10
- #define TPS23881_REG_OP_MODE  0x12
-+#define TPS23881_REG_DISC_EN  0x13
- #define TPS23881_OP_MODE_SEMIAUTO     0xaaaa
- #define TPS23881_REG_DIS_EN   0x13
- #define TPS23881_REG_DET_CLA_EN       0x14
- #define TPS23881_REG_GEN_MASK 0x17
-+#define TPS23881_REG_CLCHE    BIT(2)
-+#define TPS23881_REG_DECHE    BIT(3)
- #define TPS23881_REG_NBITACC  BIT(5)
- #define TPS23881_REG_INTEN    BIT(7)
- #define TPS23881_REG_PW_EN    0x19
-+#define TPS23881_REG_RESET    0x1a
-+#define TPS23881_REG_CLRAIN   BIT(7)
- #define TPS23881_REG_2PAIR_POL1       0x1e
- #define TPS23881_REG_PORT_MAP 0x26
- #define TPS23881_REG_PORT_POWER       0x29
-@@ -178,6 +188,7 @@ static int tps23881_pi_enable(struct pse
-       struct i2c_client *client = priv->client;
-       u8 chan;
-       u16 val;
-+      int ret;
-       if (id >= TPS23881_MAX_CHANS)
-               return -ERANGE;
-@@ -191,7 +202,22 @@ static int tps23881_pi_enable(struct pse
-                                      BIT(chan % 4));
-       }
--      return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
-+      ret = i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
-+      if (ret)
-+              return ret;
-+
-+      /* Enable DC disconnect*/
-+      chan = priv->port[id].chan[0];
-+      ret = i2c_smbus_read_word_data(client, TPS23881_REG_DISC_EN);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = tps23881_set_val(ret, chan, 0, BIT(chan % 4), BIT(chan % 4));
-+      ret = i2c_smbus_write_word_data(client, TPS23881_REG_DISC_EN, val);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
- }
- static int tps23881_pi_disable(struct pse_controller_dev *pcdev, int id)
-@@ -224,6 +250,17 @@ static int tps23881_pi_disable(struct ps
-        */
-       mdelay(5);
-+      /* Disable DC disconnect*/
-+      chan = priv->port[id].chan[0];
-+      ret = i2c_smbus_read_word_data(client, TPS23881_REG_DISC_EN);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = tps23881_set_val(ret, chan, 0, 0, BIT(chan % 4));
-+      ret = i2c_smbus_write_word_data(client, TPS23881_REG_DISC_EN, val);
-+      if (ret)
-+              return ret;
-+
-       /* Enable detection and classification */
-       ret = i2c_smbus_read_word_data(client, TPS23881_REG_DET_CLA_EN);
-       if (ret < 0)
-@@ -919,6 +956,47 @@ static int tps23881_setup_pi_matrix(stru
-       return ret;
- }
-+static int tps23881_power_class_table[] = {
-+      -ERANGE,
-+      4000,
-+      7000,
-+      15500,
-+      30000,
-+      15500,
-+      15500,
-+      -ERANGE,
-+      45000,
-+      60000,
-+      75000,
-+      90000,
-+      15500,
-+      45000,
-+      -ERANGE,
-+      -ERANGE,
-+};
-+
-+static int tps23881_pi_get_pw_req(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct tps23881_priv *priv = to_tps23881_priv(pcdev);
-+      struct i2c_client *client = priv->client;
-+      u8 reg, chan;
-+      int ret;
-+      u16 val;
-+
-+      /* For a 4-pair the classification need 5ms to be completed */
-+      if (priv->port[id].is_4p)
-+              mdelay(5);
-+
-+      chan = priv->port[id].chan[0];
-+      reg = TPS23881_REG_DISC + (chan % 4);
-+      ret = i2c_smbus_read_word_data(client, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = tps23881_calc_val(ret, chan, 4, 0xf);
-+      return tps23881_power_class_table[val];
-+}
-+
- static const struct pse_controller_ops tps23881_ops = {
-       .setup_pi_matrix = tps23881_setup_pi_matrix,
-       .pi_enable = tps23881_pi_enable,
-@@ -931,6 +1009,7 @@ static const struct pse_controller_ops t
-       .pi_get_pw_limit = tps23881_pi_get_pw_limit,
-       .pi_set_pw_limit = tps23881_pi_set_pw_limit,
-       .pi_get_pw_limit_ranges = tps23881_pi_get_pw_limit_ranges,
-+      .pi_get_pw_req = tps23881_pi_get_pw_req,
- };
- static const char fw_parity_name[] = "ti/tps23881/tps23881-parity-14.bin";
-@@ -1088,17 +1167,113 @@ static void tps23881_irq_event_over_temp
-       }
- }
--static void tps23881_irq_event_over_current(struct tps23881_priv *priv,
--                                          u16 reg_val,
--                                          unsigned long *notifs,
--                                          unsigned long *notifs_mask)
-+static int tps23881_irq_event_over_current(struct tps23881_priv *priv,
-+                                         u16 reg_val,
-+                                         unsigned long *notifs,
-+                                         unsigned long *notifs_mask)
- {
-+      int i, ret;
-       u8 chans;
-       chans = tps23881_irq_export_chans_helper(reg_val, 0);
-+      if (!chans)
-+              return 0;
-+
-+      tps23881_set_notifs_helper(priv, chans, notifs, notifs_mask,
-+                                 ETHTOOL_PSE_EVENT_OVER_CURRENT |
-+                                 ETHTOOL_C33_PSE_EVENT_DISCONNECTION);
-+
-+      /* Over Current event resets the power limit registers so we need
-+       * to configured it again.
-+       */
-+      for_each_set_bit(i, notifs_mask, priv->pcdev.nr_lines) {
-+              if (priv->port[i].pw_pol < 0)
-+                      continue;
-+
-+              ret = tps23881_pi_enable_manual_pol(priv, i);
-+              if (ret < 0)
-+                      return ret;
-+
-+              /* Set power policy */
-+              ret = tps23881_pi_set_pw_pol_limit(priv, i,
-+                                                 priv->port[i].pw_pol,
-+                                                 priv->port[i].is_4p);
-+              if (ret < 0)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static void tps23881_irq_event_disconnection(struct tps23881_priv *priv,
-+                                           u16 reg_val,
-+                                           unsigned long *notifs,
-+                                           unsigned long *notifs_mask)
-+{
-+      u8 chans;
-+
-+      chans = tps23881_irq_export_chans_helper(reg_val, 4);
-       if (chans)
-               tps23881_set_notifs_helper(priv, chans, notifs, notifs_mask,
--                                         ETHTOOL_PSE_EVENT_OVER_CURRENT);
-+                                         ETHTOOL_C33_PSE_EVENT_DISCONNECTION);
-+}
-+
-+static int tps23881_irq_event_detection(struct tps23881_priv *priv,
-+                                      u16 reg_val,
-+                                      unsigned long *notifs,
-+                                      unsigned long *notifs_mask)
-+{
-+      enum ethtool_pse_event event;
-+      int reg, ret, i, val;
-+      unsigned long chans;
-+
-+      chans = tps23881_irq_export_chans_helper(reg_val, 0);
-+      for_each_set_bit(i, &chans, TPS23881_MAX_CHANS) {
-+              reg = TPS23881_REG_DISC + (i % 4);
-+              ret = i2c_smbus_read_word_data(priv->client, reg);
-+              if (ret < 0)
-+                      return ret;
-+
-+              val = tps23881_calc_val(ret, i, 0, 0xf);
-+              /* If detection valid */
-+              if (val == 0x4)
-+                      event = ETHTOOL_C33_PSE_EVENT_DETECTION;
-+              else
-+                      event = ETHTOOL_C33_PSE_EVENT_DISCONNECTION;
-+
-+              tps23881_set_notifs_helper(priv, BIT(i), notifs,
-+                                         notifs_mask, event);
-+      }
-+
-+      return 0;
-+}
-+
-+static int tps23881_irq_event_classification(struct tps23881_priv *priv,
-+                                           u16 reg_val,
-+                                           unsigned long *notifs,
-+                                           unsigned long *notifs_mask)
-+{
-+      int reg, ret, val, i;
-+      unsigned long chans;
-+
-+      chans = tps23881_irq_export_chans_helper(reg_val, 4);
-+      for_each_set_bit(i, &chans, TPS23881_MAX_CHANS) {
-+              reg = TPS23881_REG_DISC + (i % 4);
-+              ret = i2c_smbus_read_word_data(priv->client, reg);
-+              if (ret < 0)
-+                      return ret;
-+
-+              val = tps23881_calc_val(ret, i, 4, 0xf);
-+              /* Do not report classification event for unknown class */
-+              if (!val || val == 0x8 || val == 0xf)
-+                      continue;
-+
-+              tps23881_set_notifs_helper(priv, BIT(i), notifs,
-+                                         notifs_mask,
-+                                         ETHTOOL_C33_PSE_EVENT_CLASSIFICATION);
-+      }
-+
-+      return 0;
- }
- static int tps23881_irq_event_handler(struct tps23881_priv *priv, u16 reg,
-@@ -1106,7 +1281,7 @@ static int tps23881_irq_event_handler(st
-                                     unsigned long *notifs_mask)
- {
-       struct i2c_client *client = priv->client;
--      int ret;
-+      int ret, val;
-       /* The Supply event bit is repeated twice so we only need to read
-        * the one from the first byte.
-@@ -1118,13 +1293,36 @@ static int tps23881_irq_event_handler(st
-               tps23881_irq_event_over_temp(priv, ret, notifs, notifs_mask);
-       }
--      if (reg & (TPS23881_REG_IT_IFAULT | TPS23881_REG_IT_IFAULT << 8)) {
-+      if (reg & (TPS23881_REG_IT_IFAULT | TPS23881_REG_IT_IFAULT << 8 |
-+                 TPS23881_REG_IT_DISF | TPS23881_REG_IT_DISF << 8)) {
-               ret = i2c_smbus_read_word_data(client, TPS23881_REG_FAULT);
-               if (ret < 0)
-                       return ret;
--              tps23881_irq_event_over_current(priv, ret, notifs, notifs_mask);
-+              ret = tps23881_irq_event_over_current(priv, ret, notifs,
-+                                                    notifs_mask);
-+              if (ret)
-+                      return ret;
-+
-+              tps23881_irq_event_disconnection(priv, ret, notifs, notifs_mask);
-       }
-+      if (reg & (TPS23881_REG_IT_DETC | TPS23881_REG_IT_DETC << 8 |
-+                 TPS23881_REG_IT_CLASC | TPS23881_REG_IT_CLASC << 8)) {
-+              ret = i2c_smbus_read_word_data(client, TPS23881_REG_DET_EVENT);
-+              if (ret < 0)
-+                      return ret;
-+
-+              val = ret;
-+              ret = tps23881_irq_event_detection(priv, val, notifs,
-+                                                 notifs_mask);
-+              if (ret)
-+                      return ret;
-+
-+              ret = tps23881_irq_event_classification(priv, val, notifs,
-+                                                      notifs_mask);
-+              if (ret)
-+                      return ret;
-+      }
-       return 0;
- }
-@@ -1178,7 +1376,14 @@ static int tps23881_setup_irq(struct tps
-       int ret;
-       u16 val;
--      val = TPS23881_REG_IT_IFAULT | TPS23881_REG_IT_SUPF;
-+      if (!irq) {
-+              dev_err(&client->dev, "interrupt is missing");
-+              return -EINVAL;
-+      }
-+
-+      val = TPS23881_REG_IT_IFAULT | TPS23881_REG_IT_SUPF |
-+            TPS23881_REG_IT_DETC | TPS23881_REG_IT_CLASC |
-+            TPS23881_REG_IT_DISF;
-       val |= val << 8;
-       ret = i2c_smbus_write_word_data(client, TPS23881_REG_IT_MASK, val);
-       if (ret)
-@@ -1188,11 +1393,19 @@ static int tps23881_setup_irq(struct tps
-       if (ret < 0)
-               return ret;
--      val = (u16)(ret | TPS23881_REG_INTEN | TPS23881_REG_INTEN << 8);
-+      val = TPS23881_REG_INTEN | TPS23881_REG_CLCHE | TPS23881_REG_DECHE;
-+      val |= val << 8;
-+      val |= (u16)ret;
-       ret = i2c_smbus_write_word_data(client, TPS23881_REG_GEN_MASK, val);
-       if (ret < 0)
-               return ret;
-+      /* Reset interrupts registers */
-+      ret = i2c_smbus_write_word_data(client, TPS23881_REG_RESET,
-+                                      TPS23881_REG_CLRAIN);
-+      if (ret < 0)
-+              return ret;
-+
-       return devm_pse_irq_helper(&priv->pcdev, irq, 0, &irq_desc);
- }
-@@ -1270,17 +1483,16 @@ static int tps23881_i2c_probe(struct i2c
-       priv->pcdev.dev = dev;
-       priv->pcdev.types = ETHTOOL_PSE_C33;
-       priv->pcdev.nr_lines = TPS23881_MAX_CHANS;
-+      priv->pcdev.supp_budget_eval_strategies = PSE_BUDGET_EVAL_STRAT_STATIC;
-       ret = devm_pse_controller_register(dev, &priv->pcdev);
-       if (ret) {
-               return dev_err_probe(dev, ret,
-                                    "failed to register PSE controller\n");
-       }
--      if (client->irq) {
--              ret = tps23881_setup_irq(priv, client->irq);
--              if (ret)
--                      return ret;
--      }
-+      ret = tps23881_setup_irq(priv, client->irq);
-+      if (ret)
-+              return ret;
-       return ret;
- }
diff --git a/target/linux/generic/backport-6.18/626-20-v6.17-net-pse-pd-pd692x0-reduce-stack-usage.patch b/target/linux/generic/backport-6.18/626-20-v6.17-net-pse-pd-pd692x0-reduce-stack-usage.patch
deleted file mode 100644 (file)
index d5e1aaf..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-From d12b3dc106090b358fb67b7c0c717a0884327ddf Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Wed, 9 Jul 2025 17:32:04 +0200
-Subject: [PATCH] net: pse-pd: pd692x0: reduce stack usage in
- pd692x0_setup_pi_matrix
-
-The pd692x0_manager array in this function is really too big to fit on the
-stack, though this never triggered a warning until a recent patch made
-it slightly bigger:
-
-drivers/net/pse-pd/pd692x0.c: In function 'pd692x0_setup_pi_matrix':
-drivers/net/pse-pd/pd692x0.c:1210:1: error: the frame size of 1584 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
-
-Change the function to dynamically allocate the array here.
-
-Fixes: 359754013e6a ("net: pse-pd: pd692x0: Add support for PSE PI priority feature")
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
-Link: https://patch.msgid.link/20250709153210.1920125-1-arnd@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pd692x0.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
---- a/drivers/net/pse-pd/pd692x0.c
-+++ b/drivers/net/pse-pd/pd692x0.c
-@@ -860,7 +860,7 @@ out:
- static int
- pd692x0_of_get_managers(struct pd692x0_priv *priv,
--                      struct pd692x0_manager manager[PD692X0_MAX_MANAGERS])
-+                      struct pd692x0_manager *manager)
- {
-       struct device_node *managers_node, *node;
-       int ret, nmanagers, i, j;
-@@ -1164,7 +1164,7 @@ pd692x0_write_ports_matrix(struct pd692x
- static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
- {
--      struct pd692x0_manager manager[PD692X0_MAX_MANAGERS] = {0};
-+      struct pd692x0_manager *manager __free(kfree) = NULL;
-       struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-       struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS];
-       int ret, i, j, nmanagers;
-@@ -1174,6 +1174,10 @@ static int pd692x0_setup_pi_matrix(struc
-           priv->fw_state != PD692X0_FW_COMPLETE)
-               return 0;
-+      manager = kcalloc(PD692X0_MAX_MANAGERS, sizeof(*manager), GFP_KERNEL);
-+      if (!manager)
-+              return -ENOMEM;
-+
-       ret = pd692x0_of_get_managers(priv, manager);
-       if (ret < 0)
-               return ret;
diff --git a/target/linux/generic/backport-6.18/626-21-v6.18-net-pse-pd-pd692x0-Fix-power-budget-leak.patch b/target/linux/generic/backport-6.18/626-21-v6.18-net-pse-pd-pd692x0-Fix-power-budget-leak.patch
deleted file mode 100644 (file)
index af23745..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-From 1c67f9c54cdc70627e3f6472b89cd3d895df974c Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Wed, 20 Aug 2025 15:27:07 +0200
-Subject: [PATCH] net: pse-pd: pd692x0: Fix power budget leak in manager setup
- error path
-
-Fix a resource leak where manager power budgets were freed on both
-success and error paths during manager setup. Power budgets should
-only be freed on error paths after regulator registration or during
-driver removal.
-
-Refactor cleanup logic by extracting OF node cleanup and power budget
-freeing into separate helper functions for better maintainability.
-
-Fixes: 359754013e6a ("net: pse-pd: pd692x0: Add support for PSE PI priority feature")
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Link: https://patch.msgid.link/20250820132708.837255-1-kory.maincent@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pd692x0.c | 59 +++++++++++++++++++++++++++---------
- 1 file changed, 44 insertions(+), 15 deletions(-)
-
---- a/drivers/net/pse-pd/pd692x0.c
-+++ b/drivers/net/pse-pd/pd692x0.c
-@@ -1162,12 +1162,44 @@ pd692x0_write_ports_matrix(struct pd692x
-       return 0;
- }
-+static void pd692x0_of_put_managers(struct pd692x0_priv *priv,
-+                                  struct pd692x0_manager *manager,
-+                                  int nmanagers)
-+{
-+      int i, j;
-+
-+      for (i = 0; i < nmanagers; i++) {
-+              for (j = 0; j < manager[i].nports; j++)
-+                      of_node_put(manager[i].port_node[j]);
-+              of_node_put(manager[i].node);
-+      }
-+}
-+
-+static void pd692x0_managers_free_pw_budget(struct pd692x0_priv *priv)
-+{
-+      int i;
-+
-+      for (i = 0; i < PD692X0_MAX_MANAGERS; i++) {
-+              struct regulator *supply;
-+
-+              if (!priv->manager_reg[i] || !priv->manager_pw_budget[i])
-+                      continue;
-+
-+              supply = priv->manager_reg[i]->supply;
-+              if (!supply)
-+                      continue;
-+
-+              regulator_free_power_budget(supply,
-+                                          priv->manager_pw_budget[i]);
-+      }
-+}
-+
- static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
- {
-       struct pd692x0_manager *manager __free(kfree) = NULL;
-       struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-       struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS];
--      int ret, i, j, nmanagers;
-+      int ret, nmanagers;
-       /* Should we flash the port matrix */
-       if (priv->fw_state != PD692X0_FW_OK &&
-@@ -1185,31 +1217,27 @@ static int pd692x0_setup_pi_matrix(struc
-       nmanagers = ret;
-       ret = pd692x0_register_managers_regulator(priv, manager, nmanagers);
-       if (ret)
--              goto out;
-+              goto err_of_managers;
-       ret = pd692x0_configure_managers(priv, nmanagers);
-       if (ret)
--              goto out;
-+              goto err_of_managers;
-       ret = pd692x0_set_ports_matrix(priv, manager, nmanagers, port_matrix);
-       if (ret)
--              goto out;
-+              goto err_managers_req_pw;
-       ret = pd692x0_write_ports_matrix(priv, port_matrix);
-       if (ret)
--              goto out;
--
--out:
--      for (i = 0; i < nmanagers; i++) {
--              struct regulator *supply = priv->manager_reg[i]->supply;
-+              goto err_managers_req_pw;
--              regulator_free_power_budget(supply,
--                                          priv->manager_pw_budget[i]);
-+      pd692x0_of_put_managers(priv, manager, nmanagers);
-+      return 0;
--              for (j = 0; j < manager[i].nports; j++)
--                      of_node_put(manager[i].port_node[j]);
--              of_node_put(manager[i].node);
--      }
-+err_managers_req_pw:
-+      pd692x0_managers_free_pw_budget(priv);
-+err_of_managers:
-+      pd692x0_of_put_managers(priv, manager, nmanagers);
-       return ret;
- }
-@@ -1748,6 +1776,7 @@ static void pd692x0_i2c_remove(struct i2
- {
-       struct pd692x0_priv *priv = i2c_get_clientdata(client);
-+      pd692x0_managers_free_pw_budget(priv);
-       firmware_upload_unregister(priv->fwl);
- }
diff --git a/target/linux/generic/backport-6.18/626-22-v6.18-net-pse-pd-pd692x0-Skip-power-budget-when-undefined.patch b/target/linux/generic/backport-6.18/626-22-v6.18-net-pse-pd-pd692x0-Skip-power-budget-when-undefined.patch
deleted file mode 100644 (file)
index 98da7b5..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From 7ef353879f714602b43f98662069f4fb86536761 Mon Sep 17 00:00:00 2001
-From: Kory Maincent <kory.maincent@bootlin.com>
-Date: Wed, 20 Aug 2025 15:33:21 +0200
-Subject: [PATCH] net: pse-pd: pd692x0: Skip power budget configuration when
- undefined
-
-If the power supply's power budget is not defined in the device tree,
-the current code still requests power and configures the PSE manager
-with a 0W power limit, which is undesirable behavior.
-
-Skip power budget configuration entirely when the budget is zero,
-avoiding unnecessary power requests and preventing invalid 0W limits
-from being set on the PSE manager.
-
-Fixes: 359754013e6a ("net: pse-pd: pd692x0: Add support for PSE PI priority feature")
-Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
-Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250820133321.841054-1-kory.maincent@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/pd692x0.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/pse-pd/pd692x0.c
-+++ b/drivers/net/pse-pd/pd692x0.c
-@@ -1041,6 +1041,10 @@ pd692x0_configure_managers(struct pd692x
-               int pw_budget;
-               pw_budget = regulator_get_unclaimed_power_budget(supply);
-+              if (!pw_budget)
-+                      /* Do nothing if no power budget */
-+                      continue;
-+
-               /* Max power budget per manager */
-               if (pw_budget > 6000000)
-                       pw_budget = 6000000;
diff --git a/target/linux/generic/backport-6.18/626-23-v6.18-net-pse-pd-Add-Si3474-PSE-controller-driver.patch b/target/linux/generic/backport-6.18/626-23-v6.18-net-pse-pd-Add-Si3474-PSE-controller-driver.patch
deleted file mode 100644 (file)
index 2f4087f..0000000
+++ /dev/null
@@ -1,636 +0,0 @@
-From a2317231df4b22e6634fe3d8645e7cef848acf49 Mon Sep 17 00:00:00 2001
-From: Piotr Kubik <piotr.kubik@adtran.com>
-Date: Tue, 26 Aug 2025 14:41:58 +0000
-Subject: [PATCH] net: pse-pd: Add Si3474 PSE controller driver
-
-Add a driver for the Skyworks Si3474 I2C Power Sourcing Equipment
-controller.
-
-Driver supports basic features of Si3474 IC:
-- get port status,
-- get port power,
-- get port voltage,
-- enable/disable port power.
-
-Only 4p configurations are supported at this moment.
-
-Signed-off-by: Piotr Kubik <piotr.kubik@adtran.com>
-Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
-Link: https://patch.msgid.link/9b72c8cd-c8d3-4053-9c80-671b9481d166@adtran.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/Kconfig  |  11 +
- drivers/net/pse-pd/Makefile |   1 +
- drivers/net/pse-pd/si3474.c | 578 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 590 insertions(+)
- create mode 100644 drivers/net/pse-pd/si3474.c
---- a/drivers/net/pse-pd/Kconfig
-+++ b/drivers/net/pse-pd/Kconfig
-@@ -32,6 +32,17 @@ config PSE_PD692X0
-         To compile this driver as a module, choose M here: the
-         module will be called pd692x0.
-+config PSE_SI3474
-+      tristate "Si3474 PSE controller"
-+      depends on I2C
-+      help
-+        This module provides support for Si3474 regulator based Ethernet
-+        Power Sourcing Equipment.
-+        Only 4-pair PSE configurations are supported.
-+
-+        To compile this driver as a module, choose M here: the
-+        module will be called si3474.
-+
- config PSE_TPS23881
-       tristate "TPS23881 PSE controller"
-       depends on I2C
---- a/drivers/net/pse-pd/Makefile
-+++ b/drivers/net/pse-pd/Makefile
-@@ -5,4 +5,5 @@ obj-$(CONFIG_PSE_CONTROLLER) += pse_core
- obj-$(CONFIG_PSE_REGULATOR) += pse_regulator.o
- obj-$(CONFIG_PSE_PD692X0) += pd692x0.o
-+obj-$(CONFIG_PSE_SI3474) += si3474.o
- obj-$(CONFIG_PSE_TPS23881) += tps23881.o
---- /dev/null
-+++ b/drivers/net/pse-pd/si3474.c
-@@ -0,0 +1,578 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Driver for the Skyworks Si3474 PoE PSE Controller
-+ *
-+ * Chip Architecture & Terminology:
-+ *
-+ * The Si3474 is a single-chip PoE PSE controller managing 8 physical power
-+ * delivery channels. Internally, it's structured into two logical "Quads".
-+ *
-+ * Quad 0: Manages physical channels ('ports' in datasheet) 0, 1, 2, 3
-+ * Quad 1: Manages physical channels ('ports' in datasheet) 4, 5, 6, 7
-+ *
-+ * Each Quad is accessed via a separate I2C address. The base address range is
-+ * set by hardware pins A1-A4, and the specific address selects Quad 0 (usually
-+ * the lower/even address) or Quad 1 (usually the higher/odd address).
-+ * See datasheet Table 2.2 for the address mapping.
-+ *
-+ * While the Quads manage channel-specific operations, the Si3474 package has
-+ * several resources shared across the entire chip:
-+ * - Single RESETb input pin.
-+ * - Single INTb output pin (signals interrupts from *either* Quad).
-+ * - Single OSS input pin (Emergency Shutdown).
-+ * - Global I2C Address (0x7F) used for firmware updates.
-+ * - Global status monitoring (Temperature, VDD/VPWR Undervoltage Lockout).
-+ *
-+ * Driver Architecture:
-+ *
-+ * To handle the mix of per-Quad access and shared resources correctly, this
-+ * driver treats the entire Si3474 package as one logical device. The driver
-+ * instance associated with the primary I2C address (Quad 0) takes ownership.
-+ * It discovers and manages the I2C client for the secondary address (Quad 1).
-+ * This primary instance handles shared resources like IRQ management and
-+ * registers a single PSE controller device representing all logical PIs.
-+ * Internal functions route I2C commands to the appropriate Quad's i2c_client
-+ * based on the target channel or PI.
-+ *
-+ * Terminology Mapping:
-+ *
-+ * - "PI" (Power Interface): Refers to the logical PSE port as defined by
-+ * IEEE 802.3 (typically corresponds to an RJ45 connector). This is the
-+ * `id` (0-7) used in the pse_controller_ops.
-+ * - "Channel": Refers to one of the 8 physical power control paths within
-+ * the Si3474 chip itself (hardware channels 0-7). This terminology is
-+ * used internally within the driver to avoid confusion with 'ports'.
-+ * - "Quad": One of the two internal 4-channel management units within the
-+ * Si3474, each accessed via its own I2C address.
-+ *
-+ * Relationship:
-+ * - A 2-Pair PoE PI uses 1 Channel.
-+ * - A 4-Pair PoE PI uses 2 Channels.
-+ *
-+ * ASCII Schematic:
-+ *
-+ * +-----------------------------------------------------+
-+ * |                    Si3474 Chip                      |
-+ * |                                                     |
-+ * | +---------------------+     +---------------------+ |
-+ * | |      Quad 0         |     |      Quad 1         | |
-+ * | | Channels 0, 1, 2, 3 |     | Channels 4, 5, 6, 7 | |
-+ * | +----------^----------+     +-------^-------------+ |
-+ * | I2C Addr 0 |                        | I2C Addr 1    |
-+ * |            +------------------------+               |
-+ * | (Primary Driver Instance) (Managed by Primary)      |
-+ * |                                                     |
-+ * | Shared Resources (affect whole chip):               |
-+ * |  - Single INTb Output -> Handled by Primary         |
-+ * |  - Single RESETb Input                              |
-+ * |  - Single OSS Input   -> Handled by Primary         |
-+ * |  - Global I2C Addr (0x7F) for Firmware Update       |
-+ * |  - Global Status (Temp, VDD/VPWR UVLO)              |
-+ * +-----------------------------------------------------+
-+ *        |   |   |   |        |   |   |   |
-+ *        Ch0 Ch1 Ch2 Ch3      Ch4 Ch5 Ch6 Ch7  (Physical Channels)
-+ *
-+ * Example Mapping (Logical PI to Physical Channel(s)):
-+ * * 2-Pair Mode (8 PIs):
-+ * PI 0 -> Ch 0
-+ * PI 1 -> Ch 1
-+ * ...
-+ * PI 7 -> Ch 7
-+ * * 4-Pair Mode (4 PIs):
-+ * PI 0 -> Ch 0 + Ch 1  (Managed via Quad 0 Addr)
-+ * PI 1 -> Ch 2 + Ch 3  (Managed via Quad 0 Addr)
-+ * PI 2 -> Ch 4 + Ch 5  (Managed via Quad 1 Addr)
-+ * PI 3 -> Ch 6 + Ch 7  (Managed via Quad 1 Addr)
-+ * (Note: Actual mapping depends on Device Tree and PORT_REMAP config)
-+ */
-+
-+#include <linux/i2c.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pse-pd/pse.h>
-+
-+#define SI3474_MAX_CHANS 8
-+
-+#define MANUFACTURER_ID 0x08
-+#define IC_ID 0x05
-+#define SI3474_DEVICE_ID (MANUFACTURER_ID << 3 | IC_ID)
-+
-+/* Misc registers */
-+#define VENDOR_IC_ID_REG 0x1B
-+#define TEMPERATURE_REG 0x2C
-+#define FIRMWARE_REVISION_REG 0x41
-+#define CHIP_REVISION_REG 0x43
-+
-+/* Main status registers */
-+#define POWER_STATUS_REG 0x10
-+#define PORT_MODE_REG 0x12
-+#define DETECT_CLASS_ENABLE_REG 0x14
-+
-+/* PORTn Current */
-+#define PORT1_CURRENT_LSB_REG 0x30
-+
-+/* PORTn Current [mA], return in [nA] */
-+/* 1000 * ((PORTn_CURRENT_MSB << 8) + PORTn_CURRENT_LSB) / 16384 */
-+#define SI3474_NA_STEP (1000 * 1000 * 1000 / 16384)
-+
-+/* VPWR Voltage */
-+#define VPWR_LSB_REG 0x2E
-+#define VPWR_MSB_REG 0x2F
-+
-+/* PORTn Voltage */
-+#define PORT1_VOLTAGE_LSB_REG 0x32
-+
-+/* VPWR Voltage [V], return in [uV] */
-+/* 60 * (( VPWR_MSB << 8) + VPWR_LSB) / 16384 */
-+#define SI3474_UV_STEP (1000 * 1000 * 60 / 16384)
-+
-+/* Helper macros */
-+#define CHAN_IDX(chan) ((chan) % 4)
-+#define CHAN_BIT(chan) BIT(CHAN_IDX(chan))
-+#define CHAN_UPPER_BIT(chan) BIT(CHAN_IDX(chan) + 4)
-+
-+#define CHAN_MASK(chan) (0x03U << (2 * CHAN_IDX(chan)))
-+#define CHAN_REG(base, chan) ((base) + (CHAN_IDX(chan) * 4))
-+
-+struct si3474_pi_desc {
-+      u8 chan[2];
-+      bool is_4p;
-+};
-+
-+struct si3474_priv {
-+      struct i2c_client *client[2];
-+      struct pse_controller_dev pcdev;
-+      struct device_node *np;
-+      struct si3474_pi_desc pi[SI3474_MAX_CHANS];
-+};
-+
-+static struct si3474_priv *to_si3474_priv(struct pse_controller_dev *pcdev)
-+{
-+      return container_of(pcdev, struct si3474_priv, pcdev);
-+}
-+
-+static void si3474_get_channels(struct si3474_priv *priv, int id,
-+                              u8 *chan0, u8 *chan1)
-+{
-+      *chan0 = priv->pi[id].chan[0];
-+      *chan1 = priv->pi[id].chan[1];
-+}
-+
-+static struct i2c_client *si3474_get_chan_client(struct si3474_priv *priv,
-+                                               u8 chan)
-+{
-+      return (chan < 4) ? priv->client[0] : priv->client[1];
-+}
-+
-+static int si3474_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,
-+                                   struct pse_admin_state *admin_state)
-+{
-+      struct si3474_priv *priv = to_si3474_priv(pcdev);
-+      struct i2c_client *client;
-+      bool is_enabled;
-+      u8 chan0, chan1;
-+      s32 ret;
-+
-+      si3474_get_channels(priv, id, &chan0, &chan1);
-+      client = si3474_get_chan_client(priv, chan0);
-+
-+      ret = i2c_smbus_read_byte_data(client, PORT_MODE_REG);
-+      if (ret < 0) {
-+              admin_state->c33_admin_state =
-+                      ETHTOOL_C33_PSE_ADMIN_STATE_UNKNOWN;
-+              return ret;
-+      }
-+
-+      is_enabled = ret & (CHAN_MASK(chan0) | CHAN_MASK(chan1));
-+
-+      if (is_enabled)
-+              admin_state->c33_admin_state =
-+                      ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
-+      else
-+              admin_state->c33_admin_state =
-+                      ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
-+
-+      return 0;
-+}
-+
-+static int si3474_pi_get_pw_status(struct pse_controller_dev *pcdev, int id,
-+                                 struct pse_pw_status *pw_status)
-+{
-+      struct si3474_priv *priv = to_si3474_priv(pcdev);
-+      struct i2c_client *client;
-+      bool delivering;
-+      u8 chan0, chan1;
-+      s32 ret;
-+
-+      si3474_get_channels(priv, id, &chan0, &chan1);
-+      client = si3474_get_chan_client(priv, chan0);
-+
-+      ret = i2c_smbus_read_byte_data(client, POWER_STATUS_REG);
-+      if (ret < 0) {
-+              pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_UNKNOWN;
-+              return ret;
-+      }
-+
-+      delivering = ret & (CHAN_UPPER_BIT(chan0) | CHAN_UPPER_BIT(chan1));
-+
-+      if (delivering)
-+              pw_status->c33_pw_status =
-+                      ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
-+      else
-+              pw_status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
-+
-+      return 0;
-+}
-+
-+static int si3474_get_of_channels(struct si3474_priv *priv)
-+{
-+      struct pse_pi *pi;
-+      u32 chan_id;
-+      u8 pi_no;
-+      s32 ret;
-+
-+      for (pi_no = 0; pi_no < SI3474_MAX_CHANS; pi_no++) {
-+              pi = &priv->pcdev.pi[pi_no];
-+              bool pairset_found = false;
-+              u8 pairset_no;
-+
-+              for (pairset_no = 0; pairset_no < 2; pairset_no++) {
-+                      if (!pi->pairset[pairset_no].np)
-+                              continue;
-+
-+                      pairset_found = true;
-+
-+                      ret = of_property_read_u32(pi->pairset[pairset_no].np,
-+                                                 "reg", &chan_id);
-+                      if (ret) {
-+                              dev_err(&priv->client[0]->dev,
-+                                      "Failed to read channel reg property\n");
-+                              return ret;
-+                      }
-+                      if (chan_id > SI3474_MAX_CHANS) {
-+                              dev_err(&priv->client[0]->dev,
-+                                      "Incorrect channel number: %d\n", chan_id);
-+                              return -EINVAL;
-+                      }
-+
-+                      priv->pi[pi_no].chan[pairset_no] = chan_id;
-+                      /* Mark as 4-pair if second pairset is present */
-+                      priv->pi[pi_no].is_4p = (pairset_no == 1);
-+              }
-+
-+              if (pairset_found && !priv->pi[pi_no].is_4p) {
-+                      dev_err(&priv->client[0]->dev,
-+                              "Second pairset is missing for PI %pOF, only 4p configs are supported\n",
-+                              pi->np);
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int si3474_setup_pi_matrix(struct pse_controller_dev *pcdev)
-+{
-+      struct si3474_priv *priv = to_si3474_priv(pcdev);
-+      s32 ret;
-+
-+      ret = si3474_get_of_channels(priv);
-+      if (ret < 0)
-+              dev_warn(&priv->client[0]->dev,
-+                       "Unable to parse DT PSE power interface matrix\n");
-+
-+      return ret;
-+}
-+
-+static int si3474_pi_enable(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct si3474_priv *priv = to_si3474_priv(pcdev);
-+      struct i2c_client *client;
-+      u8 chan0, chan1;
-+      s32 ret;
-+      u8 val;
-+
-+      si3474_get_channels(priv, id, &chan0, &chan1);
-+      client = si3474_get_chan_client(priv, chan0);
-+
-+      /* Release PI from shutdown */
-+      ret = i2c_smbus_read_byte_data(client, PORT_MODE_REG);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = (u8)ret;
-+      val |= CHAN_MASK(chan0);
-+      val |= CHAN_MASK(chan1);
-+
-+      ret = i2c_smbus_write_byte_data(client, PORT_MODE_REG, val);
-+      if (ret)
-+              return ret;
-+
-+      /* DETECT_CLASS_ENABLE must be set when using AUTO mode,
-+       * otherwise PI does not power up - datasheet section 2.10.2
-+       */
-+      val = CHAN_BIT(chan0) | CHAN_UPPER_BIT(chan0) |
-+            CHAN_BIT(chan1) | CHAN_UPPER_BIT(chan1);
-+
-+      ret = i2c_smbus_write_byte_data(client, DETECT_CLASS_ENABLE_REG, val);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static int si3474_pi_disable(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct si3474_priv *priv = to_si3474_priv(pcdev);
-+      struct i2c_client *client;
-+      u8 chan0, chan1;
-+      s32 ret;
-+      u8 val;
-+
-+      si3474_get_channels(priv, id, &chan0, &chan1);
-+      client = si3474_get_chan_client(priv, chan0);
-+
-+      /* Set PI in shutdown mode */
-+      ret = i2c_smbus_read_byte_data(client, PORT_MODE_REG);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = (u8)ret;
-+      val &= ~CHAN_MASK(chan0);
-+      val &= ~CHAN_MASK(chan1);
-+
-+      ret = i2c_smbus_write_byte_data(client, PORT_MODE_REG, val);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static int si3474_pi_get_chan_current(struct si3474_priv *priv, u8 chan)
-+{
-+      struct i2c_client *client;
-+      u64 tmp_64;
-+      s32 ret;
-+      u8 reg;
-+
-+      client = si3474_get_chan_client(priv, chan);
-+
-+      /* Registers 0x30 to 0x3d */
-+      reg = CHAN_REG(PORT1_CURRENT_LSB_REG, chan);
-+
-+      ret = i2c_smbus_read_word_data(client, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      tmp_64 = ret * SI3474_NA_STEP;
-+
-+      /* uA = nA / 1000 */
-+      tmp_64 = DIV_ROUND_CLOSEST_ULL(tmp_64, 1000);
-+      return (int)tmp_64;
-+}
-+
-+static int si3474_pi_get_chan_voltage(struct si3474_priv *priv, u8 chan)
-+{
-+      struct i2c_client *client;
-+      s32 ret;
-+      u32 val;
-+      u8 reg;
-+
-+      client = si3474_get_chan_client(priv, chan);
-+
-+      /* Registers 0x32 to 0x3f */
-+      reg = CHAN_REG(PORT1_VOLTAGE_LSB_REG, chan);
-+
-+      ret = i2c_smbus_read_word_data(client, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      val = ret * SI3474_UV_STEP;
-+
-+      return (int)val;
-+}
-+
-+static int si3474_pi_get_voltage(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct si3474_priv *priv = to_si3474_priv(pcdev);
-+      struct i2c_client *client;
-+      u8 chan0, chan1;
-+      s32 ret;
-+
-+      si3474_get_channels(priv, id, &chan0, &chan1);
-+      client = si3474_get_chan_client(priv, chan0);
-+
-+      /* Check which channels are enabled*/
-+      ret = i2c_smbus_read_byte_data(client, POWER_STATUS_REG);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Take voltage from the first enabled channel */
-+      if (ret & CHAN_BIT(chan0))
-+              ret = si3474_pi_get_chan_voltage(priv, chan0);
-+      else if (ret & CHAN_BIT(chan1))
-+              ret = si3474_pi_get_chan_voltage(priv, chan1);
-+      else
-+              /* 'should' be no voltage in this case */
-+              return 0;
-+
-+      return ret;
-+}
-+
-+static int si3474_pi_get_actual_pw(struct pse_controller_dev *pcdev, int id)
-+{
-+      struct si3474_priv *priv = to_si3474_priv(pcdev);
-+      u8 chan0, chan1;
-+      u32 uV, uA;
-+      u64 tmp_64;
-+      s32 ret;
-+
-+      ret = si3474_pi_get_voltage(&priv->pcdev, id);
-+
-+      /* Do not read currents if voltage is 0 */
-+      if (ret <= 0)
-+              return ret;
-+      uV = ret;
-+
-+      si3474_get_channels(priv, id, &chan0, &chan1);
-+
-+      ret = si3474_pi_get_chan_current(priv, chan0);
-+      if (ret < 0)
-+              return ret;
-+      uA = ret;
-+
-+      ret = si3474_pi_get_chan_current(priv, chan1);
-+      if (ret < 0)
-+              return ret;
-+      uA += ret;
-+
-+      tmp_64 = uV;
-+      tmp_64 *= uA;
-+      /* mW = uV * uA / 1000000000 */
-+      return DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
-+}
-+
-+static const struct pse_controller_ops si3474_ops = {
-+      .setup_pi_matrix = si3474_setup_pi_matrix,
-+      .pi_enable = si3474_pi_enable,
-+      .pi_disable = si3474_pi_disable,
-+      .pi_get_actual_pw = si3474_pi_get_actual_pw,
-+      .pi_get_voltage = si3474_pi_get_voltage,
-+      .pi_get_admin_state = si3474_pi_get_admin_state,
-+      .pi_get_pw_status = si3474_pi_get_pw_status,
-+};
-+
-+static void si3474_ancillary_i2c_remove(void *data)
-+{
-+      struct i2c_client *client = data;
-+
-+      i2c_unregister_device(client);
-+}
-+
-+static int si3474_i2c_probe(struct i2c_client *client)
-+{
-+      struct device *dev = &client->dev;
-+      struct si3474_priv *priv;
-+      u8 fw_version;
-+      s32 ret;
-+
-+      if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-+              dev_err(dev, "i2c check functionality failed\n");
-+              return -ENXIO;
-+      }
-+
-+      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+
-+      ret = i2c_smbus_read_byte_data(client, VENDOR_IC_ID_REG);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (ret != SI3474_DEVICE_ID) {
-+              dev_err(dev, "Wrong device ID: 0x%x\n", ret);
-+              return -ENXIO;
-+      }
-+
-+      ret = i2c_smbus_read_byte_data(client, FIRMWARE_REVISION_REG);
-+      if (ret < 0)
-+              return ret;
-+      fw_version = ret;
-+
-+      ret = i2c_smbus_read_byte_data(client, CHIP_REVISION_REG);
-+      if (ret < 0)
-+              return ret;
-+
-+      dev_dbg(dev, "Chip revision: 0x%x, firmware version: 0x%x\n",
-+              ret, fw_version);
-+
-+      priv->client[0] = client;
-+      i2c_set_clientdata(client, priv);
-+
-+      priv->client[1] = i2c_new_ancillary_device(priv->client[0], "secondary",
-+                                                 priv->client[0]->addr + 1);
-+      if (IS_ERR(priv->client[1]))
-+              return PTR_ERR(priv->client[1]);
-+
-+      ret = devm_add_action_or_reset(dev, si3474_ancillary_i2c_remove, priv->client[1]);
-+      if (ret < 0) {
-+              dev_err(&priv->client[1]->dev, "Cannot register remove callback\n");
-+              return ret;
-+      }
-+
-+      ret = i2c_smbus_read_byte_data(priv->client[1], VENDOR_IC_ID_REG);
-+      if (ret < 0) {
-+              dev_err(&priv->client[1]->dev, "Cannot access secondary PSE controller\n");
-+              return ret;
-+      }
-+
-+      if (ret != SI3474_DEVICE_ID) {
-+              dev_err(&priv->client[1]->dev,
-+                      "Wrong device ID for secondary PSE controller: 0x%x\n", ret);
-+              return -ENXIO;
-+      }
-+
-+      priv->np = dev->of_node;
-+      priv->pcdev.owner = THIS_MODULE;
-+      priv->pcdev.ops = &si3474_ops;
-+      priv->pcdev.dev = dev;
-+      priv->pcdev.types = ETHTOOL_PSE_C33;
-+      priv->pcdev.nr_lines = SI3474_MAX_CHANS;
-+
-+      ret = devm_pse_controller_register(dev, &priv->pcdev);
-+      if (ret) {
-+              dev_err(dev, "Failed to register PSE controller: 0x%x\n", ret);
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static const struct i2c_device_id si3474_id[] = {
-+      { "si3474" },
-+      {}
-+};
-+MODULE_DEVICE_TABLE(i2c, si3474_id);
-+
-+static const struct of_device_id si3474_of_match[] = {
-+      {
-+              .compatible = "skyworks,si3474",
-+      },
-+      {},
-+};
-+MODULE_DEVICE_TABLE(of, si3474_of_match);
-+
-+static struct i2c_driver si3474_driver = {
-+      .probe = si3474_i2c_probe,
-+      .id_table = si3474_id,
-+      .driver = {
-+              .name = "si3474",
-+              .of_match_table = si3474_of_match,
-+      },
-+};
-+module_i2c_driver(si3474_driver);
-+
-+MODULE_AUTHOR("Piotr Kubik <piotr.kubik@adtran.com>");
-+MODULE_DESCRIPTION("Skyworks Si3474 PoE PSE Controller driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.18/626-24-v6.19-net-pse-pd-tps23881-Fix-current-measurement-scaling.patch b/target/linux/generic/backport-6.18/626-24-v6.19-net-pse-pd-tps23881-Fix-current-measurement-scaling.patch
deleted file mode 100644 (file)
index 5150da3..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From 2c95a756e0cfc19af6d0b32b0c6cf3bada334998 Mon Sep 17 00:00:00 2001
-From: Thomas Wismer <thomas.wismer@scs.ch>
-Date: Mon, 6 Oct 2025 22:40:29 +0200
-Subject: [PATCH] net: pse-pd: tps23881: Fix current measurement scaling
-
-The TPS23881 improves on the TPS23880 with current sense resistors reduced
-from 255 mOhm to 200 mOhm. This has a direct impact on the scaling of the
-current measurement. However, the latest TPS23881 data sheet from May 2023
-still shows the scaling of the TPS23880 model.
-
-Fixes: 7f076ce3f1733 ("net: pse-pd: tps23881: Add support for power limit and measurement features")
-Signed-off-by: Thomas Wismer <thomas.wismer@scs.ch>
-Acked-by: Kory Maincent <kory.maincent@bootlin.com>
-Link: https://patch.msgid.link/20251006204029.7169-2-thomas@wismer.xyz
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- drivers/net/pse-pd/tps23881.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/pse-pd/tps23881.c
-+++ b/drivers/net/pse-pd/tps23881.c
-@@ -62,7 +62,7 @@
- #define TPS23881_REG_SRAM_DATA        0x61
- #define TPS23881_UV_STEP      3662
--#define TPS23881_NA_STEP      70190
-+#define TPS23881_NA_STEP      89500
- #define TPS23881_MW_STEP      500
- #define TPS23881_MIN_PI_PW_LIMIT_MW   2000
diff --git a/target/linux/generic/backport-6.18/626-v6.16-net-bridge-locally-receive-all-multicast-packets-if-.patch b/target/linux/generic/backport-6.18/626-v6.16-net-bridge-locally-receive-all-multicast-packets-if-.patch
deleted file mode 100644 (file)
index d9bd8c7..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From a496d2f0fd612ab9e10700afe00dc9267bad788b Mon Sep 17 00:00:00 2001
-From: Shengyu Qu <wiagn233@outlook.com>
-Date: Mon, 14 Apr 2025 18:56:01 +0800
-Subject: net: bridge: locally receive all multicast packets if IFF_ALLMULTI is
- set
-
-If multicast snooping is enabled, multicast packets may not always end up
-on the local bridge interface, if the host is not a member of the multicast
-group. Similar to how IFF_PROMISC allows all packets to be received
-locally, let IFF_ALLMULTI allow all multicast packets to be received.
-
-OpenWrt uses a user space daemon for DHCPv6/RA/NDP handling, and in relay
-mode it sets the ALLMULTI flag in order to receive all relevant queries on
-the network.
-
-This works for normal network interfaces and non-snooping bridges, but not
-snooping bridges (unless multicast routing is enabled).
-
-Reported-by: Felix Fietkau <nbd@nbd.name>
-Closes: https://github.com/openwrt/openwrt/issues/15857#issuecomment-2662851243
-Signed-off-by: Shengyu Qu <wiagn233@outlook.com>
-Reviewed-by: Ido Schimmel <idosch@nvidia.com>
-Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
-Link: https://patch.msgid.link/OSZPR01MB8434308370ACAFA90A22980798B32@OSZPR01MB8434.jpnprd01.prod.outlook.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/bridge/br_input.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -184,7 +184,8 @@ int br_handle_frame_finish(struct net *n
-               if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
-                   br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) {
-                       if ((mdst && mdst->host_joined) ||
--                          br_multicast_is_router(brmctx, skb)) {
-+                          br_multicast_is_router(brmctx, skb) ||
-+                          br->dev->flags & IFF_ALLMULTI) {
-                               local_rcv = true;
-                               DEV_STATS_INC(br->dev, multicast);
-                       }
diff --git a/target/linux/generic/backport-6.18/627-01-v6.17-net-pse-pd-Add-ethtool_netlink_generated-header.patch b/target/linux/generic/backport-6.18/627-01-v6.17-net-pse-pd-Add-ethtool_netlink_generated-header.patch
deleted file mode 100644 (file)
index f773fb6..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: OpenWrt PSE-PD Backport <openwrt@openwrt.org>
-Date: Fri, 31 Jan 2025 00:00:00 +0000
-Subject: [PATCH] net: pse-pd: Add ethtool netlink definitions for PSE events
- and priority
-
-GENERATED PATCH - OpenWrt PSE-PD Backport
-
-This patch:
-1. Adds ETHTOOL_A_PSE_PW_D_ID, ETHTOOL_A_PSE_PRIO_MAX, ETHTOOL_A_PSE_PRIO to
-   the ETHTOOL_A_PSE_* enum in ethtool_netlink.h (backported from kernel 6.17+)
-2. Creates include/uapi/linux/ethtool_netlink_generated.h with PSE event
-   definitions (in mainline 6.17+, this file is auto-generated)
-3. Adds ETHTOOL_MSG_PSE_NTF to the kernel message types enum
-
-These definitions are required by PSE event reporting and priority patches.
-
-Signed-off-by: OpenWrt PSE-PD Backport <openwrt@openwrt.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- include/uapi/linux/ethtool_netlink.h           |  4 ++
- include/uapi/linux/ethtool_netlink_generated.h | 31 ++++++++++++++++++++++++++
- 2 files changed, 35 insertions(+)
- create mode 100644 include/uapi/linux/ethtool_netlink_generated.h
-
---- a/include/uapi/linux/ethtool_netlink.h
-+++ b/include/uapi/linux/ethtool_netlink.h
-@@ -115,6 +115,7 @@ enum {
-       ETHTOOL_MSG_PHY_GET_REPLY,
-       ETHTOOL_MSG_PHY_NTF,
-+      ETHTOOL_MSG_PSE_NTF,
-       /* add new constants above here */
-       __ETHTOOL_MSG_KERNEL_CNT,
-       ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1
-@@ -970,6 +971,9 @@ enum {
-       ETHTOOL_A_C33_PSE_EXT_SUBSTATE,         /* u32 */
-       ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT,       /* u32 */
-       ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES,      /* nest - _C33_PSE_PW_LIMIT_* */
-+      ETHTOOL_A_PSE_PW_D_ID,                  /* u32 */
-+      ETHTOOL_A_PSE_PRIO_MAX,                 /* u32 */
-+      ETHTOOL_A_PSE_PRIO,                     /* u32 */
-       /* add new constants above here */
-       __ETHTOOL_A_PSE_CNT,
---- /dev/null
-+++ b/include/uapi/linux/ethtool_netlink_generated.h
-@@ -0,0 +1,31 @@
-+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
-+/* PSE ethtool netlink definitions - OpenWrt backport for 6.12 */
-+
-+#ifndef _UAPI_LINUX_ETHTOOL_NETLINK_GENERATED_H
-+#define _UAPI_LINUX_ETHTOOL_NETLINK_GENERATED_H
-+
-+enum ethtool_pse_event {
-+      ETHTOOL_PSE_EVENT_OVER_CURRENT = 1,
-+      ETHTOOL_PSE_EVENT_OVER_TEMP = 2,
-+      ETHTOOL_C33_PSE_EVENT_DETECTION = 4,
-+      ETHTOOL_C33_PSE_EVENT_CLASSIFICATION = 8,
-+      ETHTOOL_C33_PSE_EVENT_DISCONNECTION = 16,
-+      ETHTOOL_PSE_EVENT_OVER_BUDGET = 32,
-+      ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR = 64,
-+};
-+
-+enum {
-+      ETHTOOL_A_PSE_NTF_HEADER = 1,
-+      ETHTOOL_A_PSE_NTF_EVENTS,
-+      __ETHTOOL_A_PSE_NTF_CNT,
-+      ETHTOOL_A_PSE_NTF_MAX = (__ETHTOOL_A_PSE_NTF_CNT - 1)
-+};
-+
-+enum {
-+      ETHTOOL_A_PSE_NTF_EVT_UNSPEC,
-+      ETHTOOL_A_PSE_NTF_EVT_INDEX,
-+      __ETHTOOL_A_PSE_NTF_EVT_CNT,
-+      ETHTOOL_A_PSE_NTF_EVT_MAX = (__ETHTOOL_A_PSE_NTF_EVT_CNT - 1)
-+};
-+
-+#endif /* _UAPI_LINUX_ETHTOOL_NETLINK_GENERATED_H */
diff --git a/target/linux/generic/backport-6.18/627-02-v6.17-net-ethtool-Add-PSE-port-priority-support.patch b/target/linux/generic/backport-6.18/627-02-v6.17-net-ethtool-Add-PSE-port-priority-support.patch
deleted file mode 100644 (file)
index 06d9b11..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-# ADAPTED FOR OPENWRT 6.12 - Documentation changes removed
-# Original commit: eeb0c8f72f49
-From eeb0c8f72f49a21984981188404cfd3700edbaff Mon Sep 17 00:00:00 2001
-From: "Kory Maincent (Dent Project)" <kory.maincent@bootlin.com>
-Date: Tue, 17 Jun 2025 14:12:07 +0200
-Subject: [PATCH] net: ethtool: Add PSE port priority support feature
-
-This patch expands the status information provided by ethtool for PSE c33
-with current port priority and max port priority. It also adds a call to
-pse_ethtool_set_prio() to configure the PSE port priority.
-
-Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
-Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
-Link: https://patch.msgid.link/20250617-feature_poe_port_prio-v14-8-78a1a645e2ee@bootlin.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
----
- net/ethtool/pse-pd.c | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/net/ethtool/pse-pd.c
-+++ b/net/ethtool/pse-pd.c
-@@ -111,6 +111,9 @@ static int pse_reply_size(const struct e
-               len += st->c33_pw_limit_nb_ranges *
-                      (nla_total_size(0) +
-                       nla_total_size(sizeof(u32)) * 2);
-+      if (st->prio_max)
-+              /* _PSE_PRIO_MAX + _PSE_PRIO */
-+              len += nla_total_size(sizeof(u32)) * 2;
-       return len;
- }
-@@ -205,6 +208,11 @@ static int pse_fill_reply(struct sk_buff
-           pse_put_pw_limit_ranges(skb, st))
-               return -EMSGSIZE;
-+      if (st->prio_max &&
-+          (nla_put_u32(skb, ETHTOOL_A_PSE_PRIO_MAX, st->prio_max) ||
-+           nla_put_u32(skb, ETHTOOL_A_PSE_PRIO, st->prio)))
-+              return -EMSGSIZE;
-+
-       return 0;
- }
-@@ -226,6 +234,7 @@ const struct nla_policy ethnl_pse_set_po
-               NLA_POLICY_RANGE(NLA_U32, ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED,
-                                ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED),
-       [ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT] = { .type = NLA_U32 },
-+      [ETHTOOL_A_PSE_PRIO] = { .type = NLA_U32 },
- };
- static int
-@@ -283,6 +292,15 @@ ethnl_set_pse(struct ethnl_req_info *req
-               if (ret)
-                       return ret;
-       }
-+
-+      if (tb[ETHTOOL_A_PSE_PRIO]) {
-+              unsigned int prio;
-+
-+              prio = nla_get_u32(tb[ETHTOOL_A_PSE_PRIO]);
-+              ret = pse_ethtool_set_prio(phydev->psec, info->extack, prio);
-+              if (ret)
-+                      return ret;
-+      }
-       /* These values are already validated by the ethnl_pse_set_policy */
-       if (tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] ||
diff --git a/target/linux/generic/backport-6.18/630-v6.13-net-usb-qmi_wwan-add-Quectel-RG255C.patch b/target/linux/generic/backport-6.18/630-v6.13-net-usb-qmi_wwan-add-Quectel-RG255C.patch
deleted file mode 100644 (file)
index a1eb835..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From 5c964c8a97c12145104f5d2782aa1ffccf3a93dd Mon Sep 17 00:00:00 2001
-From: Martin Hou <martin.hou@foxmail.com>
-Date: Mon, 16 Dec 2024 11:06:18 +0800
-Subject: [PATCH] net: usb: qmi_wwan: add Quectel RG255C
-
-Add support for Quectel RG255C which is based on Qualcomm SDX35 chip.
-The composition is DM / NMEA / AT / QMI.
-
-T:  Bus=01 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#=  2 Spd=480  MxCh= 0
-D:  Ver= 2.01 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
-P:  Vendor=2c7c ProdID=0316 Rev= 5.15
-S:  Manufacturer=Quectel
-S:  Product=RG255C-CN
-S:  SerialNumber=c68192c1
-C:* #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=500mA
-I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
-E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
-E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
-E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
-E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan
-E:  Ad=86(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
-E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
-
-Signed-off-by: Martin Hou <martin.hou@foxmail.com>
-Link: https://patch.msgid.link/tencent_17DDD787B48E8A5AB8379ED69E23A0CD9309@qq.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/usb/qmi_wwan.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/usb/qmi_wwan.c
-+++ b/drivers/net/usb/qmi_wwan.c
-@@ -1442,6 +1442,7 @@ static const struct usb_device_id produc
-       {QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)}, /* Quectel EG95 */
-       {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)},    /* Quectel BG96 */
-       {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */
-+      {QMI_QUIRK_SET_DTR(0x2c7c, 0x0316, 3)}, /* Quectel RG255C */
-       {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */
-       {QMI_QUIRK_SET_DTR(0x2cb7, 0x0112, 0)}, /* Fibocom FG132 */
-       {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)},    /* Foxconn T77W968 LTE */
diff --git a/target/linux/generic/backport-6.18/630-v6.14-PM-sleep-wakeirq-Introduce-device-managed-variant-of.patch b/target/linux/generic/backport-6.18/630-v6.14-PM-sleep-wakeirq-Introduce-device-managed-variant-of.patch
deleted file mode 100644 (file)
index 06edffa..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-From fd8318a32573d73eb20637a0c80689de0dc98169 Mon Sep 17 00:00:00 2001
-From: Peng Fan <peng.fan@nxp.com>
-Date: Fri, 3 Jan 2025 16:41:13 +0800
-Subject: [PATCH] PM: sleep: wakeirq: Introduce device-managed variant of
- dev_pm_set_wake_irq()
-
-Add device-managed variant of dev_pm_set_wake_irq which automatically
-clear the wake irq on device destruction to simplify error handling
-and resource management in drivers.
-
-Signed-off-by: Peng Fan <peng.fan@nxp.com>
-Link: https://patch.msgid.link/20250103-wake_irq-v2-1-e3aeff5e9966@nxp.com
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/base/power/wakeirq.c | 26 ++++++++++++++++++++++++++
- include/linux/pm_wakeirq.h   |  6 ++++++
- 2 files changed, 32 insertions(+)
-
---- a/drivers/base/power/wakeirq.c
-+++ b/drivers/base/power/wakeirq.c
-@@ -106,6 +106,32 @@ void dev_pm_clear_wake_irq(struct device
- }
- EXPORT_SYMBOL_GPL(dev_pm_clear_wake_irq);
-+static void devm_pm_clear_wake_irq(void *dev)
-+{
-+      dev_pm_clear_wake_irq(dev);
-+}
-+
-+/**
-+ * devm_pm_set_wake_irq - device-managed variant of dev_pm_set_wake_irq
-+ * @dev: Device entry
-+ * @irq: Device IO interrupt
-+ *
-+ *
-+ * Attach a device IO interrupt as a wake IRQ, same with dev_pm_set_wake_irq,
-+ * but the device will be auto clear wake capability on driver detach.
-+ */
-+int devm_pm_set_wake_irq(struct device *dev, int irq)
-+{
-+      int ret;
-+
-+      ret = dev_pm_set_wake_irq(dev, irq);
-+      if (ret)
-+              return ret;
-+
-+      return devm_add_action_or_reset(dev, devm_pm_clear_wake_irq, dev);
-+}
-+EXPORT_SYMBOL_GPL(devm_pm_set_wake_irq);
-+
- /**
-  * handle_threaded_wake_irq - Handler for dedicated wake-up interrupts
-  * @irq: Device specific dedicated wake-up interrupt
---- a/include/linux/pm_wakeirq.h
-+++ b/include/linux/pm_wakeirq.h
-@@ -10,6 +10,7 @@ extern int dev_pm_set_wake_irq(struct de
- extern int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq);
- extern int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq);
- extern void dev_pm_clear_wake_irq(struct device *dev);
-+extern int devm_pm_set_wake_irq(struct device *dev, int irq);
- #else /* !CONFIG_PM */
-@@ -32,5 +33,10 @@ static inline void dev_pm_clear_wake_irq
- {
- }
-+static inline int devm_pm_set_wake_irq(struct device *dev, int irq)
-+{
-+      return 0;
-+}
-+
- #endif        /* CONFIG_PM */
- #endif        /* _LINUX_PM_WAKEIRQ_H */
diff --git a/target/linux/generic/backport-6.18/710-v6.16-igc-enable-HW-vlan-tag-insertion-stripping-by-defaul.patch b/target/linux/generic/backport-6.18/710-v6.16-igc-enable-HW-vlan-tag-insertion-stripping-by-defaul.patch
deleted file mode 100644 (file)
index 48d03f1..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From 8cae5a0d91fea01d90ce7c1827e26934a22ca2fa Mon Sep 17 00:00:00 2001
-From: Rui Salvaterra <rsalvaterra@gmail.com>
-Date: Wed, 5 Mar 2025 11:53:56 +0000
-Subject: [PATCH] igc: enable HW vlan tag insertion/stripping by default
-
-This is enabled by default in other Intel drivers I've checked (e1000, e1000e,
-iavf, igb and ice). Fixes an out-of-the-box performance issue when running
-OpenWrt on typical mini-PCs with igc-supported Ethernet controllers and 802.1Q
-VLAN configurations, as ethtool isn't part of the default packages and sane
-defaults are expected.
-
-In my specific case, with an Intel N100-based machine with four I226-V Ethernet
-controllers, my upload performance increased from under 30 Mb/s to the expected
-~1 Gb/s.
-
-Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
----
- drivers/net/ethernet/intel/igc/igc_main.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/ethernet/intel/igc/igc_main.c
-+++ b/drivers/net/ethernet/intel/igc/igc_main.c
-@@ -7070,6 +7070,9 @@ static int igc_probe(struct pci_dev *pde
-       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
-                              NETDEV_XDP_ACT_XSK_ZEROCOPY;
-+      /* enable HW vlan tag insertion/stripping by default */
-+      netdev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
-+
-       /* MTU range: 68 - 9216 */
-       netdev->min_mtu = ETH_MIN_MTU;
-       netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE;
diff --git a/target/linux/generic/backport-6.18/720-01-v6.13-net-phy-mediatek-ge-soc-Fix-coding-style.patch b/target/linux/generic/backport-6.18/720-01-v6.13-net-phy-mediatek-ge-soc-Fix-coding-style.patch
deleted file mode 100644 (file)
index 25bd96f..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-From 277f96c1f3f71d6e1d3bcf650d7cd84c1442210f Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 17 Oct 2024 11:22:11 +0800
-Subject: [PATCH 01/20] net: phy: mediatek-ge-soc: Fix coding style
-
-This patch fixes spelling errors, re-arrange vars with
-reverse Xmas tree and remove unnecessary parens in
-mediatek-ge-soc.c.
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
----
- drivers/net/phy/mediatek-ge-soc.c | 36 ++++++++++++++++---------------
- 1 file changed, 19 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/mediatek-ge-soc.c
-+++ b/drivers/net/phy/mediatek-ge-soc.c
-@@ -408,16 +408,17 @@ static int tx_offset_cal_efuse(struct ph
- static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
- {
--      int i;
--      int bias[16] = {};
--      const int vals_9461[16] = { 7, 1, 4, 7,
--                                  7, 1, 4, 7,
--                                  7, 1, 4, 7,
--                                  7, 1, 4, 7 };
-       const int vals_9481[16] = { 10, 6, 6, 10,
-                                   10, 6, 6, 10,
-                                   10, 6, 6, 10,
-                                   10, 6, 6, 10 };
-+      const int vals_9461[16] = { 7, 1, 4, 7,
-+                                  7, 1, 4, 7,
-+                                  7, 1, 4, 7,
-+                                  7, 1, 4, 7 };
-+      int bias[16] = {};
-+      int i;
-+
-       switch (phydev->drv->phy_id) {
-       case MTK_GPHY_ID_MT7981:
-               /* We add some calibration to efuse values
-@@ -1069,10 +1070,10 @@ static int start_cal(struct phy_device *
- static int mt798x_phy_calibration(struct phy_device *phydev)
- {
-+      struct nvmem_cell *cell;
-       int ret = 0;
--      u32 *buf;
-       size_t len;
--      struct nvmem_cell *cell;
-+      u32 *buf;
-       cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
-       if (IS_ERR(cell)) {
-@@ -1210,14 +1211,15 @@ static int mt798x_phy_led_brightness_set
-       return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
- }
--static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
--                                               BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
--                                               BIT(TRIGGER_NETDEV_LINK)        |
--                                               BIT(TRIGGER_NETDEV_LINK_10)     |
--                                               BIT(TRIGGER_NETDEV_LINK_100)    |
--                                               BIT(TRIGGER_NETDEV_LINK_1000)   |
--                                               BIT(TRIGGER_NETDEV_RX)          |
--                                               BIT(TRIGGER_NETDEV_TX));
-+static const unsigned long supported_triggers =
-+      BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
-+      BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
-+      BIT(TRIGGER_NETDEV_LINK)        |
-+      BIT(TRIGGER_NETDEV_LINK_10)     |
-+      BIT(TRIGGER_NETDEV_LINK_100)    |
-+      BIT(TRIGGER_NETDEV_LINK_1000)   |
-+      BIT(TRIGGER_NETDEV_RX)          |
-+      BIT(TRIGGER_NETDEV_TX);
- static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-                                         unsigned long rules)
-@@ -1415,7 +1417,7 @@ static int mt7988_phy_probe_shared(struc
-        * LED_C and LED_D respectively. At the same time those pins are used to
-        * bootstrap configuration of the reference clock source (LED_A),
-        * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
--       * In practise this is done using a LED and a resistor pulling the pin
-+       * In practice this is done using a LED and a resistor pulling the pin
-        * either to GND or to VIO.
-        * The detected value at boot time is accessible at run-time using the
-        * TPBANK0 register located in the gpio base of the pinctrl, in order
diff --git a/target/linux/generic/backport-6.18/720-02-v6.13-net-phy-mediatek-ge-soc-Shrink-line-wrapping-to-80-c.patch b/target/linux/generic/backport-6.18/720-02-v6.13-net-phy-mediatek-ge-soc-Shrink-line-wrapping-to-80-c.patch
deleted file mode 100644 (file)
index fbf3a99..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-From c0dc1b412f9d840c51c5ee8927bf066e15a59550 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 17 Oct 2024 11:22:12 +0800
-Subject: [PATCH 02/20] net: phy: mediatek-ge-soc: Shrink line wrapping to 80
- characters
-
-This patch shrinks line wrapping to 80 chars. Also, in
-tx_amp_fill_result(), use FIELD_PREP() to prettify code.
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
----
- drivers/net/phy/mediatek-ge-soc.c | 125 +++++++++++++++++++++---------
- 1 file changed, 88 insertions(+), 37 deletions(-)
-
---- a/drivers/net/phy/mediatek-ge-soc.c
-+++ b/drivers/net/phy/mediatek-ge-soc.c
-@@ -342,7 +342,8 @@ static int cal_cycle(struct phy_device *
-       ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-                                       MTK_PHY_RG_AD_CAL_CLK, reg_val,
-                                       reg_val & MTK_PHY_DA_CAL_CLK, 500,
--                                      ANALOG_INTERNAL_OPERATION_MAX_US, false);
-+                                      ANALOG_INTERNAL_OPERATION_MAX_US,
-+                                      false);
-       if (ret) {
-               phydev_err(phydev, "Calibration cycle timeout\n");
-               return ret;
-@@ -441,40 +442,72 @@ static int tx_amp_fill_result(struct phy
-       }
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
--                     MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
-+                     MTK_PHY_DA_TX_I2MPB_A_GBE_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_GBE_MASK,
-+                                buf[0] + bias[0]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
--                     MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
-+                     MTK_PHY_DA_TX_I2MPB_A_TBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_TBT_MASK,
-+                                buf[0] + bias[1]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
--                     MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
-+                     MTK_PHY_DA_TX_I2MPB_A_HBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_HBT_MASK,
-+                                buf[0] + bias[2]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
--                     MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
-+                     MTK_PHY_DA_TX_I2MPB_A_TST_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_TST_MASK,
-+                                buf[0] + bias[3]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
--                     MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
-+                     MTK_PHY_DA_TX_I2MPB_B_GBE_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_GBE_MASK,
-+                                buf[1] + bias[4]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
--                     MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
-+                     MTK_PHY_DA_TX_I2MPB_B_TBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_TBT_MASK,
-+                                buf[1] + bias[5]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
--                     MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
-+                     MTK_PHY_DA_TX_I2MPB_B_HBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_HBT_MASK,
-+                                buf[1] + bias[6]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
--                     MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
-+                     MTK_PHY_DA_TX_I2MPB_B_TST_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_TST_MASK,
-+                                buf[1] + bias[7]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
--                     MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
-+                     MTK_PHY_DA_TX_I2MPB_C_GBE_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_GBE_MASK,
-+                                buf[2] + bias[8]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
--                     MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
-+                     MTK_PHY_DA_TX_I2MPB_C_TBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_TBT_MASK,
-+                                buf[2] + bias[9]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
--                     MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
-+                     MTK_PHY_DA_TX_I2MPB_C_HBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_HBT_MASK,
-+                                buf[2] + bias[10]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
--                     MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
-+                     MTK_PHY_DA_TX_I2MPB_C_TST_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_TST_MASK,
-+                                buf[2] + bias[11]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
--                     MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
-+                     MTK_PHY_DA_TX_I2MPB_D_GBE_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_GBE_MASK,
-+                                buf[3] + bias[12]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
--                     MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
-+                     MTK_PHY_DA_TX_I2MPB_D_TBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_TBT_MASK,
-+                                buf[3] + bias[13]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
--                     MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
-+                     MTK_PHY_DA_TX_I2MPB_D_HBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_HBT_MASK,
-+                                buf[3] + bias[14]));
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
--                     MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
-+                     MTK_PHY_DA_TX_I2MPB_D_TST_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_TST_MASK,
-+                                buf[3] + bias[15]));
-       return 0;
- }
-@@ -663,7 +696,8 @@ static int tx_vcm_cal_sw(struct phy_devi
-               goto restore;
-       /* We calibrate TX-VCM in different logic. Check upper index and then
--       * lower index. If this calibration is valid, apply lower index's result.
-+       * lower index. If this calibration is valid, apply lower index's
-+       * result.
-        */
-       ret = upper_ret - lower_ret;
-       if (ret == 1) {
-@@ -692,7 +726,8 @@ static int tx_vcm_cal_sw(struct phy_devi
-       } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
-                  lower_ret == 0) {
-               ret = 0;
--              phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",
-+              phydev_warn(phydev,
-+                          "TX-VCM SW cal result at high margin 0x%x\n",
-                           upper_idx);
-       } else {
-               ret = -EINVAL;
-@@ -796,7 +831,8 @@ static void mt7981_phy_finetune(struct p
-       /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
--                     MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
-+                     MTK_PHY_TR_OPEN_LOOP_EN_MASK |
-+                     MTK_PHY_LPF_X_AVERAGE_MASK,
-                      BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
-       /* rg_tr_lpf_cnt_val = 512 */
-@@ -865,7 +901,8 @@ static void mt7988_phy_finetune(struct p
-       /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
--                     MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
-+                     MTK_PHY_TR_OPEN_LOOP_EN_MASK |
-+                     MTK_PHY_LPF_X_AVERAGE_MASK,
-                      BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
-       /* rg_tr_lpf_cnt_val = 1023 */
-@@ -977,7 +1014,8 @@ static void mt798x_phy_eee(struct phy_de
-       phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
--      __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
-+      __phy_modify(phydev, MTK_PHY_LPI_REG_14,
-+                   MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
-                    FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
-       __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
-@@ -987,7 +1025,8 @@ static void mt798x_phy_eee(struct phy_de
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-                      MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
-                      MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
--                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
-+                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
-+                                0xff));
- }
- static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
-@@ -1147,7 +1186,8 @@ static int mt798x_phy_hw_led_on_set(stru
-                                       (index ? 16 : 0), &priv->led_state);
-       if (changed)
-               return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
--                                    MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
-+                                    MTK_PHY_LED1_ON_CTRL :
-+                                    MTK_PHY_LED0_ON_CTRL,
-                                     MTK_PHY_LED_ON_MASK,
-                                     on ? MTK_PHY_LED_ON_FORCE_ON : 0);
-       else
-@@ -1157,7 +1197,8 @@ static int mt798x_phy_hw_led_on_set(stru
- static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
-                                      bool blinking)
- {
--      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
-+      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
-+                               (index ? 16 : 0);
-       struct mtk_socphy_priv *priv = phydev->priv;
-       bool changed;
-@@ -1170,8 +1211,10 @@ static int mt798x_phy_hw_led_blink_set(s
-                             (index ? 16 : 0), &priv->led_state);
-       if (changed)
-               return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
--                                   MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
--                                   blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
-+                                   MTK_PHY_LED1_BLINK_CTRL :
-+                                   MTK_PHY_LED0_BLINK_CTRL,
-+                                   blinking ?
-+                                   MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
-       else
-               return 0;
- }
-@@ -1237,7 +1280,8 @@ static int mt798x_phy_led_hw_is_supporte
- static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
-                                        unsigned long *rules)
- {
--      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
-+      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
-+                               (index ? 16 : 0);
-       unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
-       unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
-       struct mtk_socphy_priv *priv = phydev->priv;
-@@ -1258,8 +1302,8 @@ static int mt798x_phy_led_hw_control_get
-       if (blink < 0)
-               return -EIO;
--      if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |
--                 MTK_PHY_LED_ON_LINKDOWN)) ||
-+      if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX |
-+                 MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) ||
-           (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
-               set_bit(bit_netdev, &priv->led_state);
-       else
-@@ -1333,17 +1377,23 @@ static int mt798x_phy_led_hw_control_set
-       if (rules & BIT(TRIGGER_NETDEV_RX)) {
-               blink |= (on & MTK_PHY_LED_ON_LINK) ?
--                        (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :
-+                        (((on & MTK_PHY_LED_ON_LINK10) ?
-+                          MTK_PHY_LED_BLINK_10RX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK100) ?
-+                          MTK_PHY_LED_BLINK_100RX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK1000) ?
-+                          MTK_PHY_LED_BLINK_1000RX : 0)) :
-                         MTK_PHY_LED_BLINK_RX;
-       }
-       if (rules & BIT(TRIGGER_NETDEV_TX)) {
-               blink |= (on & MTK_PHY_LED_ON_LINK) ?
--                        (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :
-+                        (((on & MTK_PHY_LED_ON_LINK10) ?
-+                          MTK_PHY_LED_BLINK_10TX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK100) ?
-+                          MTK_PHY_LED_BLINK_100TX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK1000) ?
-+                          MTK_PHY_LED_BLINK_1000TX : 0)) :
-                         MTK_PHY_LED_BLINK_TX;
-       }
-@@ -1400,7 +1450,8 @@ static int mt7988_phy_fix_leds_polaritie
-       /* Only now setup pinctrl to avoid bogus blinking */
-       pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
-       if (IS_ERR(pinctrl))
--              dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
-+              dev_err(&phydev->mdio.bus->dev,
-+                      "Failed to setup PHY LED pinctrl\n");
-       return 0;
- }
diff --git a/target/linux/generic/backport-6.18/720-03-v6.13-net-phy-mediatek-ge-soc-Propagate-error-code-correct.patch b/target/linux/generic/backport-6.18/720-03-v6.13-net-phy-mediatek-ge-soc-Propagate-error-code-correct.patch
deleted file mode 100644 (file)
index 1f6f5f5..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From bcbbfb4f62c4ba35783cc617997a2e92d91e3940 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 17 Oct 2024 11:22:13 +0800
-Subject: [PATCH 03/20] net: phy: mediatek-ge-soc: Propagate error code
- correctly in cal_cycle()
-
-This patch propagates error code correctly in cal_cycle()
-and improve with FIELD_GET().
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
----
- drivers/net/phy/mediatek-ge-soc.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/mediatek-ge-soc.c
-+++ b/drivers/net/phy/mediatek-ge-soc.c
-@@ -110,7 +110,7 @@
- #define   MTK_PHY_CR_TX_AMP_OFFSET_D_MASK     GENMASK(6, 0)
- #define MTK_PHY_RG_AD_CAL_COMP                        0x17a
--#define   MTK_PHY_AD_CAL_COMP_OUT_SHIFT               (8)
-+#define   MTK_PHY_AD_CAL_COMP_OUT_MASK                GENMASK(8, 8)
- #define MTK_PHY_RG_AD_CAL_CLK                 0x17b
- #define   MTK_PHY_DA_CAL_CLK                  BIT(0)
-@@ -351,8 +351,10 @@ static int cal_cycle(struct phy_device *
-       phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
-                          MTK_PHY_DA_CALIN_FLAG);
--      ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
--                         MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
-+      ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP);
-+      if (ret < 0)
-+              return ret;
-+      ret = FIELD_GET(MTK_PHY_AD_CAL_COMP_OUT_MASK, ret);
-       phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
-       return ret;
diff --git a/target/linux/generic/backport-6.18/720-04-v6.13-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch b/target/linux/generic/backport-6.18/720-04-v6.13-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch
deleted file mode 100644 (file)
index 81e2510..0000000
+++ /dev/null
@@ -1,3565 +0,0 @@
-From e062f073dc0df4fcd338043cb0b69b6bcd31e4af Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Sat, 9 Nov 2024 00:34:51 +0800
-Subject: [PATCH 04/20] net: phy: mediatek: Re-organize MediaTek ethernet phy
- drivers
-
-Re-organize MediaTek ethernet phy driver files and get ready to integrate
-some common functions and add new 2.5G phy driver.
-mtk-ge.c: MT7530 Gphy on MT7621 & MT7531 Gphy
-mtk-ge-soc.c: Built-in Gphy on MT7981 & Built-in switch Gphy on MT7988
-mtk-2p5ge.c: Planned for built-in 2.5G phy on MT7988
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- MAINTAINERS                                   |  4 ++--
- drivers/net/phy/Kconfig                       | 17 +-------------
- drivers/net/phy/Makefile                      |  3 +--
- drivers/net/phy/mediatek/Kconfig              | 22 +++++++++++++++++++
- drivers/net/phy/mediatek/Makefile             |  3 +++
- .../mtk-ge-soc.c}                             |  0
- .../phy/{mediatek-ge.c => mediatek/mtk-ge.c}  |  0
- 7 files changed, 29 insertions(+), 20 deletions(-)
- create mode 100644 drivers/net/phy/mediatek/Kconfig
- create mode 100644 drivers/net/phy/mediatek/Makefile
- rename drivers/net/phy/{mediatek-ge-soc.c => mediatek/mtk-ge-soc.c} (100%)
- rename drivers/net/phy/{mediatek-ge.c => mediatek/mtk-ge.c} (100%)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -14427,8 +14427,8 @@ M:     Qingfang Deng <dqfext@gmail.com>
- M:    SkyLake Huang <SkyLake.Huang@mediatek.com>
- L:    netdev@vger.kernel.org
- S:    Maintained
--F:    drivers/net/phy/mediatek-ge-soc.c
--F:    drivers/net/phy/mediatek-ge.c
-+F:    drivers/net/phy/mediatek/mtk-ge-soc.c
-+F:    drivers/net/phy/mediatek/mtk-ge.c
- F:    drivers/phy/mediatek/phy-mtk-xfi-tphy.c
- MEDIATEK I2C CONTROLLER DRIVER
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -266,22 +266,7 @@ config MAXLINEAR_GPHY
-         Support for the Maxlinear GPY115, GPY211, GPY212, GPY215,
-         GPY241, GPY245 PHYs.
--config MEDIATEK_GE_PHY
--      tristate "MediaTek Gigabit Ethernet PHYs"
--      help
--        Supports the MediaTek Gigabit Ethernet PHYs.
--
--config MEDIATEK_GE_SOC_PHY
--      tristate "MediaTek SoC Ethernet PHYs"
--      depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
--      depends on NVMEM_MTK_EFUSE
--      help
--        Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
--
--        Include support for built-in Ethernet PHYs which are present in
--        the MT7981 and MT7988 SoCs. These PHYs need calibration data
--        present in the SoCs efuse and will dynamically calibrate VCM
--        (common-mode voltage) during startup.
-+source "drivers/net/phy/mediatek/Kconfig"
- config MICREL_PHY
-       tristate "Micrel PHYs"
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -74,8 +74,7 @@ obj-$(CONFIG_MARVELL_PHY)    += marvell.o
- obj-$(CONFIG_MARVELL_88Q2XXX_PHY)     += marvell-88q2xxx.o
- obj-$(CONFIG_MARVELL_88X2222_PHY)     += marvell-88x2222.o
- obj-$(CONFIG_MAXLINEAR_GPHY)  += mxl-gpy.o
--obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
--obj-$(CONFIG_MEDIATEK_GE_SOC_PHY)     += mediatek-ge-soc.o
-+obj-y                         += mediatek/
- obj-$(CONFIG_MESON_GXL_PHY)   += meson-gxl.o
- obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
- obj-$(CONFIG_MICREL_PHY)      += micrel.o
---- /dev/null
-+++ b/drivers/net/phy/mediatek/Kconfig
-@@ -0,0 +1,22 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+config MEDIATEK_GE_PHY
-+      tristate "MediaTek Gigabit Ethernet PHYs"
-+      help
-+        Supports the MediaTek non-built-in Gigabit Ethernet PHYs.
-+
-+        Non-built-in Gigabit Ethernet PHYs include mt7530/mt7531.
-+        You may find mt7530 inside mt7621. This driver shares some
-+        common operations with MediaTek SoC built-in Gigabit
-+        Ethernet PHYs.
-+
-+config MEDIATEK_GE_SOC_PHY
-+      tristate "MediaTek SoC Ethernet PHYs"
-+      depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
-+      depends on NVMEM_MTK_EFUSE
-+      help
-+        Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
-+
-+        Include support for built-in Ethernet PHYs which are present in
-+        the MT7981 and MT7988 SoCs. These PHYs need calibration data
-+        present in the SoCs efuse and will dynamically calibrate VCM
-+        (common-mode voltage) during startup.
---- /dev/null
-+++ b/drivers/net/phy/mediatek/Makefile
-@@ -0,0 +1,3 @@
-+# SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_MEDIATEK_GE_PHY)         += mtk-ge.o
-+obj-$(CONFIG_MEDIATEK_GE_SOC_PHY)     += mtk-ge-soc.o
---- a/drivers/net/phy/mediatek-ge-soc.c
-+++ /dev/null
-@@ -1,1610 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0+
--#include <linux/bitfield.h>
--#include <linux/bitmap.h>
--#include <linux/mfd/syscon.h>
--#include <linux/module.h>
--#include <linux/nvmem-consumer.h>
--#include <linux/pinctrl/consumer.h>
--#include <linux/phy.h>
--#include <linux/regmap.h>
--
--#define MTK_GPHY_ID_MT7981                    0x03a29461
--#define MTK_GPHY_ID_MT7988                    0x03a29481
--
--#define MTK_EXT_PAGE_ACCESS                   0x1f
--#define MTK_PHY_PAGE_STANDARD                 0x0000
--#define MTK_PHY_PAGE_EXTENDED_3                       0x0003
--
--#define MTK_PHY_LPI_REG_14                    0x14
--#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK      GENMASK(8, 0)
--
--#define MTK_PHY_LPI_REG_1c                    0x1c
--#define MTK_PHY_SMI_DET_ON_THRESH_MASK                GENMASK(13, 8)
--
--#define MTK_PHY_PAGE_EXTENDED_2A30            0x2a30
--#define MTK_PHY_PAGE_EXTENDED_52B5            0x52b5
--
--#define ANALOG_INTERNAL_OPERATION_MAX_US      20
--#define TXRESERVE_MIN                         0
--#define TXRESERVE_MAX                         7
--
--#define MTK_PHY_ANARG_RG                      0x10
--#define   MTK_PHY_TCLKOFFSET_MASK             GENMASK(12, 8)
--
--/* Registers on MDIO_MMD_VEND1 */
--#define MTK_PHY_TXVLD_DA_RG                   0x12
--#define   MTK_PHY_DA_TX_I2MPB_A_GBE_MASK      GENMASK(15, 10)
--#define   MTK_PHY_DA_TX_I2MPB_A_TBT_MASK      GENMASK(5, 0)
--
--#define MTK_PHY_TX_I2MPB_TEST_MODE_A2         0x16
--#define   MTK_PHY_DA_TX_I2MPB_A_HBT_MASK      GENMASK(15, 10)
--#define   MTK_PHY_DA_TX_I2MPB_A_TST_MASK      GENMASK(5, 0)
--
--#define MTK_PHY_TX_I2MPB_TEST_MODE_B1         0x17
--#define   MTK_PHY_DA_TX_I2MPB_B_GBE_MASK      GENMASK(13, 8)
--#define   MTK_PHY_DA_TX_I2MPB_B_TBT_MASK      GENMASK(5, 0)
--
--#define MTK_PHY_TX_I2MPB_TEST_MODE_B2         0x18
--#define   MTK_PHY_DA_TX_I2MPB_B_HBT_MASK      GENMASK(13, 8)
--#define   MTK_PHY_DA_TX_I2MPB_B_TST_MASK      GENMASK(5, 0)
--
--#define MTK_PHY_TX_I2MPB_TEST_MODE_C1         0x19
--#define   MTK_PHY_DA_TX_I2MPB_C_GBE_MASK      GENMASK(13, 8)
--#define   MTK_PHY_DA_TX_I2MPB_C_TBT_MASK      GENMASK(5, 0)
--
--#define MTK_PHY_TX_I2MPB_TEST_MODE_C2         0x20
--#define   MTK_PHY_DA_TX_I2MPB_C_HBT_MASK      GENMASK(13, 8)
--#define   MTK_PHY_DA_TX_I2MPB_C_TST_MASK      GENMASK(5, 0)
--
--#define MTK_PHY_TX_I2MPB_TEST_MODE_D1         0x21
--#define   MTK_PHY_DA_TX_I2MPB_D_GBE_MASK      GENMASK(13, 8)
--#define   MTK_PHY_DA_TX_I2MPB_D_TBT_MASK      GENMASK(5, 0)
--
--#define MTK_PHY_TX_I2MPB_TEST_MODE_D2         0x22
--#define   MTK_PHY_DA_TX_I2MPB_D_HBT_MASK      GENMASK(13, 8)
--#define   MTK_PHY_DA_TX_I2MPB_D_TST_MASK      GENMASK(5, 0)
--
--#define MTK_PHY_RXADC_CTRL_RG7                        0xc6
--#define   MTK_PHY_DA_AD_BUF_BIAS_LP_MASK      GENMASK(9, 8)
--
--#define MTK_PHY_RXADC_CTRL_RG9                        0xc8
--#define   MTK_PHY_DA_RX_PSBN_TBT_MASK         GENMASK(14, 12)
--#define   MTK_PHY_DA_RX_PSBN_HBT_MASK         GENMASK(10, 8)
--#define   MTK_PHY_DA_RX_PSBN_GBE_MASK         GENMASK(6, 4)
--#define   MTK_PHY_DA_RX_PSBN_LP_MASK          GENMASK(2, 0)
--
--#define MTK_PHY_LDO_OUTPUT_V                  0xd7
--
--#define MTK_PHY_RG_ANA_CAL_RG0                        0xdb
--#define   MTK_PHY_RG_CAL_CKINV                        BIT(12)
--#define   MTK_PHY_RG_ANA_CALEN                        BIT(8)
--#define   MTK_PHY_RG_ZCALEN_A                 BIT(0)
--
--#define MTK_PHY_RG_ANA_CAL_RG1                        0xdc
--#define   MTK_PHY_RG_ZCALEN_B                 BIT(12)
--#define   MTK_PHY_RG_ZCALEN_C                 BIT(8)
--#define   MTK_PHY_RG_ZCALEN_D                 BIT(4)
--#define   MTK_PHY_RG_TXVOS_CALEN              BIT(0)
--
--#define MTK_PHY_RG_ANA_CAL_RG5                        0xe0
--#define   MTK_PHY_RG_REXT_TRIM_MASK           GENMASK(13, 8)
--
--#define MTK_PHY_RG_TX_FILTER                  0xfe
--
--#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120    0x120
--#define   MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK       GENMASK(12, 8)
--#define   MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK       GENMASK(4, 0)
--
--#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122    0x122
--#define   MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK     GENMASK(7, 0)
--
--#define MTK_PHY_RG_TESTMUX_ADC_CTRL           0x144
--#define   MTK_PHY_RG_TXEN_DIG_MASK            GENMASK(5, 5)
--
--#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B               0x172
--#define   MTK_PHY_CR_TX_AMP_OFFSET_A_MASK     GENMASK(13, 8)
--#define   MTK_PHY_CR_TX_AMP_OFFSET_B_MASK     GENMASK(6, 0)
--
--#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D               0x173
--#define   MTK_PHY_CR_TX_AMP_OFFSET_C_MASK     GENMASK(13, 8)
--#define   MTK_PHY_CR_TX_AMP_OFFSET_D_MASK     GENMASK(6, 0)
--
--#define MTK_PHY_RG_AD_CAL_COMP                        0x17a
--#define   MTK_PHY_AD_CAL_COMP_OUT_MASK                GENMASK(8, 8)
--
--#define MTK_PHY_RG_AD_CAL_CLK                 0x17b
--#define   MTK_PHY_DA_CAL_CLK                  BIT(0)
--
--#define MTK_PHY_RG_AD_CALIN                   0x17c
--#define   MTK_PHY_DA_CALIN_FLAG                       BIT(0)
--
--#define MTK_PHY_RG_DASN_DAC_IN0_A             0x17d
--#define   MTK_PHY_DASN_DAC_IN0_A_MASK         GENMASK(9, 0)
--
--#define MTK_PHY_RG_DASN_DAC_IN0_B             0x17e
--#define   MTK_PHY_DASN_DAC_IN0_B_MASK         GENMASK(9, 0)
--
--#define MTK_PHY_RG_DASN_DAC_IN0_C             0x17f
--#define   MTK_PHY_DASN_DAC_IN0_C_MASK         GENMASK(9, 0)
--
--#define MTK_PHY_RG_DASN_DAC_IN0_D             0x180
--#define   MTK_PHY_DASN_DAC_IN0_D_MASK         GENMASK(9, 0)
--
--#define MTK_PHY_RG_DASN_DAC_IN1_A             0x181
--#define   MTK_PHY_DASN_DAC_IN1_A_MASK         GENMASK(9, 0)
--
--#define MTK_PHY_RG_DASN_DAC_IN1_B             0x182
--#define   MTK_PHY_DASN_DAC_IN1_B_MASK         GENMASK(9, 0)
--
--#define MTK_PHY_RG_DASN_DAC_IN1_C             0x183
--#define   MTK_PHY_DASN_DAC_IN1_C_MASK         GENMASK(9, 0)
--
--#define MTK_PHY_RG_DASN_DAC_IN1_D             0x184
--#define   MTK_PHY_DASN_DAC_IN1_D_MASK         GENMASK(9, 0)
--
--#define MTK_PHY_RG_DEV1E_REG19b                       0x19b
--#define   MTK_PHY_BYPASS_DSP_LPI_READY                BIT(8)
--
--#define MTK_PHY_RG_LP_IIR2_K1_L                       0x22a
--#define MTK_PHY_RG_LP_IIR2_K1_U                       0x22b
--#define MTK_PHY_RG_LP_IIR2_K2_L                       0x22c
--#define MTK_PHY_RG_LP_IIR2_K2_U                       0x22d
--#define MTK_PHY_RG_LP_IIR2_K3_L                       0x22e
--#define MTK_PHY_RG_LP_IIR2_K3_U                       0x22f
--#define MTK_PHY_RG_LP_IIR2_K4_L                       0x230
--#define MTK_PHY_RG_LP_IIR2_K4_U                       0x231
--#define MTK_PHY_RG_LP_IIR2_K5_L                       0x232
--#define MTK_PHY_RG_LP_IIR2_K5_U                       0x233
--
--#define MTK_PHY_RG_DEV1E_REG234                       0x234
--#define   MTK_PHY_TR_OPEN_LOOP_EN_MASK                GENMASK(0, 0)
--#define   MTK_PHY_LPF_X_AVERAGE_MASK          GENMASK(7, 4)
--#define   MTK_PHY_TR_LP_IIR_EEE_EN            BIT(12)
--
--#define MTK_PHY_RG_LPF_CNT_VAL                        0x235
--
--#define MTK_PHY_RG_DEV1E_REG238                       0x238
--#define   MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK  GENMASK(8, 0)
--#define   MTK_PHY_LPI_SLV_SEND_TX_EN          BIT(12)
--
--#define MTK_PHY_RG_DEV1E_REG239                       0x239
--#define   MTK_PHY_LPI_SEND_LOC_TIMER_MASK     GENMASK(8, 0)
--#define   MTK_PHY_LPI_TXPCS_LOC_RCV           BIT(12)
--
--#define MTK_PHY_RG_DEV1E_REG27C                       0x27c
--#define   MTK_PHY_VGASTATE_FFE_THR_ST1_MASK   GENMASK(12, 8)
--#define MTK_PHY_RG_DEV1E_REG27D                       0x27d
--#define   MTK_PHY_VGASTATE_FFE_THR_ST2_MASK   GENMASK(4, 0)
--
--#define MTK_PHY_RG_DEV1E_REG2C7                       0x2c7
--#define   MTK_PHY_MAX_GAIN_MASK                       GENMASK(4, 0)
--#define   MTK_PHY_MIN_GAIN_MASK                       GENMASK(12, 8)
--
--#define MTK_PHY_RG_DEV1E_REG2D1                       0x2d1
--#define   MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK        GENMASK(7, 0)
--#define   MTK_PHY_LPI_SKIP_SD_SLV_TR          BIT(8)
--#define   MTK_PHY_LPI_TR_READY                        BIT(9)
--#define   MTK_PHY_LPI_VCO_EEE_STG0_EN         BIT(10)
--
--#define MTK_PHY_RG_DEV1E_REG323                       0x323
--#define   MTK_PHY_EEE_WAKE_MAS_INT_DC         BIT(0)
--#define   MTK_PHY_EEE_WAKE_SLV_INT_DC         BIT(4)
--
--#define MTK_PHY_RG_DEV1E_REG324                       0x324
--#define   MTK_PHY_SMI_DETCNT_MAX_MASK         GENMASK(5, 0)
--#define   MTK_PHY_SMI_DET_MAX_EN              BIT(8)
--
--#define MTK_PHY_RG_DEV1E_REG326                       0x326
--#define   MTK_PHY_LPI_MODE_SD_ON              BIT(0)
--#define   MTK_PHY_RESET_RANDUPD_CNT           BIT(1)
--#define   MTK_PHY_TREC_UPDATE_ENAB_CLR                BIT(2)
--#define   MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF       BIT(4)
--#define   MTK_PHY_TR_READY_SKIP_AFE_WAKEUP    BIT(5)
--
--#define MTK_PHY_LDO_PUMP_EN_PAIRAB            0x502
--#define MTK_PHY_LDO_PUMP_EN_PAIRCD            0x503
--
--#define MTK_PHY_DA_TX_R50_PAIR_A              0x53d
--#define MTK_PHY_DA_TX_R50_PAIR_B              0x53e
--#define MTK_PHY_DA_TX_R50_PAIR_C              0x53f
--#define MTK_PHY_DA_TX_R50_PAIR_D              0x540
--
--/* Registers on MDIO_MMD_VEND2 */
--#define MTK_PHY_LED0_ON_CTRL                  0x24
--#define MTK_PHY_LED1_ON_CTRL                  0x26
--#define   MTK_PHY_LED_ON_MASK                 GENMASK(6, 0)
--#define   MTK_PHY_LED_ON_LINK1000             BIT(0)
--#define   MTK_PHY_LED_ON_LINK100              BIT(1)
--#define   MTK_PHY_LED_ON_LINK10                       BIT(2)
--#define   MTK_PHY_LED_ON_LINK                 (MTK_PHY_LED_ON_LINK10 |\
--                                               MTK_PHY_LED_ON_LINK100 |\
--                                               MTK_PHY_LED_ON_LINK1000)
--#define   MTK_PHY_LED_ON_LINKDOWN             BIT(3)
--#define   MTK_PHY_LED_ON_FDX                  BIT(4) /* Full duplex */
--#define   MTK_PHY_LED_ON_HDX                  BIT(5) /* Half duplex */
--#define   MTK_PHY_LED_ON_FORCE_ON             BIT(6)
--#define   MTK_PHY_LED_ON_POLARITY             BIT(14)
--#define   MTK_PHY_LED_ON_ENABLE                       BIT(15)
--
--#define MTK_PHY_LED0_BLINK_CTRL                       0x25
--#define MTK_PHY_LED1_BLINK_CTRL                       0x27
--#define   MTK_PHY_LED_BLINK_1000TX            BIT(0)
--#define   MTK_PHY_LED_BLINK_1000RX            BIT(1)
--#define   MTK_PHY_LED_BLINK_100TX             BIT(2)
--#define   MTK_PHY_LED_BLINK_100RX             BIT(3)
--#define   MTK_PHY_LED_BLINK_10TX              BIT(4)
--#define   MTK_PHY_LED_BLINK_10RX              BIT(5)
--#define   MTK_PHY_LED_BLINK_RX                        (MTK_PHY_LED_BLINK_10RX |\
--                                               MTK_PHY_LED_BLINK_100RX |\
--                                               MTK_PHY_LED_BLINK_1000RX)
--#define   MTK_PHY_LED_BLINK_TX                        (MTK_PHY_LED_BLINK_10TX |\
--                                               MTK_PHY_LED_BLINK_100TX |\
--                                               MTK_PHY_LED_BLINK_1000TX)
--#define   MTK_PHY_LED_BLINK_COLLISION         BIT(6)
--#define   MTK_PHY_LED_BLINK_RX_CRC_ERR                BIT(7)
--#define   MTK_PHY_LED_BLINK_RX_IDLE_ERR               BIT(8)
--#define   MTK_PHY_LED_BLINK_FORCE_BLINK               BIT(9)
--
--#define MTK_PHY_LED1_DEFAULT_POLARITIES               BIT(1)
--
--#define MTK_PHY_RG_BG_RASEL                   0x115
--#define   MTK_PHY_RG_BG_RASEL_MASK            GENMASK(2, 0)
--
--/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
--#define RG_GPIO_MISC_TPBANK0                  0x6f0
--#define   RG_GPIO_MISC_TPBANK0_BOOTMODE               GENMASK(11, 8)
--
--/* These macro privides efuse parsing for internal phy. */
--#define EFS_DA_TX_I2MPB_A(x)                  (((x) >> 0) & GENMASK(5, 0))
--#define EFS_DA_TX_I2MPB_B(x)                  (((x) >> 6) & GENMASK(5, 0))
--#define EFS_DA_TX_I2MPB_C(x)                  (((x) >> 12) & GENMASK(5, 0))
--#define EFS_DA_TX_I2MPB_D(x)                  (((x) >> 18) & GENMASK(5, 0))
--#define EFS_DA_TX_AMP_OFFSET_A(x)             (((x) >> 24) & GENMASK(5, 0))
--
--#define EFS_DA_TX_AMP_OFFSET_B(x)             (((x) >> 0) & GENMASK(5, 0))
--#define EFS_DA_TX_AMP_OFFSET_C(x)             (((x) >> 6) & GENMASK(5, 0))
--#define EFS_DA_TX_AMP_OFFSET_D(x)             (((x) >> 12) & GENMASK(5, 0))
--#define EFS_DA_TX_R50_A(x)                    (((x) >> 18) & GENMASK(5, 0))
--#define EFS_DA_TX_R50_B(x)                    (((x) >> 24) & GENMASK(5, 0))
--
--#define EFS_DA_TX_R50_C(x)                    (((x) >> 0) & GENMASK(5, 0))
--#define EFS_DA_TX_R50_D(x)                    (((x) >> 6) & GENMASK(5, 0))
--
--#define EFS_RG_BG_RASEL(x)                    (((x) >> 4) & GENMASK(2, 0))
--#define EFS_RG_REXT_TRIM(x)                   (((x) >> 7) & GENMASK(5, 0))
--
--enum {
--      NO_PAIR,
--      PAIR_A,
--      PAIR_B,
--      PAIR_C,
--      PAIR_D,
--};
--
--enum calibration_mode {
--      EFUSE_K,
--      SW_K
--};
--
--enum CAL_ITEM {
--      REXT,
--      TX_OFFSET,
--      TX_AMP,
--      TX_R50,
--      TX_VCM
--};
--
--enum CAL_MODE {
--      EFUSE_M,
--      SW_M
--};
--
--#define MTK_PHY_LED_STATE_FORCE_ON    0
--#define MTK_PHY_LED_STATE_FORCE_BLINK 1
--#define MTK_PHY_LED_STATE_NETDEV      2
--
--struct mtk_socphy_priv {
--      unsigned long           led_state;
--};
--
--struct mtk_socphy_shared {
--      u32                     boottrap;
--      struct mtk_socphy_priv  priv[4];
--};
--
--static int mtk_socphy_read_page(struct phy_device *phydev)
--{
--      return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
--}
--
--static int mtk_socphy_write_page(struct phy_device *phydev, int page)
--{
--      return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
--}
--
--/* One calibration cycle consists of:
-- * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
-- *   until AD_CAL_COMP is ready to output calibration result.
-- * 2.Wait until DA_CAL_CLK is available.
-- * 3.Fetch AD_CAL_COMP_OUT.
-- */
--static int cal_cycle(struct phy_device *phydev, int devad,
--                   u32 regnum, u16 mask, u16 cal_val)
--{
--      int reg_val;
--      int ret;
--
--      phy_modify_mmd(phydev, devad, regnum,
--                     mask, cal_val);
--      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
--                       MTK_PHY_DA_CALIN_FLAG);
--
--      ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
--                                      MTK_PHY_RG_AD_CAL_CLK, reg_val,
--                                      reg_val & MTK_PHY_DA_CAL_CLK, 500,
--                                      ANALOG_INTERNAL_OPERATION_MAX_US,
--                                      false);
--      if (ret) {
--              phydev_err(phydev, "Calibration cycle timeout\n");
--              return ret;
--      }
--
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
--                         MTK_PHY_DA_CALIN_FLAG);
--      ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP);
--      if (ret < 0)
--              return ret;
--      ret = FIELD_GET(MTK_PHY_AD_CAL_COMP_OUT_MASK, ret);
--      phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
--
--      return ret;
--}
--
--static int rext_fill_result(struct phy_device *phydev, u16 *buf)
--{
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
--                     MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
--      phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
--                     MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
--
--      return 0;
--}
--
--static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
--{
--      u16 rext_cal_val[2];
--
--      rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
--      rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
--      rext_fill_result(phydev, rext_cal_val);
--
--      return 0;
--}
--
--static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
--{
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
--                     MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
--                     MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
--                     MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
--                     MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
--
--      return 0;
--}
--
--static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
--{
--      u16 tx_offset_cal_val[4];
--
--      tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
--      tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
--      tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
--      tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
--
--      tx_offset_fill_result(phydev, tx_offset_cal_val);
--
--      return 0;
--}
--
--static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
--{
--      const int vals_9481[16] = { 10, 6, 6, 10,
--                                  10, 6, 6, 10,
--                                  10, 6, 6, 10,
--                                  10, 6, 6, 10 };
--      const int vals_9461[16] = { 7, 1, 4, 7,
--                                  7, 1, 4, 7,
--                                  7, 1, 4, 7,
--                                  7, 1, 4, 7 };
--      int bias[16] = {};
--      int i;
--
--      switch (phydev->drv->phy_id) {
--      case MTK_GPHY_ID_MT7981:
--              /* We add some calibration to efuse values
--               * due to board level influence.
--               * GBE: +7, TBT: +1, HBT: +4, TST: +7
--               */
--              memcpy(bias, (const void *)vals_9461, sizeof(bias));
--              break;
--      case MTK_GPHY_ID_MT7988:
--              memcpy(bias, (const void *)vals_9481, sizeof(bias));
--              break;
--      }
--
--      /* Prevent overflow */
--      for (i = 0; i < 12; i++) {
--              if (buf[i >> 2] + bias[i] > 63) {
--                      buf[i >> 2] = 63;
--                      bias[i] = 0;
--              }
--      }
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
--                     MTK_PHY_DA_TX_I2MPB_A_GBE_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_GBE_MASK,
--                                buf[0] + bias[0]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
--                     MTK_PHY_DA_TX_I2MPB_A_TBT_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_TBT_MASK,
--                                buf[0] + bias[1]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
--                     MTK_PHY_DA_TX_I2MPB_A_HBT_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_HBT_MASK,
--                                buf[0] + bias[2]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
--                     MTK_PHY_DA_TX_I2MPB_A_TST_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_TST_MASK,
--                                buf[0] + bias[3]));
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
--                     MTK_PHY_DA_TX_I2MPB_B_GBE_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_GBE_MASK,
--                                buf[1] + bias[4]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
--                     MTK_PHY_DA_TX_I2MPB_B_TBT_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_TBT_MASK,
--                                buf[1] + bias[5]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
--                     MTK_PHY_DA_TX_I2MPB_B_HBT_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_HBT_MASK,
--                                buf[1] + bias[6]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
--                     MTK_PHY_DA_TX_I2MPB_B_TST_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_TST_MASK,
--                                buf[1] + bias[7]));
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
--                     MTK_PHY_DA_TX_I2MPB_C_GBE_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_GBE_MASK,
--                                buf[2] + bias[8]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
--                     MTK_PHY_DA_TX_I2MPB_C_TBT_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_TBT_MASK,
--                                buf[2] + bias[9]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
--                     MTK_PHY_DA_TX_I2MPB_C_HBT_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_HBT_MASK,
--                                buf[2] + bias[10]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
--                     MTK_PHY_DA_TX_I2MPB_C_TST_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_TST_MASK,
--                                buf[2] + bias[11]));
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
--                     MTK_PHY_DA_TX_I2MPB_D_GBE_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_GBE_MASK,
--                                buf[3] + bias[12]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
--                     MTK_PHY_DA_TX_I2MPB_D_TBT_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_TBT_MASK,
--                                buf[3] + bias[13]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
--                     MTK_PHY_DA_TX_I2MPB_D_HBT_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_HBT_MASK,
--                                buf[3] + bias[14]));
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
--                     MTK_PHY_DA_TX_I2MPB_D_TST_MASK,
--                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_TST_MASK,
--                                buf[3] + bias[15]));
--
--      return 0;
--}
--
--static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
--{
--      u16 tx_amp_cal_val[4];
--
--      tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
--      tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
--      tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
--      tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
--      tx_amp_fill_result(phydev, tx_amp_cal_val);
--
--      return 0;
--}
--
--static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
--                            u8 txg_calen_x)
--{
--      int bias = 0;
--      u16 reg, val;
--
--      if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
--              bias = -1;
--
--      val = clamp_val(bias + tx_r50_cal_val, 0, 63);
--
--      switch (txg_calen_x) {
--      case PAIR_A:
--              reg = MTK_PHY_DA_TX_R50_PAIR_A;
--              break;
--      case PAIR_B:
--              reg = MTK_PHY_DA_TX_R50_PAIR_B;
--              break;
--      case PAIR_C:
--              reg = MTK_PHY_DA_TX_R50_PAIR_C;
--              break;
--      case PAIR_D:
--              reg = MTK_PHY_DA_TX_R50_PAIR_D;
--              break;
--      default:
--              return -EINVAL;
--      }
--
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
--
--      return 0;
--}
--
--static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
--                          u8 txg_calen_x)
--{
--      u16 tx_r50_cal_val;
--
--      switch (txg_calen_x) {
--      case PAIR_A:
--              tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
--              break;
--      case PAIR_B:
--              tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
--              break;
--      case PAIR_C:
--              tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
--              break;
--      case PAIR_D:
--              tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
--              break;
--      default:
--              return -EINVAL;
--      }
--      tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
--
--      return 0;
--}
--
--static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
--{
--      u8 lower_idx, upper_idx, txreserve_val;
--      u8 lower_ret, upper_ret;
--      int ret;
--
--      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
--                       MTK_PHY_RG_ANA_CALEN);
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
--                         MTK_PHY_RG_CAL_CKINV);
--      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
--                       MTK_PHY_RG_TXVOS_CALEN);
--
--      switch (rg_txreserve_x) {
--      case PAIR_A:
--              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                                 MTK_PHY_RG_DASN_DAC_IN0_A,
--                                 MTK_PHY_DASN_DAC_IN0_A_MASK);
--              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                                 MTK_PHY_RG_DASN_DAC_IN1_A,
--                                 MTK_PHY_DASN_DAC_IN1_A_MASK);
--              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
--                               MTK_PHY_RG_ANA_CAL_RG0,
--                               MTK_PHY_RG_ZCALEN_A);
--              break;
--      case PAIR_B:
--              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                                 MTK_PHY_RG_DASN_DAC_IN0_B,
--                                 MTK_PHY_DASN_DAC_IN0_B_MASK);
--              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                                 MTK_PHY_RG_DASN_DAC_IN1_B,
--                                 MTK_PHY_DASN_DAC_IN1_B_MASK);
--              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
--                               MTK_PHY_RG_ANA_CAL_RG1,
--                               MTK_PHY_RG_ZCALEN_B);
--              break;
--      case PAIR_C:
--              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                                 MTK_PHY_RG_DASN_DAC_IN0_C,
--                                 MTK_PHY_DASN_DAC_IN0_C_MASK);
--              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                                 MTK_PHY_RG_DASN_DAC_IN1_C,
--                                 MTK_PHY_DASN_DAC_IN1_C_MASK);
--              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
--                               MTK_PHY_RG_ANA_CAL_RG1,
--                               MTK_PHY_RG_ZCALEN_C);
--              break;
--      case PAIR_D:
--              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                                 MTK_PHY_RG_DASN_DAC_IN0_D,
--                                 MTK_PHY_DASN_DAC_IN0_D_MASK);
--              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                                 MTK_PHY_RG_DASN_DAC_IN1_D,
--                                 MTK_PHY_DASN_DAC_IN1_D_MASK);
--              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
--                               MTK_PHY_RG_ANA_CAL_RG1,
--                               MTK_PHY_RG_ZCALEN_D);
--              break;
--      default:
--              ret = -EINVAL;
--              goto restore;
--      }
--
--      lower_idx = TXRESERVE_MIN;
--      upper_idx = TXRESERVE_MAX;
--
--      phydev_dbg(phydev, "Start TX-VCM SW cal.\n");
--      while ((upper_idx - lower_idx) > 1) {
--              txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
--              ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
--                              MTK_PHY_DA_RX_PSBN_TBT_MASK |
--                              MTK_PHY_DA_RX_PSBN_HBT_MASK |
--                              MTK_PHY_DA_RX_PSBN_GBE_MASK |
--                              MTK_PHY_DA_RX_PSBN_LP_MASK,
--                              txreserve_val << 12 | txreserve_val << 8 |
--                              txreserve_val << 4 | txreserve_val);
--              if (ret == 1) {
--                      upper_idx = txreserve_val;
--                      upper_ret = ret;
--              } else if (ret == 0) {
--                      lower_idx = txreserve_val;
--                      lower_ret = ret;
--              } else {
--                      goto restore;
--              }
--      }
--
--      if (lower_idx == TXRESERVE_MIN) {
--              lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
--                                    MTK_PHY_RXADC_CTRL_RG9,
--                                    MTK_PHY_DA_RX_PSBN_TBT_MASK |
--                                    MTK_PHY_DA_RX_PSBN_HBT_MASK |
--                                    MTK_PHY_DA_RX_PSBN_GBE_MASK |
--                                    MTK_PHY_DA_RX_PSBN_LP_MASK,
--                                    lower_idx << 12 | lower_idx << 8 |
--                                    lower_idx << 4 | lower_idx);
--              ret = lower_ret;
--      } else if (upper_idx == TXRESERVE_MAX) {
--              upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
--                                    MTK_PHY_RXADC_CTRL_RG9,
--                                    MTK_PHY_DA_RX_PSBN_TBT_MASK |
--                                    MTK_PHY_DA_RX_PSBN_HBT_MASK |
--                                    MTK_PHY_DA_RX_PSBN_GBE_MASK |
--                                    MTK_PHY_DA_RX_PSBN_LP_MASK,
--                                    upper_idx << 12 | upper_idx << 8 |
--                                    upper_idx << 4 | upper_idx);
--              ret = upper_ret;
--      }
--      if (ret < 0)
--              goto restore;
--
--      /* We calibrate TX-VCM in different logic. Check upper index and then
--       * lower index. If this calibration is valid, apply lower index's
--       * result.
--       */
--      ret = upper_ret - lower_ret;
--      if (ret == 1) {
--              ret = 0;
--              /* Make sure we use upper_idx in our calibration system */
--              cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
--                        MTK_PHY_DA_RX_PSBN_TBT_MASK |
--                        MTK_PHY_DA_RX_PSBN_HBT_MASK |
--                        MTK_PHY_DA_RX_PSBN_GBE_MASK |
--                        MTK_PHY_DA_RX_PSBN_LP_MASK,
--                        upper_idx << 12 | upper_idx << 8 |
--                        upper_idx << 4 | upper_idx);
--              phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
--      } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
--                 lower_ret == 1) {
--              ret = 0;
--              cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
--                        MTK_PHY_DA_RX_PSBN_TBT_MASK |
--                        MTK_PHY_DA_RX_PSBN_HBT_MASK |
--                        MTK_PHY_DA_RX_PSBN_GBE_MASK |
--                        MTK_PHY_DA_RX_PSBN_LP_MASK,
--                        lower_idx << 12 | lower_idx << 8 |
--                        lower_idx << 4 | lower_idx);
--              phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n",
--                          lower_idx);
--      } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
--                 lower_ret == 0) {
--              ret = 0;
--              phydev_warn(phydev,
--                          "TX-VCM SW cal result at high margin 0x%x\n",
--                          upper_idx);
--      } else {
--              ret = -EINVAL;
--      }
--
--restore:
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
--                         MTK_PHY_RG_ANA_CALEN);
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
--                         MTK_PHY_RG_TXVOS_CALEN);
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
--                         MTK_PHY_RG_ZCALEN_A);
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
--                         MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
--                         MTK_PHY_RG_ZCALEN_D);
--
--      return ret;
--}
--
--static void mt798x_phy_common_finetune(struct phy_device *phydev)
--{
--      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
--      __phy_write(phydev, 0x11, 0xc71);
--      __phy_write(phydev, 0x12, 0xc);
--      __phy_write(phydev, 0x10, 0x8fae);
--
--      /* EnabRandUpdTrig = 1 */
--      __phy_write(phydev, 0x11, 0x2f00);
--      __phy_write(phydev, 0x12, 0xe);
--      __phy_write(phydev, 0x10, 0x8fb0);
--
--      /* NormMseLoThresh = 85 */
--      __phy_write(phydev, 0x11, 0x55a0);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x83aa);
--
--      /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
--      __phy_write(phydev, 0x11, 0x240);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x9680);
--
--      /* TrFreeze = 0 (mt7988 default) */
--      __phy_write(phydev, 0x11, 0x0);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x9686);
--
--      /* SSTrKp100 = 5 */
--      /* SSTrKf100 = 6 */
--      /* SSTrKp1000Mas = 5 */
--      /* SSTrKf1000Mas = 6 */
--      /* SSTrKp1000Slv = 5 */
--      /* SSTrKf1000Slv = 6 */
--      __phy_write(phydev, 0x11, 0xbaef);
--      __phy_write(phydev, 0x12, 0x2e);
--      __phy_write(phydev, 0x10, 0x968c);
--      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
--}
--
--static void mt7981_phy_finetune(struct phy_device *phydev)
--{
--      u16 val[8] = { 0x01ce, 0x01c1,
--                     0x020f, 0x0202,
--                     0x03d0, 0x03c0,
--                     0x0013, 0x0005 };
--      int i, k;
--
--      /* 100M eye finetune:
--       * Keep middle level of TX MLT3 shapper as default.
--       * Only change TX MLT3 overshoot level here.
--       */
--      for (k = 0, i = 1; i < 12; i++) {
--              if (i % 3 == 0)
--                      continue;
--              phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
--      }
--
--      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      /* ResetSyncOffset = 6 */
--      __phy_write(phydev, 0x11, 0x600);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x8fc0);
--
--      /* VgaDecRate = 1 */
--      __phy_write(phydev, 0x11, 0x4c2a);
--      __phy_write(phydev, 0x12, 0x3e);
--      __phy_write(phydev, 0x10, 0x8fa4);
--
--      /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
--       * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
--       */
--      __phy_write(phydev, 0x11, 0xd10a);
--      __phy_write(phydev, 0x12, 0x34);
--      __phy_write(phydev, 0x10, 0x8f82);
--
--      /* VcoSlicerThreshBitsHigh */
--      __phy_write(phydev, 0x11, 0x5555);
--      __phy_write(phydev, 0x12, 0x55);
--      __phy_write(phydev, 0x10, 0x8ec0);
--      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
--
--      /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
--                     MTK_PHY_TR_OPEN_LOOP_EN_MASK |
--                     MTK_PHY_LPF_X_AVERAGE_MASK,
--                     BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
--
--      /* rg_tr_lpf_cnt_val = 512 */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
--
--      /* IIR2 related */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
--
--      /* FFE peaking */
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
--                     MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
--                     MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
--
--      /* Disable LDO pump */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
--      /* Adjust LDO output voltage */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
--}
--
--static void mt7988_phy_finetune(struct phy_device *phydev)
--{
--      u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
--                      0x020d, 0x0206, 0x0384, 0x03d0,
--                      0x03c6, 0x030a, 0x0011, 0x0005 };
--      int i;
--
--      /* Set default MLT3 shaper first */
--      for (i = 0; i < 12; i++)
--              phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
--
--      /* TCT finetune */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
--
--      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      /* ResetSyncOffset = 5 */
--      __phy_write(phydev, 0x11, 0x500);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x8fc0);
--
--      /* VgaDecRate is 1 at default on mt7988 */
--
--      /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
--       * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
--       */
--      __phy_write(phydev, 0x11, 0xb90a);
--      __phy_write(phydev, 0x12, 0x6f);
--      __phy_write(phydev, 0x10, 0x8f82);
--
--      /* RemAckCntLimitCtrl = 1 */
--      __phy_write(phydev, 0x11, 0xfbba);
--      __phy_write(phydev, 0x12, 0xc3);
--      __phy_write(phydev, 0x10, 0x87f8);
--
--      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
--
--      /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
--                     MTK_PHY_TR_OPEN_LOOP_EN_MASK |
--                     MTK_PHY_LPF_X_AVERAGE_MASK,
--                     BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
--
--      /* rg_tr_lpf_cnt_val = 1023 */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
--}
--
--static void mt798x_phy_eee(struct phy_device *phydev)
--{
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
--                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,
--                     MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |
--                     MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,
--                     FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |
--                     FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
--                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
--                     MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
--                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
--                                0xff));
--
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                         MTK_PHY_RG_TESTMUX_ADC_CTRL,
--                         MTK_PHY_RG_TXEN_DIG_MASK);
--
--      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
--                       MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);
--
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
--                         MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,
--                     MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |
--                     MTK_PHY_LPI_SLV_SEND_TX_EN,
--                     FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
--
--      /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
--                         MTK_PHY_LPI_TXPCS_LOC_RCV);
--
--      /* This also fixes some IoT issues, such as CH340 */
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
--                     MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
--                     FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
--                     FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,
--                     MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
--                     FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
--                                0x33) |
--                     MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |
--                     MTK_PHY_LPI_VCO_EEE_STG0_EN);
--
--      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,
--                       MTK_PHY_EEE_WAKE_MAS_INT_DC |
--                       MTK_PHY_EEE_WAKE_SLV_INT_DC);
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,
--                     MTK_PHY_SMI_DETCNT_MAX_MASK,
--                     FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |
--                     MTK_PHY_SMI_DET_MAX_EN);
--
--      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,
--                       MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |
--                       MTK_PHY_TREC_UPDATE_ENAB_CLR |
--                       MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |
--                       MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
--
--      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      /* Regsigdet_sel_1000 = 0 */
--      __phy_write(phydev, 0x11, 0xb);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x9690);
--
--      /* REG_EEE_st2TrKf1000 = 2 */
--      __phy_write(phydev, 0x11, 0x114f);
--      __phy_write(phydev, 0x12, 0x2);
--      __phy_write(phydev, 0x10, 0x969a);
--
--      /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
--      __phy_write(phydev, 0x11, 0x3028);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x969e);
--
--      /* RegEEE_slv_wake_int_timer_tar = 8 */
--      __phy_write(phydev, 0x11, 0x5010);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x96a0);
--
--      /* RegEEE_trfreeze_timer2 = 586 */
--      __phy_write(phydev, 0x11, 0x24a);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x96a8);
--
--      /* RegEEE100Stg1_tar = 16 */
--      __phy_write(phydev, 0x11, 0x3210);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x96b8);
--
--      /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
--      __phy_write(phydev, 0x11, 0x1463);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x96ca);
--
--      /* DfeTailEnableVgaThresh1000 = 27 */
--      __phy_write(phydev, 0x11, 0x36);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x8f80);
--      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
--
--      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
--      __phy_modify(phydev, MTK_PHY_LPI_REG_14,
--                   MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
--                   FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
--
--      __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
--                   FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));
--      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
--
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
--                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
--                     MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
--                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
--                                0xff));
--}
--
--static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
--                u8 start_pair, u8 end_pair)
--{
--      u8 pair_n;
--      int ret;
--
--      for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
--              /* TX_OFFSET & TX_AMP have no SW calibration. */
--              switch (cal_item) {
--              case TX_VCM:
--                      ret = tx_vcm_cal_sw(phydev, pair_n);
--                      break;
--              default:
--                      return -EINVAL;
--              }
--              if (ret)
--                      return ret;
--      }
--      return 0;
--}
--
--static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
--                   u8 start_pair, u8 end_pair, u32 *buf)
--{
--      u8 pair_n;
--      int ret;
--
--      for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
--              /* TX_VCM has no efuse calibration. */
--              switch (cal_item) {
--              case REXT:
--                      ret = rext_cal_efuse(phydev, buf);
--                      break;
--              case TX_OFFSET:
--                      ret = tx_offset_cal_efuse(phydev, buf);
--                      break;
--              case TX_AMP:
--                      ret = tx_amp_cal_efuse(phydev, buf);
--                      break;
--              case TX_R50:
--                      ret = tx_r50_cal_efuse(phydev, buf, pair_n);
--                      break;
--              default:
--                      return -EINVAL;
--              }
--              if (ret)
--                      return ret;
--      }
--
--      return 0;
--}
--
--static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
--                   enum CAL_MODE cal_mode, u8 start_pair,
--                   u8 end_pair, u32 *buf)
--{
--      int ret;
--
--      switch (cal_mode) {
--      case EFUSE_M:
--              ret = cal_efuse(phydev, cal_item, start_pair,
--                              end_pair, buf);
--              break;
--      case SW_M:
--              ret = cal_sw(phydev, cal_item, start_pair, end_pair);
--              break;
--      default:
--              return -EINVAL;
--      }
--
--      if (ret) {
--              phydev_err(phydev, "cal %d failed\n", cal_item);
--              return -EIO;
--      }
--
--      return 0;
--}
--
--static int mt798x_phy_calibration(struct phy_device *phydev)
--{
--      struct nvmem_cell *cell;
--      int ret = 0;
--      size_t len;
--      u32 *buf;
--
--      cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
--      if (IS_ERR(cell)) {
--              if (PTR_ERR(cell) == -EPROBE_DEFER)
--                      return PTR_ERR(cell);
--              return 0;
--      }
--
--      buf = (u32 *)nvmem_cell_read(cell, &len);
--      nvmem_cell_put(cell);
--      if (IS_ERR(buf))
--              return PTR_ERR(buf);
--
--      if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
--              phydev_err(phydev, "invalid efuse data\n");
--              ret = -EINVAL;
--              goto out;
--      }
--
--      ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
--      if (ret)
--              goto out;
--      ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
--      if (ret)
--              goto out;
--      ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
--      if (ret)
--              goto out;
--      ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
--      if (ret)
--              goto out;
--      ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
--      if (ret)
--              goto out;
--
--out:
--      kfree(buf);
--      return ret;
--}
--
--static int mt798x_phy_config_init(struct phy_device *phydev)
--{
--      switch (phydev->drv->phy_id) {
--      case MTK_GPHY_ID_MT7981:
--              mt7981_phy_finetune(phydev);
--              break;
--      case MTK_GPHY_ID_MT7988:
--              mt7988_phy_finetune(phydev);
--              break;
--      }
--
--      mt798x_phy_common_finetune(phydev);
--      mt798x_phy_eee(phydev);
--
--      return mt798x_phy_calibration(phydev);
--}
--
--static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
--                                  bool on)
--{
--      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
--      struct mtk_socphy_priv *priv = phydev->priv;
--      bool changed;
--
--      if (on)
--              changed = !test_and_set_bit(bit_on, &priv->led_state);
--      else
--              changed = !!test_and_clear_bit(bit_on, &priv->led_state);
--
--      changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
--                                      (index ? 16 : 0), &priv->led_state);
--      if (changed)
--              return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
--                                    MTK_PHY_LED1_ON_CTRL :
--                                    MTK_PHY_LED0_ON_CTRL,
--                                    MTK_PHY_LED_ON_MASK,
--                                    on ? MTK_PHY_LED_ON_FORCE_ON : 0);
--      else
--              return 0;
--}
--
--static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
--                                     bool blinking)
--{
--      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
--                               (index ? 16 : 0);
--      struct mtk_socphy_priv *priv = phydev->priv;
--      bool changed;
--
--      if (blinking)
--              changed = !test_and_set_bit(bit_blink, &priv->led_state);
--      else
--              changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
--
--      changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
--                            (index ? 16 : 0), &priv->led_state);
--      if (changed)
--              return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
--                                   MTK_PHY_LED1_BLINK_CTRL :
--                                   MTK_PHY_LED0_BLINK_CTRL,
--                                   blinking ?
--                                   MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
--      else
--              return 0;
--}
--
--static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
--                                  unsigned long *delay_on,
--                                  unsigned long *delay_off)
--{
--      bool blinking = false;
--      int err = 0;
--
--      if (index > 1)
--              return -EINVAL;
--
--      if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
--              blinking = true;
--              *delay_on = 50;
--              *delay_off = 50;
--      }
--
--      err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
--      if (err)
--              return err;
--
--      return mt798x_phy_hw_led_on_set(phydev, index, false);
--}
--
--static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
--                                       u8 index, enum led_brightness value)
--{
--      int err;
--
--      err = mt798x_phy_hw_led_blink_set(phydev, index, false);
--      if (err)
--              return err;
--
--      return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
--}
--
--static const unsigned long supported_triggers =
--      BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
--      BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
--      BIT(TRIGGER_NETDEV_LINK)        |
--      BIT(TRIGGER_NETDEV_LINK_10)     |
--      BIT(TRIGGER_NETDEV_LINK_100)    |
--      BIT(TRIGGER_NETDEV_LINK_1000)   |
--      BIT(TRIGGER_NETDEV_RX)          |
--      BIT(TRIGGER_NETDEV_TX);
--
--static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
--                                        unsigned long rules)
--{
--      if (index > 1)
--              return -EINVAL;
--
--      /* All combinations of the supported triggers are allowed */
--      if (rules & ~supported_triggers)
--              return -EOPNOTSUPP;
--
--      return 0;
--};
--
--static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
--                                       unsigned long *rules)
--{
--      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
--                               (index ? 16 : 0);
--      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
--      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
--      struct mtk_socphy_priv *priv = phydev->priv;
--      int on, blink;
--
--      if (index > 1)
--              return -EINVAL;
--
--      on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
--                        index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
--
--      if (on < 0)
--              return -EIO;
--
--      blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
--                           index ? MTK_PHY_LED1_BLINK_CTRL :
--                                   MTK_PHY_LED0_BLINK_CTRL);
--      if (blink < 0)
--              return -EIO;
--
--      if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX |
--                 MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) ||
--          (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
--              set_bit(bit_netdev, &priv->led_state);
--      else
--              clear_bit(bit_netdev, &priv->led_state);
--
--      if (on & MTK_PHY_LED_ON_FORCE_ON)
--              set_bit(bit_on, &priv->led_state);
--      else
--              clear_bit(bit_on, &priv->led_state);
--
--      if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
--              set_bit(bit_blink, &priv->led_state);
--      else
--              clear_bit(bit_blink, &priv->led_state);
--
--      if (!rules)
--              return 0;
--
--      if (on & MTK_PHY_LED_ON_LINK)
--              *rules |= BIT(TRIGGER_NETDEV_LINK);
--
--      if (on & MTK_PHY_LED_ON_LINK10)
--              *rules |= BIT(TRIGGER_NETDEV_LINK_10);
--
--      if (on & MTK_PHY_LED_ON_LINK100)
--              *rules |= BIT(TRIGGER_NETDEV_LINK_100);
--
--      if (on & MTK_PHY_LED_ON_LINK1000)
--              *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
--
--      if (on & MTK_PHY_LED_ON_FDX)
--              *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
--
--      if (on & MTK_PHY_LED_ON_HDX)
--              *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
--
--      if (blink & MTK_PHY_LED_BLINK_RX)
--              *rules |= BIT(TRIGGER_NETDEV_RX);
--
--      if (blink & MTK_PHY_LED_BLINK_TX)
--              *rules |= BIT(TRIGGER_NETDEV_TX);
--
--      return 0;
--};
--
--static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
--                                       unsigned long rules)
--{
--      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
--      struct mtk_socphy_priv *priv = phydev->priv;
--      u16 on = 0, blink = 0;
--      int ret;
--
--      if (index > 1)
--              return -EINVAL;
--
--      if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
--              on |= MTK_PHY_LED_ON_FDX;
--
--      if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
--              on |= MTK_PHY_LED_ON_HDX;
--
--      if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
--              on |= MTK_PHY_LED_ON_LINK10;
--
--      if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
--              on |= MTK_PHY_LED_ON_LINK100;
--
--      if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
--              on |= MTK_PHY_LED_ON_LINK1000;
--
--      if (rules & BIT(TRIGGER_NETDEV_RX)) {
--              blink |= (on & MTK_PHY_LED_ON_LINK) ?
--                        (((on & MTK_PHY_LED_ON_LINK10) ?
--                          MTK_PHY_LED_BLINK_10RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK100) ?
--                          MTK_PHY_LED_BLINK_100RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK1000) ?
--                          MTK_PHY_LED_BLINK_1000RX : 0)) :
--                        MTK_PHY_LED_BLINK_RX;
--      }
--
--      if (rules & BIT(TRIGGER_NETDEV_TX)) {
--              blink |= (on & MTK_PHY_LED_ON_LINK) ?
--                        (((on & MTK_PHY_LED_ON_LINK10) ?
--                          MTK_PHY_LED_BLINK_10TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK100) ?
--                          MTK_PHY_LED_BLINK_100TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK1000) ?
--                          MTK_PHY_LED_BLINK_1000TX : 0)) :
--                        MTK_PHY_LED_BLINK_TX;
--      }
--
--      if (blink || on)
--              set_bit(bit_netdev, &priv->led_state);
--      else
--              clear_bit(bit_netdev, &priv->led_state);
--
--      ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
--                              MTK_PHY_LED1_ON_CTRL :
--                              MTK_PHY_LED0_ON_CTRL,
--                           MTK_PHY_LED_ON_FDX     |
--                           MTK_PHY_LED_ON_HDX     |
--                           MTK_PHY_LED_ON_LINK,
--                           on);
--
--      if (ret)
--              return ret;
--
--      return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
--                              MTK_PHY_LED1_BLINK_CTRL :
--                              MTK_PHY_LED0_BLINK_CTRL, blink);
--};
--
--static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
--{
--      struct mtk_socphy_shared *priv = phydev->shared->priv;
--      u32 polarities;
--
--      if (led_num == 0)
--              polarities = ~(priv->boottrap);
--      else
--              polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
--
--      if (polarities & BIT(phydev->mdio.addr))
--              return true;
--
--      return false;
--}
--
--static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
--{
--      struct pinctrl *pinctrl;
--      int index;
--
--      /* Setup LED polarity according to bootstrap use of LED pins */
--      for (index = 0; index < 2; ++index)
--              phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
--                              MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
--                             MTK_PHY_LED_ON_POLARITY,
--                             mt7988_phy_led_get_polarity(phydev, index) ?
--                              MTK_PHY_LED_ON_POLARITY : 0);
--
--      /* Only now setup pinctrl to avoid bogus blinking */
--      pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
--      if (IS_ERR(pinctrl))
--              dev_err(&phydev->mdio.bus->dev,
--                      "Failed to setup PHY LED pinctrl\n");
--
--      return 0;
--}
--
--static int mt7988_phy_probe_shared(struct phy_device *phydev)
--{
--      struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
--      struct mtk_socphy_shared *shared = phydev->shared->priv;
--      struct regmap *regmap;
--      u32 reg;
--      int ret;
--
--      /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
--       * LED_C and LED_D respectively. At the same time those pins are used to
--       * bootstrap configuration of the reference clock source (LED_A),
--       * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
--       * In practice this is done using a LED and a resistor pulling the pin
--       * either to GND or to VIO.
--       * The detected value at boot time is accessible at run-time using the
--       * TPBANK0 register located in the gpio base of the pinctrl, in order
--       * to read it here it needs to be referenced by a phandle called
--       * 'mediatek,pio' in the MDIO bus hosting the PHY.
--       * The 4 bits in TPBANK0 are kept as package shared data and are used to
--       * set LED polarity for each of the LED0.
--       */
--      regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
--      if (IS_ERR(regmap))
--              return PTR_ERR(regmap);
--
--      ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
--      if (ret)
--              return ret;
--
--      shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
--
--      return 0;
--}
--
--static void mt798x_phy_leds_state_init(struct phy_device *phydev)
--{
--      int i;
--
--      for (i = 0; i < 2; ++i)
--              mt798x_phy_led_hw_control_get(phydev, i, NULL);
--}
--
--static int mt7988_phy_probe(struct phy_device *phydev)
--{
--      struct mtk_socphy_shared *shared;
--      struct mtk_socphy_priv *priv;
--      int err;
--
--      if (phydev->mdio.addr > 3)
--              return -EINVAL;
--
--      err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
--                                  sizeof(struct mtk_socphy_shared));
--      if (err)
--              return err;
--
--      if (phy_package_probe_once(phydev)) {
--              err = mt7988_phy_probe_shared(phydev);
--              if (err)
--                      return err;
--      }
--
--      shared = phydev->shared->priv;
--      priv = &shared->priv[phydev->mdio.addr];
--
--      phydev->priv = priv;
--
--      mt798x_phy_leds_state_init(phydev);
--
--      err = mt7988_phy_fix_leds_polarities(phydev);
--      if (err)
--              return err;
--
--      /* Disable TX power saving at probing to:
--       * 1. Meet common mode compliance test criteria
--       * 2. Make sure that TX-VCM calibration works fine
--       */
--      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
--                     MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
--
--      return mt798x_phy_calibration(phydev);
--}
--
--static int mt7981_phy_probe(struct phy_device *phydev)
--{
--      struct mtk_socphy_priv *priv;
--
--      priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
--                          GFP_KERNEL);
--      if (!priv)
--              return -ENOMEM;
--
--      phydev->priv = priv;
--
--      mt798x_phy_leds_state_init(phydev);
--
--      return mt798x_phy_calibration(phydev);
--}
--
--static struct phy_driver mtk_socphy_driver[] = {
--      {
--              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
--              .name           = "MediaTek MT7981 PHY",
--              .config_init    = mt798x_phy_config_init,
--              .config_intr    = genphy_no_config_intr,
--              .handle_interrupt = genphy_handle_interrupt_no_ack,
--              .probe          = mt7981_phy_probe,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = mtk_socphy_read_page,
--              .write_page     = mtk_socphy_write_page,
--              .led_blink_set  = mt798x_phy_led_blink_set,
--              .led_brightness_set = mt798x_phy_led_brightness_set,
--              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
--              .led_hw_control_set = mt798x_phy_led_hw_control_set,
--              .led_hw_control_get = mt798x_phy_led_hw_control_get,
--      },
--      {
--              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
--              .name           = "MediaTek MT7988 PHY",
--              .config_init    = mt798x_phy_config_init,
--              .config_intr    = genphy_no_config_intr,
--              .handle_interrupt = genphy_handle_interrupt_no_ack,
--              .probe          = mt7988_phy_probe,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = mtk_socphy_read_page,
--              .write_page     = mtk_socphy_write_page,
--              .led_blink_set  = mt798x_phy_led_blink_set,
--              .led_brightness_set = mt798x_phy_led_brightness_set,
--              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
--              .led_hw_control_set = mt798x_phy_led_hw_control_set,
--              .led_hw_control_get = mt798x_phy_led_hw_control_get,
--      },
--};
--
--module_phy_driver(mtk_socphy_driver);
--
--static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
--      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
--      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
--      { }
--};
--
--MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver");
--MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
--MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
--MODULE_LICENSE("GPL");
--
--MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);
---- a/drivers/net/phy/mediatek-ge.c
-+++ /dev/null
-@@ -1,111 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0+
--#include <linux/bitfield.h>
--#include <linux/module.h>
--#include <linux/phy.h>
--
--#define MTK_EXT_PAGE_ACCESS           0x1f
--#define MTK_PHY_PAGE_STANDARD         0x0000
--#define MTK_PHY_PAGE_EXTENDED         0x0001
--#define MTK_PHY_PAGE_EXTENDED_2               0x0002
--#define MTK_PHY_PAGE_EXTENDED_3               0x0003
--#define MTK_PHY_PAGE_EXTENDED_2A30    0x2a30
--#define MTK_PHY_PAGE_EXTENDED_52B5    0x52b5
--
--static int mtk_gephy_read_page(struct phy_device *phydev)
--{
--      return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
--}
--
--static int mtk_gephy_write_page(struct phy_device *phydev, int page)
--{
--      return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
--}
--
--static void mtk_gephy_config_init(struct phy_device *phydev)
--{
--      /* Enable HW auto downshift */
--      phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
--
--      /* Increase SlvDPSready time */
--      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      __phy_write(phydev, 0x10, 0xafae);
--      __phy_write(phydev, 0x12, 0x2f);
--      __phy_write(phydev, 0x10, 0x8fae);
--      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
--
--      /* Adjust 100_mse_threshold */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
--
--      /* Disable mcc */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
--}
--
--static int mt7530_phy_config_init(struct phy_device *phydev)
--{
--      mtk_gephy_config_init(phydev);
--
--      /* Increase post_update_timer */
--      phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
--
--      return 0;
--}
--
--static int mt7531_phy_config_init(struct phy_device *phydev)
--{
--      mtk_gephy_config_init(phydev);
--
--      /* PHY link down power saving enable */
--      phy_set_bits(phydev, 0x17, BIT(4));
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
--
--      /* Set TX Pair delay selection */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
--
--      return 0;
--}
--
--static struct phy_driver mtk_gephy_driver[] = {
--      {
--              PHY_ID_MATCH_EXACT(0x03a29412),
--              .name           = "MediaTek MT7530 PHY",
--              .config_init    = mt7530_phy_config_init,
--              /* Interrupts are handled by the switch, not the PHY
--               * itself.
--               */
--              .config_intr    = genphy_no_config_intr,
--              .handle_interrupt = genphy_handle_interrupt_no_ack,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = mtk_gephy_read_page,
--              .write_page     = mtk_gephy_write_page,
--      },
--      {
--              PHY_ID_MATCH_EXACT(0x03a29441),
--              .name           = "MediaTek MT7531 PHY",
--              .config_init    = mt7531_phy_config_init,
--              /* Interrupts are handled by the switch, not the PHY
--               * itself.
--               */
--              .config_intr    = genphy_no_config_intr,
--              .handle_interrupt = genphy_handle_interrupt_no_ack,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = mtk_gephy_read_page,
--              .write_page     = mtk_gephy_write_page,
--      },
--};
--
--module_phy_driver(mtk_gephy_driver);
--
--static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
--      { PHY_ID_MATCH_EXACT(0x03a29441) },
--      { PHY_ID_MATCH_EXACT(0x03a29412) },
--      { }
--};
--
--MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
--MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
--MODULE_LICENSE("GPL");
--
--MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);
---- /dev/null
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -0,0 +1,1610 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+#include <linux/bitfield.h>
-+#include <linux/bitmap.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/pinctrl/consumer.h>
-+#include <linux/phy.h>
-+#include <linux/regmap.h>
-+
-+#define MTK_GPHY_ID_MT7981                    0x03a29461
-+#define MTK_GPHY_ID_MT7988                    0x03a29481
-+
-+#define MTK_EXT_PAGE_ACCESS                   0x1f
-+#define MTK_PHY_PAGE_STANDARD                 0x0000
-+#define MTK_PHY_PAGE_EXTENDED_3                       0x0003
-+
-+#define MTK_PHY_LPI_REG_14                    0x14
-+#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK      GENMASK(8, 0)
-+
-+#define MTK_PHY_LPI_REG_1c                    0x1c
-+#define MTK_PHY_SMI_DET_ON_THRESH_MASK                GENMASK(13, 8)
-+
-+#define MTK_PHY_PAGE_EXTENDED_2A30            0x2a30
-+#define MTK_PHY_PAGE_EXTENDED_52B5            0x52b5
-+
-+#define ANALOG_INTERNAL_OPERATION_MAX_US      20
-+#define TXRESERVE_MIN                         0
-+#define TXRESERVE_MAX                         7
-+
-+#define MTK_PHY_ANARG_RG                      0x10
-+#define   MTK_PHY_TCLKOFFSET_MASK             GENMASK(12, 8)
-+
-+/* Registers on MDIO_MMD_VEND1 */
-+#define MTK_PHY_TXVLD_DA_RG                   0x12
-+#define   MTK_PHY_DA_TX_I2MPB_A_GBE_MASK      GENMASK(15, 10)
-+#define   MTK_PHY_DA_TX_I2MPB_A_TBT_MASK      GENMASK(5, 0)
-+
-+#define MTK_PHY_TX_I2MPB_TEST_MODE_A2         0x16
-+#define   MTK_PHY_DA_TX_I2MPB_A_HBT_MASK      GENMASK(15, 10)
-+#define   MTK_PHY_DA_TX_I2MPB_A_TST_MASK      GENMASK(5, 0)
-+
-+#define MTK_PHY_TX_I2MPB_TEST_MODE_B1         0x17
-+#define   MTK_PHY_DA_TX_I2MPB_B_GBE_MASK      GENMASK(13, 8)
-+#define   MTK_PHY_DA_TX_I2MPB_B_TBT_MASK      GENMASK(5, 0)
-+
-+#define MTK_PHY_TX_I2MPB_TEST_MODE_B2         0x18
-+#define   MTK_PHY_DA_TX_I2MPB_B_HBT_MASK      GENMASK(13, 8)
-+#define   MTK_PHY_DA_TX_I2MPB_B_TST_MASK      GENMASK(5, 0)
-+
-+#define MTK_PHY_TX_I2MPB_TEST_MODE_C1         0x19
-+#define   MTK_PHY_DA_TX_I2MPB_C_GBE_MASK      GENMASK(13, 8)
-+#define   MTK_PHY_DA_TX_I2MPB_C_TBT_MASK      GENMASK(5, 0)
-+
-+#define MTK_PHY_TX_I2MPB_TEST_MODE_C2         0x20
-+#define   MTK_PHY_DA_TX_I2MPB_C_HBT_MASK      GENMASK(13, 8)
-+#define   MTK_PHY_DA_TX_I2MPB_C_TST_MASK      GENMASK(5, 0)
-+
-+#define MTK_PHY_TX_I2MPB_TEST_MODE_D1         0x21
-+#define   MTK_PHY_DA_TX_I2MPB_D_GBE_MASK      GENMASK(13, 8)
-+#define   MTK_PHY_DA_TX_I2MPB_D_TBT_MASK      GENMASK(5, 0)
-+
-+#define MTK_PHY_TX_I2MPB_TEST_MODE_D2         0x22
-+#define   MTK_PHY_DA_TX_I2MPB_D_HBT_MASK      GENMASK(13, 8)
-+#define   MTK_PHY_DA_TX_I2MPB_D_TST_MASK      GENMASK(5, 0)
-+
-+#define MTK_PHY_RXADC_CTRL_RG7                        0xc6
-+#define   MTK_PHY_DA_AD_BUF_BIAS_LP_MASK      GENMASK(9, 8)
-+
-+#define MTK_PHY_RXADC_CTRL_RG9                        0xc8
-+#define   MTK_PHY_DA_RX_PSBN_TBT_MASK         GENMASK(14, 12)
-+#define   MTK_PHY_DA_RX_PSBN_HBT_MASK         GENMASK(10, 8)
-+#define   MTK_PHY_DA_RX_PSBN_GBE_MASK         GENMASK(6, 4)
-+#define   MTK_PHY_DA_RX_PSBN_LP_MASK          GENMASK(2, 0)
-+
-+#define MTK_PHY_LDO_OUTPUT_V                  0xd7
-+
-+#define MTK_PHY_RG_ANA_CAL_RG0                        0xdb
-+#define   MTK_PHY_RG_CAL_CKINV                        BIT(12)
-+#define   MTK_PHY_RG_ANA_CALEN                        BIT(8)
-+#define   MTK_PHY_RG_ZCALEN_A                 BIT(0)
-+
-+#define MTK_PHY_RG_ANA_CAL_RG1                        0xdc
-+#define   MTK_PHY_RG_ZCALEN_B                 BIT(12)
-+#define   MTK_PHY_RG_ZCALEN_C                 BIT(8)
-+#define   MTK_PHY_RG_ZCALEN_D                 BIT(4)
-+#define   MTK_PHY_RG_TXVOS_CALEN              BIT(0)
-+
-+#define MTK_PHY_RG_ANA_CAL_RG5                        0xe0
-+#define   MTK_PHY_RG_REXT_TRIM_MASK           GENMASK(13, 8)
-+
-+#define MTK_PHY_RG_TX_FILTER                  0xfe
-+
-+#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120    0x120
-+#define   MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK       GENMASK(12, 8)
-+#define   MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK       GENMASK(4, 0)
-+
-+#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122    0x122
-+#define   MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK     GENMASK(7, 0)
-+
-+#define MTK_PHY_RG_TESTMUX_ADC_CTRL           0x144
-+#define   MTK_PHY_RG_TXEN_DIG_MASK            GENMASK(5, 5)
-+
-+#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B               0x172
-+#define   MTK_PHY_CR_TX_AMP_OFFSET_A_MASK     GENMASK(13, 8)
-+#define   MTK_PHY_CR_TX_AMP_OFFSET_B_MASK     GENMASK(6, 0)
-+
-+#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D               0x173
-+#define   MTK_PHY_CR_TX_AMP_OFFSET_C_MASK     GENMASK(13, 8)
-+#define   MTK_PHY_CR_TX_AMP_OFFSET_D_MASK     GENMASK(6, 0)
-+
-+#define MTK_PHY_RG_AD_CAL_COMP                        0x17a
-+#define   MTK_PHY_AD_CAL_COMP_OUT_MASK                GENMASK(8, 8)
-+
-+#define MTK_PHY_RG_AD_CAL_CLK                 0x17b
-+#define   MTK_PHY_DA_CAL_CLK                  BIT(0)
-+
-+#define MTK_PHY_RG_AD_CALIN                   0x17c
-+#define   MTK_PHY_DA_CALIN_FLAG                       BIT(0)
-+
-+#define MTK_PHY_RG_DASN_DAC_IN0_A             0x17d
-+#define   MTK_PHY_DASN_DAC_IN0_A_MASK         GENMASK(9, 0)
-+
-+#define MTK_PHY_RG_DASN_DAC_IN0_B             0x17e
-+#define   MTK_PHY_DASN_DAC_IN0_B_MASK         GENMASK(9, 0)
-+
-+#define MTK_PHY_RG_DASN_DAC_IN0_C             0x17f
-+#define   MTK_PHY_DASN_DAC_IN0_C_MASK         GENMASK(9, 0)
-+
-+#define MTK_PHY_RG_DASN_DAC_IN0_D             0x180
-+#define   MTK_PHY_DASN_DAC_IN0_D_MASK         GENMASK(9, 0)
-+
-+#define MTK_PHY_RG_DASN_DAC_IN1_A             0x181
-+#define   MTK_PHY_DASN_DAC_IN1_A_MASK         GENMASK(9, 0)
-+
-+#define MTK_PHY_RG_DASN_DAC_IN1_B             0x182
-+#define   MTK_PHY_DASN_DAC_IN1_B_MASK         GENMASK(9, 0)
-+
-+#define MTK_PHY_RG_DASN_DAC_IN1_C             0x183
-+#define   MTK_PHY_DASN_DAC_IN1_C_MASK         GENMASK(9, 0)
-+
-+#define MTK_PHY_RG_DASN_DAC_IN1_D             0x184
-+#define   MTK_PHY_DASN_DAC_IN1_D_MASK         GENMASK(9, 0)
-+
-+#define MTK_PHY_RG_DEV1E_REG19b                       0x19b
-+#define   MTK_PHY_BYPASS_DSP_LPI_READY                BIT(8)
-+
-+#define MTK_PHY_RG_LP_IIR2_K1_L                       0x22a
-+#define MTK_PHY_RG_LP_IIR2_K1_U                       0x22b
-+#define MTK_PHY_RG_LP_IIR2_K2_L                       0x22c
-+#define MTK_PHY_RG_LP_IIR2_K2_U                       0x22d
-+#define MTK_PHY_RG_LP_IIR2_K3_L                       0x22e
-+#define MTK_PHY_RG_LP_IIR2_K3_U                       0x22f
-+#define MTK_PHY_RG_LP_IIR2_K4_L                       0x230
-+#define MTK_PHY_RG_LP_IIR2_K4_U                       0x231
-+#define MTK_PHY_RG_LP_IIR2_K5_L                       0x232
-+#define MTK_PHY_RG_LP_IIR2_K5_U                       0x233
-+
-+#define MTK_PHY_RG_DEV1E_REG234                       0x234
-+#define   MTK_PHY_TR_OPEN_LOOP_EN_MASK                GENMASK(0, 0)
-+#define   MTK_PHY_LPF_X_AVERAGE_MASK          GENMASK(7, 4)
-+#define   MTK_PHY_TR_LP_IIR_EEE_EN            BIT(12)
-+
-+#define MTK_PHY_RG_LPF_CNT_VAL                        0x235
-+
-+#define MTK_PHY_RG_DEV1E_REG238                       0x238
-+#define   MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK  GENMASK(8, 0)
-+#define   MTK_PHY_LPI_SLV_SEND_TX_EN          BIT(12)
-+
-+#define MTK_PHY_RG_DEV1E_REG239                       0x239
-+#define   MTK_PHY_LPI_SEND_LOC_TIMER_MASK     GENMASK(8, 0)
-+#define   MTK_PHY_LPI_TXPCS_LOC_RCV           BIT(12)
-+
-+#define MTK_PHY_RG_DEV1E_REG27C                       0x27c
-+#define   MTK_PHY_VGASTATE_FFE_THR_ST1_MASK   GENMASK(12, 8)
-+#define MTK_PHY_RG_DEV1E_REG27D                       0x27d
-+#define   MTK_PHY_VGASTATE_FFE_THR_ST2_MASK   GENMASK(4, 0)
-+
-+#define MTK_PHY_RG_DEV1E_REG2C7                       0x2c7
-+#define   MTK_PHY_MAX_GAIN_MASK                       GENMASK(4, 0)
-+#define   MTK_PHY_MIN_GAIN_MASK                       GENMASK(12, 8)
-+
-+#define MTK_PHY_RG_DEV1E_REG2D1                       0x2d1
-+#define   MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK        GENMASK(7, 0)
-+#define   MTK_PHY_LPI_SKIP_SD_SLV_TR          BIT(8)
-+#define   MTK_PHY_LPI_TR_READY                        BIT(9)
-+#define   MTK_PHY_LPI_VCO_EEE_STG0_EN         BIT(10)
-+
-+#define MTK_PHY_RG_DEV1E_REG323                       0x323
-+#define   MTK_PHY_EEE_WAKE_MAS_INT_DC         BIT(0)
-+#define   MTK_PHY_EEE_WAKE_SLV_INT_DC         BIT(4)
-+
-+#define MTK_PHY_RG_DEV1E_REG324                       0x324
-+#define   MTK_PHY_SMI_DETCNT_MAX_MASK         GENMASK(5, 0)
-+#define   MTK_PHY_SMI_DET_MAX_EN              BIT(8)
-+
-+#define MTK_PHY_RG_DEV1E_REG326                       0x326
-+#define   MTK_PHY_LPI_MODE_SD_ON              BIT(0)
-+#define   MTK_PHY_RESET_RANDUPD_CNT           BIT(1)
-+#define   MTK_PHY_TREC_UPDATE_ENAB_CLR                BIT(2)
-+#define   MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF       BIT(4)
-+#define   MTK_PHY_TR_READY_SKIP_AFE_WAKEUP    BIT(5)
-+
-+#define MTK_PHY_LDO_PUMP_EN_PAIRAB            0x502
-+#define MTK_PHY_LDO_PUMP_EN_PAIRCD            0x503
-+
-+#define MTK_PHY_DA_TX_R50_PAIR_A              0x53d
-+#define MTK_PHY_DA_TX_R50_PAIR_B              0x53e
-+#define MTK_PHY_DA_TX_R50_PAIR_C              0x53f
-+#define MTK_PHY_DA_TX_R50_PAIR_D              0x540
-+
-+/* Registers on MDIO_MMD_VEND2 */
-+#define MTK_PHY_LED0_ON_CTRL                  0x24
-+#define MTK_PHY_LED1_ON_CTRL                  0x26
-+#define   MTK_PHY_LED_ON_MASK                 GENMASK(6, 0)
-+#define   MTK_PHY_LED_ON_LINK1000             BIT(0)
-+#define   MTK_PHY_LED_ON_LINK100              BIT(1)
-+#define   MTK_PHY_LED_ON_LINK10                       BIT(2)
-+#define   MTK_PHY_LED_ON_LINK                 (MTK_PHY_LED_ON_LINK10 |\
-+                                               MTK_PHY_LED_ON_LINK100 |\
-+                                               MTK_PHY_LED_ON_LINK1000)
-+#define   MTK_PHY_LED_ON_LINKDOWN             BIT(3)
-+#define   MTK_PHY_LED_ON_FDX                  BIT(4) /* Full duplex */
-+#define   MTK_PHY_LED_ON_HDX                  BIT(5) /* Half duplex */
-+#define   MTK_PHY_LED_ON_FORCE_ON             BIT(6)
-+#define   MTK_PHY_LED_ON_POLARITY             BIT(14)
-+#define   MTK_PHY_LED_ON_ENABLE                       BIT(15)
-+
-+#define MTK_PHY_LED0_BLINK_CTRL                       0x25
-+#define MTK_PHY_LED1_BLINK_CTRL                       0x27
-+#define   MTK_PHY_LED_BLINK_1000TX            BIT(0)
-+#define   MTK_PHY_LED_BLINK_1000RX            BIT(1)
-+#define   MTK_PHY_LED_BLINK_100TX             BIT(2)
-+#define   MTK_PHY_LED_BLINK_100RX             BIT(3)
-+#define   MTK_PHY_LED_BLINK_10TX              BIT(4)
-+#define   MTK_PHY_LED_BLINK_10RX              BIT(5)
-+#define   MTK_PHY_LED_BLINK_RX                        (MTK_PHY_LED_BLINK_10RX |\
-+                                               MTK_PHY_LED_BLINK_100RX |\
-+                                               MTK_PHY_LED_BLINK_1000RX)
-+#define   MTK_PHY_LED_BLINK_TX                        (MTK_PHY_LED_BLINK_10TX |\
-+                                               MTK_PHY_LED_BLINK_100TX |\
-+                                               MTK_PHY_LED_BLINK_1000TX)
-+#define   MTK_PHY_LED_BLINK_COLLISION         BIT(6)
-+#define   MTK_PHY_LED_BLINK_RX_CRC_ERR                BIT(7)
-+#define   MTK_PHY_LED_BLINK_RX_IDLE_ERR               BIT(8)
-+#define   MTK_PHY_LED_BLINK_FORCE_BLINK               BIT(9)
-+
-+#define MTK_PHY_LED1_DEFAULT_POLARITIES               BIT(1)
-+
-+#define MTK_PHY_RG_BG_RASEL                   0x115
-+#define   MTK_PHY_RG_BG_RASEL_MASK            GENMASK(2, 0)
-+
-+/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
-+#define RG_GPIO_MISC_TPBANK0                  0x6f0
-+#define   RG_GPIO_MISC_TPBANK0_BOOTMODE               GENMASK(11, 8)
-+
-+/* These macro privides efuse parsing for internal phy. */
-+#define EFS_DA_TX_I2MPB_A(x)                  (((x) >> 0) & GENMASK(5, 0))
-+#define EFS_DA_TX_I2MPB_B(x)                  (((x) >> 6) & GENMASK(5, 0))
-+#define EFS_DA_TX_I2MPB_C(x)                  (((x) >> 12) & GENMASK(5, 0))
-+#define EFS_DA_TX_I2MPB_D(x)                  (((x) >> 18) & GENMASK(5, 0))
-+#define EFS_DA_TX_AMP_OFFSET_A(x)             (((x) >> 24) & GENMASK(5, 0))
-+
-+#define EFS_DA_TX_AMP_OFFSET_B(x)             (((x) >> 0) & GENMASK(5, 0))
-+#define EFS_DA_TX_AMP_OFFSET_C(x)             (((x) >> 6) & GENMASK(5, 0))
-+#define EFS_DA_TX_AMP_OFFSET_D(x)             (((x) >> 12) & GENMASK(5, 0))
-+#define EFS_DA_TX_R50_A(x)                    (((x) >> 18) & GENMASK(5, 0))
-+#define EFS_DA_TX_R50_B(x)                    (((x) >> 24) & GENMASK(5, 0))
-+
-+#define EFS_DA_TX_R50_C(x)                    (((x) >> 0) & GENMASK(5, 0))
-+#define EFS_DA_TX_R50_D(x)                    (((x) >> 6) & GENMASK(5, 0))
-+
-+#define EFS_RG_BG_RASEL(x)                    (((x) >> 4) & GENMASK(2, 0))
-+#define EFS_RG_REXT_TRIM(x)                   (((x) >> 7) & GENMASK(5, 0))
-+
-+enum {
-+      NO_PAIR,
-+      PAIR_A,
-+      PAIR_B,
-+      PAIR_C,
-+      PAIR_D,
-+};
-+
-+enum calibration_mode {
-+      EFUSE_K,
-+      SW_K
-+};
-+
-+enum CAL_ITEM {
-+      REXT,
-+      TX_OFFSET,
-+      TX_AMP,
-+      TX_R50,
-+      TX_VCM
-+};
-+
-+enum CAL_MODE {
-+      EFUSE_M,
-+      SW_M
-+};
-+
-+#define MTK_PHY_LED_STATE_FORCE_ON    0
-+#define MTK_PHY_LED_STATE_FORCE_BLINK 1
-+#define MTK_PHY_LED_STATE_NETDEV      2
-+
-+struct mtk_socphy_priv {
-+      unsigned long           led_state;
-+};
-+
-+struct mtk_socphy_shared {
-+      u32                     boottrap;
-+      struct mtk_socphy_priv  priv[4];
-+};
-+
-+static int mtk_socphy_read_page(struct phy_device *phydev)
-+{
-+      return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
-+}
-+
-+static int mtk_socphy_write_page(struct phy_device *phydev, int page)
-+{
-+      return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
-+}
-+
-+/* One calibration cycle consists of:
-+ * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
-+ *   until AD_CAL_COMP is ready to output calibration result.
-+ * 2.Wait until DA_CAL_CLK is available.
-+ * 3.Fetch AD_CAL_COMP_OUT.
-+ */
-+static int cal_cycle(struct phy_device *phydev, int devad,
-+                   u32 regnum, u16 mask, u16 cal_val)
-+{
-+      int reg_val;
-+      int ret;
-+
-+      phy_modify_mmd(phydev, devad, regnum,
-+                     mask, cal_val);
-+      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
-+                       MTK_PHY_DA_CALIN_FLAG);
-+
-+      ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-+                                      MTK_PHY_RG_AD_CAL_CLK, reg_val,
-+                                      reg_val & MTK_PHY_DA_CAL_CLK, 500,
-+                                      ANALOG_INTERNAL_OPERATION_MAX_US,
-+                                      false);
-+      if (ret) {
-+              phydev_err(phydev, "Calibration cycle timeout\n");
-+              return ret;
-+      }
-+
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
-+                         MTK_PHY_DA_CALIN_FLAG);
-+      ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP);
-+      if (ret < 0)
-+              return ret;
-+      ret = FIELD_GET(MTK_PHY_AD_CAL_COMP_OUT_MASK, ret);
-+      phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
-+
-+      return ret;
-+}
-+
-+static int rext_fill_result(struct phy_device *phydev, u16 *buf)
-+{
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
-+                     MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
-+                     MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
-+
-+      return 0;
-+}
-+
-+static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
-+{
-+      u16 rext_cal_val[2];
-+
-+      rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
-+      rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
-+      rext_fill_result(phydev, rext_cal_val);
-+
-+      return 0;
-+}
-+
-+static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
-+{
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
-+                     MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
-+                     MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
-+                     MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
-+                     MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
-+
-+      return 0;
-+}
-+
-+static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
-+{
-+      u16 tx_offset_cal_val[4];
-+
-+      tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
-+      tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
-+      tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
-+      tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
-+
-+      tx_offset_fill_result(phydev, tx_offset_cal_val);
-+
-+      return 0;
-+}
-+
-+static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
-+{
-+      const int vals_9481[16] = { 10, 6, 6, 10,
-+                                  10, 6, 6, 10,
-+                                  10, 6, 6, 10,
-+                                  10, 6, 6, 10 };
-+      const int vals_9461[16] = { 7, 1, 4, 7,
-+                                  7, 1, 4, 7,
-+                                  7, 1, 4, 7,
-+                                  7, 1, 4, 7 };
-+      int bias[16] = {};
-+      int i;
-+
-+      switch (phydev->drv->phy_id) {
-+      case MTK_GPHY_ID_MT7981:
-+              /* We add some calibration to efuse values
-+               * due to board level influence.
-+               * GBE: +7, TBT: +1, HBT: +4, TST: +7
-+               */
-+              memcpy(bias, (const void *)vals_9461, sizeof(bias));
-+              break;
-+      case MTK_GPHY_ID_MT7988:
-+              memcpy(bias, (const void *)vals_9481, sizeof(bias));
-+              break;
-+      }
-+
-+      /* Prevent overflow */
-+      for (i = 0; i < 12; i++) {
-+              if (buf[i >> 2] + bias[i] > 63) {
-+                      buf[i >> 2] = 63;
-+                      bias[i] = 0;
-+              }
-+      }
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
-+                     MTK_PHY_DA_TX_I2MPB_A_GBE_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_GBE_MASK,
-+                                buf[0] + bias[0]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
-+                     MTK_PHY_DA_TX_I2MPB_A_TBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_TBT_MASK,
-+                                buf[0] + bias[1]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
-+                     MTK_PHY_DA_TX_I2MPB_A_HBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_HBT_MASK,
-+                                buf[0] + bias[2]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
-+                     MTK_PHY_DA_TX_I2MPB_A_TST_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_TST_MASK,
-+                                buf[0] + bias[3]));
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
-+                     MTK_PHY_DA_TX_I2MPB_B_GBE_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_GBE_MASK,
-+                                buf[1] + bias[4]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
-+                     MTK_PHY_DA_TX_I2MPB_B_TBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_TBT_MASK,
-+                                buf[1] + bias[5]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
-+                     MTK_PHY_DA_TX_I2MPB_B_HBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_HBT_MASK,
-+                                buf[1] + bias[6]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
-+                     MTK_PHY_DA_TX_I2MPB_B_TST_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_TST_MASK,
-+                                buf[1] + bias[7]));
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
-+                     MTK_PHY_DA_TX_I2MPB_C_GBE_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_GBE_MASK,
-+                                buf[2] + bias[8]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
-+                     MTK_PHY_DA_TX_I2MPB_C_TBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_TBT_MASK,
-+                                buf[2] + bias[9]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
-+                     MTK_PHY_DA_TX_I2MPB_C_HBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_HBT_MASK,
-+                                buf[2] + bias[10]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
-+                     MTK_PHY_DA_TX_I2MPB_C_TST_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_TST_MASK,
-+                                buf[2] + bias[11]));
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
-+                     MTK_PHY_DA_TX_I2MPB_D_GBE_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_GBE_MASK,
-+                                buf[3] + bias[12]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
-+                     MTK_PHY_DA_TX_I2MPB_D_TBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_TBT_MASK,
-+                                buf[3] + bias[13]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
-+                     MTK_PHY_DA_TX_I2MPB_D_HBT_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_HBT_MASK,
-+                                buf[3] + bias[14]));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
-+                     MTK_PHY_DA_TX_I2MPB_D_TST_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_TST_MASK,
-+                                buf[3] + bias[15]));
-+
-+      return 0;
-+}
-+
-+static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
-+{
-+      u16 tx_amp_cal_val[4];
-+
-+      tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
-+      tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
-+      tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
-+      tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
-+      tx_amp_fill_result(phydev, tx_amp_cal_val);
-+
-+      return 0;
-+}
-+
-+static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
-+                            u8 txg_calen_x)
-+{
-+      int bias = 0;
-+      u16 reg, val;
-+
-+      if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
-+              bias = -1;
-+
-+      val = clamp_val(bias + tx_r50_cal_val, 0, 63);
-+
-+      switch (txg_calen_x) {
-+      case PAIR_A:
-+              reg = MTK_PHY_DA_TX_R50_PAIR_A;
-+              break;
-+      case PAIR_B:
-+              reg = MTK_PHY_DA_TX_R50_PAIR_B;
-+              break;
-+      case PAIR_C:
-+              reg = MTK_PHY_DA_TX_R50_PAIR_C;
-+              break;
-+      case PAIR_D:
-+              reg = MTK_PHY_DA_TX_R50_PAIR_D;
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
-+
-+      return 0;
-+}
-+
-+static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
-+                          u8 txg_calen_x)
-+{
-+      u16 tx_r50_cal_val;
-+
-+      switch (txg_calen_x) {
-+      case PAIR_A:
-+              tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
-+              break;
-+      case PAIR_B:
-+              tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
-+              break;
-+      case PAIR_C:
-+              tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
-+              break;
-+      case PAIR_D:
-+              tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+      tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
-+
-+      return 0;
-+}
-+
-+static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
-+{
-+      u8 lower_idx, upper_idx, txreserve_val;
-+      u8 lower_ret, upper_ret;
-+      int ret;
-+
-+      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
-+                       MTK_PHY_RG_ANA_CALEN);
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
-+                         MTK_PHY_RG_CAL_CKINV);
-+      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
-+                       MTK_PHY_RG_TXVOS_CALEN);
-+
-+      switch (rg_txreserve_x) {
-+      case PAIR_A:
-+              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                                 MTK_PHY_RG_DASN_DAC_IN0_A,
-+                                 MTK_PHY_DASN_DAC_IN0_A_MASK);
-+              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                                 MTK_PHY_RG_DASN_DAC_IN1_A,
-+                                 MTK_PHY_DASN_DAC_IN1_A_MASK);
-+              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                               MTK_PHY_RG_ANA_CAL_RG0,
-+                               MTK_PHY_RG_ZCALEN_A);
-+              break;
-+      case PAIR_B:
-+              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                                 MTK_PHY_RG_DASN_DAC_IN0_B,
-+                                 MTK_PHY_DASN_DAC_IN0_B_MASK);
-+              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                                 MTK_PHY_RG_DASN_DAC_IN1_B,
-+                                 MTK_PHY_DASN_DAC_IN1_B_MASK);
-+              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                               MTK_PHY_RG_ANA_CAL_RG1,
-+                               MTK_PHY_RG_ZCALEN_B);
-+              break;
-+      case PAIR_C:
-+              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                                 MTK_PHY_RG_DASN_DAC_IN0_C,
-+                                 MTK_PHY_DASN_DAC_IN0_C_MASK);
-+              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                                 MTK_PHY_RG_DASN_DAC_IN1_C,
-+                                 MTK_PHY_DASN_DAC_IN1_C_MASK);
-+              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                               MTK_PHY_RG_ANA_CAL_RG1,
-+                               MTK_PHY_RG_ZCALEN_C);
-+              break;
-+      case PAIR_D:
-+              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                                 MTK_PHY_RG_DASN_DAC_IN0_D,
-+                                 MTK_PHY_DASN_DAC_IN0_D_MASK);
-+              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                                 MTK_PHY_RG_DASN_DAC_IN1_D,
-+                                 MTK_PHY_DASN_DAC_IN1_D_MASK);
-+              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                               MTK_PHY_RG_ANA_CAL_RG1,
-+                               MTK_PHY_RG_ZCALEN_D);
-+              break;
-+      default:
-+              ret = -EINVAL;
-+              goto restore;
-+      }
-+
-+      lower_idx = TXRESERVE_MIN;
-+      upper_idx = TXRESERVE_MAX;
-+
-+      phydev_dbg(phydev, "Start TX-VCM SW cal.\n");
-+      while ((upper_idx - lower_idx) > 1) {
-+              txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
-+              ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
-+                              MTK_PHY_DA_RX_PSBN_TBT_MASK |
-+                              MTK_PHY_DA_RX_PSBN_HBT_MASK |
-+                              MTK_PHY_DA_RX_PSBN_GBE_MASK |
-+                              MTK_PHY_DA_RX_PSBN_LP_MASK,
-+                              txreserve_val << 12 | txreserve_val << 8 |
-+                              txreserve_val << 4 | txreserve_val);
-+              if (ret == 1) {
-+                      upper_idx = txreserve_val;
-+                      upper_ret = ret;
-+              } else if (ret == 0) {
-+                      lower_idx = txreserve_val;
-+                      lower_ret = ret;
-+              } else {
-+                      goto restore;
-+              }
-+      }
-+
-+      if (lower_idx == TXRESERVE_MIN) {
-+              lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
-+                                    MTK_PHY_RXADC_CTRL_RG9,
-+                                    MTK_PHY_DA_RX_PSBN_TBT_MASK |
-+                                    MTK_PHY_DA_RX_PSBN_HBT_MASK |
-+                                    MTK_PHY_DA_RX_PSBN_GBE_MASK |
-+                                    MTK_PHY_DA_RX_PSBN_LP_MASK,
-+                                    lower_idx << 12 | lower_idx << 8 |
-+                                    lower_idx << 4 | lower_idx);
-+              ret = lower_ret;
-+      } else if (upper_idx == TXRESERVE_MAX) {
-+              upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
-+                                    MTK_PHY_RXADC_CTRL_RG9,
-+                                    MTK_PHY_DA_RX_PSBN_TBT_MASK |
-+                                    MTK_PHY_DA_RX_PSBN_HBT_MASK |
-+                                    MTK_PHY_DA_RX_PSBN_GBE_MASK |
-+                                    MTK_PHY_DA_RX_PSBN_LP_MASK,
-+                                    upper_idx << 12 | upper_idx << 8 |
-+                                    upper_idx << 4 | upper_idx);
-+              ret = upper_ret;
-+      }
-+      if (ret < 0)
-+              goto restore;
-+
-+      /* We calibrate TX-VCM in different logic. Check upper index and then
-+       * lower index. If this calibration is valid, apply lower index's
-+       * result.
-+       */
-+      ret = upper_ret - lower_ret;
-+      if (ret == 1) {
-+              ret = 0;
-+              /* Make sure we use upper_idx in our calibration system */
-+              cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
-+                        MTK_PHY_DA_RX_PSBN_TBT_MASK |
-+                        MTK_PHY_DA_RX_PSBN_HBT_MASK |
-+                        MTK_PHY_DA_RX_PSBN_GBE_MASK |
-+                        MTK_PHY_DA_RX_PSBN_LP_MASK,
-+                        upper_idx << 12 | upper_idx << 8 |
-+                        upper_idx << 4 | upper_idx);
-+              phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
-+      } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
-+                 lower_ret == 1) {
-+              ret = 0;
-+              cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
-+                        MTK_PHY_DA_RX_PSBN_TBT_MASK |
-+                        MTK_PHY_DA_RX_PSBN_HBT_MASK |
-+                        MTK_PHY_DA_RX_PSBN_GBE_MASK |
-+                        MTK_PHY_DA_RX_PSBN_LP_MASK,
-+                        lower_idx << 12 | lower_idx << 8 |
-+                        lower_idx << 4 | lower_idx);
-+              phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n",
-+                          lower_idx);
-+      } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
-+                 lower_ret == 0) {
-+              ret = 0;
-+              phydev_warn(phydev,
-+                          "TX-VCM SW cal result at high margin 0x%x\n",
-+                          upper_idx);
-+      } else {
-+              ret = -EINVAL;
-+      }
-+
-+restore:
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
-+                         MTK_PHY_RG_ANA_CALEN);
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
-+                         MTK_PHY_RG_TXVOS_CALEN);
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
-+                         MTK_PHY_RG_ZCALEN_A);
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
-+                         MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
-+                         MTK_PHY_RG_ZCALEN_D);
-+
-+      return ret;
-+}
-+
-+static void mt798x_phy_common_finetune(struct phy_device *phydev)
-+{
-+      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-+      /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
-+      __phy_write(phydev, 0x11, 0xc71);
-+      __phy_write(phydev, 0x12, 0xc);
-+      __phy_write(phydev, 0x10, 0x8fae);
-+
-+      /* EnabRandUpdTrig = 1 */
-+      __phy_write(phydev, 0x11, 0x2f00);
-+      __phy_write(phydev, 0x12, 0xe);
-+      __phy_write(phydev, 0x10, 0x8fb0);
-+
-+      /* NormMseLoThresh = 85 */
-+      __phy_write(phydev, 0x11, 0x55a0);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x83aa);
-+
-+      /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
-+      __phy_write(phydev, 0x11, 0x240);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x9680);
-+
-+      /* TrFreeze = 0 (mt7988 default) */
-+      __phy_write(phydev, 0x11, 0x0);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x9686);
-+
-+      /* SSTrKp100 = 5 */
-+      /* SSTrKf100 = 6 */
-+      /* SSTrKp1000Mas = 5 */
-+      /* SSTrKf1000Mas = 6 */
-+      /* SSTrKp1000Slv = 5 */
-+      /* SSTrKf1000Slv = 6 */
-+      __phy_write(phydev, 0x11, 0xbaef);
-+      __phy_write(phydev, 0x12, 0x2e);
-+      __phy_write(phydev, 0x10, 0x968c);
-+      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+}
-+
-+static void mt7981_phy_finetune(struct phy_device *phydev)
-+{
-+      u16 val[8] = { 0x01ce, 0x01c1,
-+                     0x020f, 0x0202,
-+                     0x03d0, 0x03c0,
-+                     0x0013, 0x0005 };
-+      int i, k;
-+
-+      /* 100M eye finetune:
-+       * Keep middle level of TX MLT3 shapper as default.
-+       * Only change TX MLT3 overshoot level here.
-+       */
-+      for (k = 0, i = 1; i < 12; i++) {
-+              if (i % 3 == 0)
-+                      continue;
-+              phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
-+      }
-+
-+      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-+      /* ResetSyncOffset = 6 */
-+      __phy_write(phydev, 0x11, 0x600);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x8fc0);
-+
-+      /* VgaDecRate = 1 */
-+      __phy_write(phydev, 0x11, 0x4c2a);
-+      __phy_write(phydev, 0x12, 0x3e);
-+      __phy_write(phydev, 0x10, 0x8fa4);
-+
-+      /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
-+       * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
-+       */
-+      __phy_write(phydev, 0x11, 0xd10a);
-+      __phy_write(phydev, 0x12, 0x34);
-+      __phy_write(phydev, 0x10, 0x8f82);
-+
-+      /* VcoSlicerThreshBitsHigh */
-+      __phy_write(phydev, 0x11, 0x5555);
-+      __phy_write(phydev, 0x12, 0x55);
-+      __phy_write(phydev, 0x10, 0x8ec0);
-+      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+
-+      /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
-+                     MTK_PHY_TR_OPEN_LOOP_EN_MASK |
-+                     MTK_PHY_LPF_X_AVERAGE_MASK,
-+                     BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
-+
-+      /* rg_tr_lpf_cnt_val = 512 */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
-+
-+      /* IIR2 related */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
-+
-+      /* FFE peaking */
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
-+                     MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
-+                     MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
-+
-+      /* Disable LDO pump */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
-+      /* Adjust LDO output voltage */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
-+}
-+
-+static void mt7988_phy_finetune(struct phy_device *phydev)
-+{
-+      u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
-+                      0x020d, 0x0206, 0x0384, 0x03d0,
-+                      0x03c6, 0x030a, 0x0011, 0x0005 };
-+      int i;
-+
-+      /* Set default MLT3 shaper first */
-+      for (i = 0; i < 12; i++)
-+              phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
-+
-+      /* TCT finetune */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
-+
-+      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-+      /* ResetSyncOffset = 5 */
-+      __phy_write(phydev, 0x11, 0x500);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x8fc0);
-+
-+      /* VgaDecRate is 1 at default on mt7988 */
-+
-+      /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
-+       * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
-+       */
-+      __phy_write(phydev, 0x11, 0xb90a);
-+      __phy_write(phydev, 0x12, 0x6f);
-+      __phy_write(phydev, 0x10, 0x8f82);
-+
-+      /* RemAckCntLimitCtrl = 1 */
-+      __phy_write(phydev, 0x11, 0xfbba);
-+      __phy_write(phydev, 0x12, 0xc3);
-+      __phy_write(phydev, 0x10, 0x87f8);
-+
-+      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+
-+      /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
-+                     MTK_PHY_TR_OPEN_LOOP_EN_MASK |
-+                     MTK_PHY_LPF_X_AVERAGE_MASK,
-+                     BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
-+
-+      /* rg_tr_lpf_cnt_val = 1023 */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
-+}
-+
-+static void mt798x_phy_eee(struct phy_device *phydev)
-+{
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,
-+                     MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |
-+                     MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,
-+                     FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |
-+                     FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
-+                     MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
-+                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
-+                                0xff));
-+
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                         MTK_PHY_RG_TESTMUX_ADC_CTRL,
-+                         MTK_PHY_RG_TXEN_DIG_MASK);
-+
-+      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                       MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);
-+
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-+                         MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,
-+                     MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |
-+                     MTK_PHY_LPI_SLV_SEND_TX_EN,
-+                     FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
-+
-+      /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
-+                         MTK_PHY_LPI_TXPCS_LOC_RCV);
-+
-+      /* This also fixes some IoT issues, such as CH340 */
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
-+                     MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
-+                     FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
-+                     FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,
-+                     MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
-+                     FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
-+                                0x33) |
-+                     MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |
-+                     MTK_PHY_LPI_VCO_EEE_STG0_EN);
-+
-+      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,
-+                       MTK_PHY_EEE_WAKE_MAS_INT_DC |
-+                       MTK_PHY_EEE_WAKE_SLV_INT_DC);
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,
-+                     MTK_PHY_SMI_DETCNT_MAX_MASK,
-+                     FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |
-+                     MTK_PHY_SMI_DET_MAX_EN);
-+
-+      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,
-+                       MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |
-+                       MTK_PHY_TREC_UPDATE_ENAB_CLR |
-+                       MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |
-+                       MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
-+
-+      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-+      /* Regsigdet_sel_1000 = 0 */
-+      __phy_write(phydev, 0x11, 0xb);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x9690);
-+
-+      /* REG_EEE_st2TrKf1000 = 2 */
-+      __phy_write(phydev, 0x11, 0x114f);
-+      __phy_write(phydev, 0x12, 0x2);
-+      __phy_write(phydev, 0x10, 0x969a);
-+
-+      /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
-+      __phy_write(phydev, 0x11, 0x3028);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x969e);
-+
-+      /* RegEEE_slv_wake_int_timer_tar = 8 */
-+      __phy_write(phydev, 0x11, 0x5010);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x96a0);
-+
-+      /* RegEEE_trfreeze_timer2 = 586 */
-+      __phy_write(phydev, 0x11, 0x24a);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x96a8);
-+
-+      /* RegEEE100Stg1_tar = 16 */
-+      __phy_write(phydev, 0x11, 0x3210);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x96b8);
-+
-+      /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
-+      __phy_write(phydev, 0x11, 0x1463);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x96ca);
-+
-+      /* DfeTailEnableVgaThresh1000 = 27 */
-+      __phy_write(phydev, 0x11, 0x36);
-+      __phy_write(phydev, 0x12, 0x0);
-+      __phy_write(phydev, 0x10, 0x8f80);
-+      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+
-+      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
-+      __phy_modify(phydev, MTK_PHY_LPI_REG_14,
-+                   MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
-+                   FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
-+
-+      __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
-+                   FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));
-+      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
-+                     MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
-+                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
-+                                0xff));
-+}
-+
-+static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
-+                u8 start_pair, u8 end_pair)
-+{
-+      u8 pair_n;
-+      int ret;
-+
-+      for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
-+              /* TX_OFFSET & TX_AMP have no SW calibration. */
-+              switch (cal_item) {
-+              case TX_VCM:
-+                      ret = tx_vcm_cal_sw(phydev, pair_n);
-+                      break;
-+              default:
-+                      return -EINVAL;
-+              }
-+              if (ret)
-+                      return ret;
-+      }
-+      return 0;
-+}
-+
-+static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
-+                   u8 start_pair, u8 end_pair, u32 *buf)
-+{
-+      u8 pair_n;
-+      int ret;
-+
-+      for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
-+              /* TX_VCM has no efuse calibration. */
-+              switch (cal_item) {
-+              case REXT:
-+                      ret = rext_cal_efuse(phydev, buf);
-+                      break;
-+              case TX_OFFSET:
-+                      ret = tx_offset_cal_efuse(phydev, buf);
-+                      break;
-+              case TX_AMP:
-+                      ret = tx_amp_cal_efuse(phydev, buf);
-+                      break;
-+              case TX_R50:
-+                      ret = tx_r50_cal_efuse(phydev, buf, pair_n);
-+                      break;
-+              default:
-+                      return -EINVAL;
-+              }
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
-+                   enum CAL_MODE cal_mode, u8 start_pair,
-+                   u8 end_pair, u32 *buf)
-+{
-+      int ret;
-+
-+      switch (cal_mode) {
-+      case EFUSE_M:
-+              ret = cal_efuse(phydev, cal_item, start_pair,
-+                              end_pair, buf);
-+              break;
-+      case SW_M:
-+              ret = cal_sw(phydev, cal_item, start_pair, end_pair);
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      if (ret) {
-+              phydev_err(phydev, "cal %d failed\n", cal_item);
-+              return -EIO;
-+      }
-+
-+      return 0;
-+}
-+
-+static int mt798x_phy_calibration(struct phy_device *phydev)
-+{
-+      struct nvmem_cell *cell;
-+      int ret = 0;
-+      size_t len;
-+      u32 *buf;
-+
-+      cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
-+      if (IS_ERR(cell)) {
-+              if (PTR_ERR(cell) == -EPROBE_DEFER)
-+                      return PTR_ERR(cell);
-+              return 0;
-+      }
-+
-+      buf = (u32 *)nvmem_cell_read(cell, &len);
-+      if (IS_ERR(buf))
-+              return PTR_ERR(buf);
-+      nvmem_cell_put(cell);
-+
-+      if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
-+              phydev_err(phydev, "invalid efuse data\n");
-+              ret = -EINVAL;
-+              goto out;
-+      }
-+
-+      ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
-+      if (ret)
-+              goto out;
-+      ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
-+      if (ret)
-+              goto out;
-+      ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
-+      if (ret)
-+              goto out;
-+      ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
-+      if (ret)
-+              goto out;
-+      ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
-+      if (ret)
-+              goto out;
-+
-+out:
-+      kfree(buf);
-+      return ret;
-+}
-+
-+static int mt798x_phy_config_init(struct phy_device *phydev)
-+{
-+      switch (phydev->drv->phy_id) {
-+      case MTK_GPHY_ID_MT7981:
-+              mt7981_phy_finetune(phydev);
-+              break;
-+      case MTK_GPHY_ID_MT7988:
-+              mt7988_phy_finetune(phydev);
-+              break;
-+      }
-+
-+      mt798x_phy_common_finetune(phydev);
-+      mt798x_phy_eee(phydev);
-+
-+      return mt798x_phy_calibration(phydev);
-+}
-+
-+static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
-+                                  bool on)
-+{
-+      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
-+      struct mtk_socphy_priv *priv = phydev->priv;
-+      bool changed;
-+
-+      if (on)
-+              changed = !test_and_set_bit(bit_on, &priv->led_state);
-+      else
-+              changed = !!test_and_clear_bit(bit_on, &priv->led_state);
-+
-+      changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
-+                                      (index ? 16 : 0), &priv->led_state);
-+      if (changed)
-+              return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                                    MTK_PHY_LED1_ON_CTRL :
-+                                    MTK_PHY_LED0_ON_CTRL,
-+                                    MTK_PHY_LED_ON_MASK,
-+                                    on ? MTK_PHY_LED_ON_FORCE_ON : 0);
-+      else
-+              return 0;
-+}
-+
-+static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
-+                                     bool blinking)
-+{
-+      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
-+                               (index ? 16 : 0);
-+      struct mtk_socphy_priv *priv = phydev->priv;
-+      bool changed;
-+
-+      if (blinking)
-+              changed = !test_and_set_bit(bit_blink, &priv->led_state);
-+      else
-+              changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
-+
-+      changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
-+                            (index ? 16 : 0), &priv->led_state);
-+      if (changed)
-+              return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                                   MTK_PHY_LED1_BLINK_CTRL :
-+                                   MTK_PHY_LED0_BLINK_CTRL,
-+                                   blinking ?
-+                                   MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
-+      else
-+              return 0;
-+}
-+
-+static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
-+                                  unsigned long *delay_on,
-+                                  unsigned long *delay_off)
-+{
-+      bool blinking = false;
-+      int err = 0;
-+
-+      if (index > 1)
-+              return -EINVAL;
-+
-+      if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
-+              blinking = true;
-+              *delay_on = 50;
-+              *delay_off = 50;
-+      }
-+
-+      err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
-+      if (err)
-+              return err;
-+
-+      return mt798x_phy_hw_led_on_set(phydev, index, false);
-+}
-+
-+static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
-+                                       u8 index, enum led_brightness value)
-+{
-+      int err;
-+
-+      err = mt798x_phy_hw_led_blink_set(phydev, index, false);
-+      if (err)
-+              return err;
-+
-+      return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
-+}
-+
-+static const unsigned long supported_triggers =
-+      BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
-+      BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
-+      BIT(TRIGGER_NETDEV_LINK)        |
-+      BIT(TRIGGER_NETDEV_LINK_10)     |
-+      BIT(TRIGGER_NETDEV_LINK_100)    |
-+      BIT(TRIGGER_NETDEV_LINK_1000)   |
-+      BIT(TRIGGER_NETDEV_RX)          |
-+      BIT(TRIGGER_NETDEV_TX);
-+
-+static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+                                        unsigned long rules)
-+{
-+      if (index > 1)
-+              return -EINVAL;
-+
-+      /* All combinations of the supported triggers are allowed */
-+      if (rules & ~supported_triggers)
-+              return -EOPNOTSUPP;
-+
-+      return 0;
-+};
-+
-+static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
-+                                       unsigned long *rules)
-+{
-+      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
-+                               (index ? 16 : 0);
-+      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
-+      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
-+      struct mtk_socphy_priv *priv = phydev->priv;
-+      int on, blink;
-+
-+      if (index > 1)
-+              return -EINVAL;
-+
-+      on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
-+                        index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
-+
-+      if (on < 0)
-+              return -EIO;
-+
-+      blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
-+                           index ? MTK_PHY_LED1_BLINK_CTRL :
-+                                   MTK_PHY_LED0_BLINK_CTRL);
-+      if (blink < 0)
-+              return -EIO;
-+
-+      if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX |
-+                 MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) ||
-+          (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
-+              set_bit(bit_netdev, &priv->led_state);
-+      else
-+              clear_bit(bit_netdev, &priv->led_state);
-+
-+      if (on & MTK_PHY_LED_ON_FORCE_ON)
-+              set_bit(bit_on, &priv->led_state);
-+      else
-+              clear_bit(bit_on, &priv->led_state);
-+
-+      if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
-+              set_bit(bit_blink, &priv->led_state);
-+      else
-+              clear_bit(bit_blink, &priv->led_state);
-+
-+      if (!rules)
-+              return 0;
-+
-+      if (on & MTK_PHY_LED_ON_LINK)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK);
-+
-+      if (on & MTK_PHY_LED_ON_LINK10)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_10);
-+
-+      if (on & MTK_PHY_LED_ON_LINK100)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_100);
-+
-+      if (on & MTK_PHY_LED_ON_LINK1000)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
-+
-+      if (on & MTK_PHY_LED_ON_FDX)
-+              *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
-+
-+      if (on & MTK_PHY_LED_ON_HDX)
-+              *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
-+
-+      if (blink & MTK_PHY_LED_BLINK_RX)
-+              *rules |= BIT(TRIGGER_NETDEV_RX);
-+
-+      if (blink & MTK_PHY_LED_BLINK_TX)
-+              *rules |= BIT(TRIGGER_NETDEV_TX);
-+
-+      return 0;
-+};
-+
-+static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
-+                                       unsigned long rules)
-+{
-+      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
-+      struct mtk_socphy_priv *priv = phydev->priv;
-+      u16 on = 0, blink = 0;
-+      int ret;
-+
-+      if (index > 1)
-+              return -EINVAL;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
-+              on |= MTK_PHY_LED_ON_FDX;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
-+              on |= MTK_PHY_LED_ON_HDX;
-+
-+      if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
-+              on |= MTK_PHY_LED_ON_LINK10;
-+
-+      if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
-+              on |= MTK_PHY_LED_ON_LINK100;
-+
-+      if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
-+              on |= MTK_PHY_LED_ON_LINK1000;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_RX)) {
-+              blink |= (on & MTK_PHY_LED_ON_LINK) ?
-+                        (((on & MTK_PHY_LED_ON_LINK10) ?
-+                          MTK_PHY_LED_BLINK_10RX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK100) ?
-+                          MTK_PHY_LED_BLINK_100RX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK1000) ?
-+                          MTK_PHY_LED_BLINK_1000RX : 0)) :
-+                        MTK_PHY_LED_BLINK_RX;
-+      }
-+
-+      if (rules & BIT(TRIGGER_NETDEV_TX)) {
-+              blink |= (on & MTK_PHY_LED_ON_LINK) ?
-+                        (((on & MTK_PHY_LED_ON_LINK10) ?
-+                          MTK_PHY_LED_BLINK_10TX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK100) ?
-+                          MTK_PHY_LED_BLINK_100TX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK1000) ?
-+                          MTK_PHY_LED_BLINK_1000TX : 0)) :
-+                        MTK_PHY_LED_BLINK_TX;
-+      }
-+
-+      if (blink || on)
-+              set_bit(bit_netdev, &priv->led_state);
-+      else
-+              clear_bit(bit_netdev, &priv->led_state);
-+
-+      ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                              MTK_PHY_LED1_ON_CTRL :
-+                              MTK_PHY_LED0_ON_CTRL,
-+                           MTK_PHY_LED_ON_FDX     |
-+                           MTK_PHY_LED_ON_HDX     |
-+                           MTK_PHY_LED_ON_LINK,
-+                           on);
-+
-+      if (ret)
-+              return ret;
-+
-+      return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                              MTK_PHY_LED1_BLINK_CTRL :
-+                              MTK_PHY_LED0_BLINK_CTRL, blink);
-+};
-+
-+static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
-+{
-+      struct mtk_socphy_shared *priv = phydev->shared->priv;
-+      u32 polarities;
-+
-+      if (led_num == 0)
-+              polarities = ~(priv->boottrap);
-+      else
-+              polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
-+
-+      if (polarities & BIT(phydev->mdio.addr))
-+              return true;
-+
-+      return false;
-+}
-+
-+static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
-+{
-+      struct pinctrl *pinctrl;
-+      int index;
-+
-+      /* Setup LED polarity according to bootstrap use of LED pins */
-+      for (index = 0; index < 2; ++index)
-+              phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                              MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
-+                             MTK_PHY_LED_ON_POLARITY,
-+                             mt7988_phy_led_get_polarity(phydev, index) ?
-+                              MTK_PHY_LED_ON_POLARITY : 0);
-+
-+      /* Only now setup pinctrl to avoid bogus blinking */
-+      pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
-+      if (IS_ERR(pinctrl))
-+              dev_err(&phydev->mdio.bus->dev,
-+                      "Failed to setup PHY LED pinctrl\n");
-+
-+      return 0;
-+}
-+
-+static int mt7988_phy_probe_shared(struct phy_device *phydev)
-+{
-+      struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
-+      struct mtk_socphy_shared *shared = phydev->shared->priv;
-+      struct regmap *regmap;
-+      u32 reg;
-+      int ret;
-+
-+      /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
-+       * LED_C and LED_D respectively. At the same time those pins are used to
-+       * bootstrap configuration of the reference clock source (LED_A),
-+       * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
-+       * In practice this is done using a LED and a resistor pulling the pin
-+       * either to GND or to VIO.
-+       * The detected value at boot time is accessible at run-time using the
-+       * TPBANK0 register located in the gpio base of the pinctrl, in order
-+       * to read it here it needs to be referenced by a phandle called
-+       * 'mediatek,pio' in the MDIO bus hosting the PHY.
-+       * The 4 bits in TPBANK0 are kept as package shared data and are used to
-+       * set LED polarity for each of the LED0.
-+       */
-+      regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
-+      if (IS_ERR(regmap))
-+              return PTR_ERR(regmap);
-+
-+      ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
-+      if (ret)
-+              return ret;
-+
-+      shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
-+
-+      return 0;
-+}
-+
-+static void mt798x_phy_leds_state_init(struct phy_device *phydev)
-+{
-+      int i;
-+
-+      for (i = 0; i < 2; ++i)
-+              mt798x_phy_led_hw_control_get(phydev, i, NULL);
-+}
-+
-+static int mt7988_phy_probe(struct phy_device *phydev)
-+{
-+      struct mtk_socphy_shared *shared;
-+      struct mtk_socphy_priv *priv;
-+      int err;
-+
-+      if (phydev->mdio.addr > 3)
-+              return -EINVAL;
-+
-+      err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
-+                                  sizeof(struct mtk_socphy_shared));
-+      if (err)
-+              return err;
-+
-+      if (phy_package_probe_once(phydev)) {
-+              err = mt7988_phy_probe_shared(phydev);
-+              if (err)
-+                      return err;
-+      }
-+
-+      shared = phydev->shared->priv;
-+      priv = &shared->priv[phydev->mdio.addr];
-+
-+      phydev->priv = priv;
-+
-+      mt798x_phy_leds_state_init(phydev);
-+
-+      err = mt7988_phy_fix_leds_polarities(phydev);
-+      if (err)
-+              return err;
-+
-+      /* Disable TX power saving at probing to:
-+       * 1. Meet common mode compliance test criteria
-+       * 2. Make sure that TX-VCM calibration works fine
-+       */
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
-+                     MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
-+
-+      return mt798x_phy_calibration(phydev);
-+}
-+
-+static int mt7981_phy_probe(struct phy_device *phydev)
-+{
-+      struct mtk_socphy_priv *priv;
-+
-+      priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
-+                          GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+
-+      phydev->priv = priv;
-+
-+      mt798x_phy_leds_state_init(phydev);
-+
-+      return mt798x_phy_calibration(phydev);
-+}
-+
-+static struct phy_driver mtk_socphy_driver[] = {
-+      {
-+              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
-+              .name           = "MediaTek MT7981 PHY",
-+              .config_init    = mt798x_phy_config_init,
-+              .config_intr    = genphy_no_config_intr,
-+              .handle_interrupt = genphy_handle_interrupt_no_ack,
-+              .probe          = mt7981_phy_probe,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = mtk_socphy_read_page,
-+              .write_page     = mtk_socphy_write_page,
-+              .led_blink_set  = mt798x_phy_led_blink_set,
-+              .led_brightness_set = mt798x_phy_led_brightness_set,
-+              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
-+              .led_hw_control_set = mt798x_phy_led_hw_control_set,
-+              .led_hw_control_get = mt798x_phy_led_hw_control_get,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
-+              .name           = "MediaTek MT7988 PHY",
-+              .config_init    = mt798x_phy_config_init,
-+              .config_intr    = genphy_no_config_intr,
-+              .handle_interrupt = genphy_handle_interrupt_no_ack,
-+              .probe          = mt7988_phy_probe,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = mtk_socphy_read_page,
-+              .write_page     = mtk_socphy_write_page,
-+              .led_blink_set  = mt798x_phy_led_blink_set,
-+              .led_brightness_set = mt798x_phy_led_brightness_set,
-+              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
-+              .led_hw_control_set = mt798x_phy_led_hw_control_set,
-+              .led_hw_control_get = mt798x_phy_led_hw_control_get,
-+      },
-+};
-+
-+module_phy_driver(mtk_socphy_driver);
-+
-+static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
-+      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
-+      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
-+      { }
-+};
-+
-+MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver");
-+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
-+MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);
---- /dev/null
-+++ b/drivers/net/phy/mediatek/mtk-ge.c
-@@ -0,0 +1,111 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+#include <linux/bitfield.h>
-+#include <linux/module.h>
-+#include <linux/phy.h>
-+
-+#define MTK_EXT_PAGE_ACCESS           0x1f
-+#define MTK_PHY_PAGE_STANDARD         0x0000
-+#define MTK_PHY_PAGE_EXTENDED         0x0001
-+#define MTK_PHY_PAGE_EXTENDED_2               0x0002
-+#define MTK_PHY_PAGE_EXTENDED_3               0x0003
-+#define MTK_PHY_PAGE_EXTENDED_2A30    0x2a30
-+#define MTK_PHY_PAGE_EXTENDED_52B5    0x52b5
-+
-+static int mtk_gephy_read_page(struct phy_device *phydev)
-+{
-+      return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
-+}
-+
-+static int mtk_gephy_write_page(struct phy_device *phydev, int page)
-+{
-+      return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
-+}
-+
-+static void mtk_gephy_config_init(struct phy_device *phydev)
-+{
-+      /* Enable HW auto downshift */
-+      phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
-+
-+      /* Increase SlvDPSready time */
-+      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-+      __phy_write(phydev, 0x10, 0xafae);
-+      __phy_write(phydev, 0x12, 0x2f);
-+      __phy_write(phydev, 0x10, 0x8fae);
-+      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+
-+      /* Adjust 100_mse_threshold */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
-+
-+      /* Disable mcc */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
-+}
-+
-+static int mt7530_phy_config_init(struct phy_device *phydev)
-+{
-+      mtk_gephy_config_init(phydev);
-+
-+      /* Increase post_update_timer */
-+      phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
-+
-+      return 0;
-+}
-+
-+static int mt7531_phy_config_init(struct phy_device *phydev)
-+{
-+      mtk_gephy_config_init(phydev);
-+
-+      /* PHY link down power saving enable */
-+      phy_set_bits(phydev, 0x17, BIT(4));
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
-+
-+      /* Set TX Pair delay selection */
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
-+      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
-+
-+      return 0;
-+}
-+
-+static struct phy_driver mtk_gephy_driver[] = {
-+      {
-+              PHY_ID_MATCH_EXACT(0x03a29412),
-+              .name           = "MediaTek MT7530 PHY",
-+              .config_init    = mt7530_phy_config_init,
-+              /* Interrupts are handled by the switch, not the PHY
-+               * itself.
-+               */
-+              .config_intr    = genphy_no_config_intr,
-+              .handle_interrupt = genphy_handle_interrupt_no_ack,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = mtk_gephy_read_page,
-+              .write_page     = mtk_gephy_write_page,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(0x03a29441),
-+              .name           = "MediaTek MT7531 PHY",
-+              .config_init    = mt7531_phy_config_init,
-+              /* Interrupts are handled by the switch, not the PHY
-+               * itself.
-+               */
-+              .config_intr    = genphy_no_config_intr,
-+              .handle_interrupt = genphy_handle_interrupt_no_ack,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = mtk_gephy_read_page,
-+              .write_page     = mtk_gephy_write_page,
-+      },
-+};
-+
-+module_phy_driver(mtk_gephy_driver);
-+
-+static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
-+      { PHY_ID_MATCH_EXACT(0x03a29441) },
-+      { PHY_ID_MATCH_EXACT(0x03a29412) },
-+      { }
-+};
-+
-+MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
-+MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);
diff --git a/target/linux/generic/backport-6.18/720-05-v6.13-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch b/target/linux/generic/backport-6.18/720-05-v6.13-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch
deleted file mode 100644 (file)
index 63407ac..0000000
+++ /dev/null
@@ -1,774 +0,0 @@
-From 71d88c7409b91c853d7f9c933f5e27933d656e5e Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Sat, 9 Nov 2024 00:34:52 +0800
-Subject: [PATCH 05/20] net: phy: mediatek: Move LED helper functions into mtk
- phy lib
-
-This patch creates mtk-phy-lib.c & mtk-phy.h and integrates mtk-ge-soc.c's
-LED helper functions so that we can use those helper functions in other
-MTK's ethernet phy driver.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- MAINTAINERS                            |   2 +
- drivers/net/phy/mediatek/Kconfig       |   4 +
- drivers/net/phy/mediatek/Makefile      |   1 +
- drivers/net/phy/mediatek/mtk-ge-soc.c  | 280 +++----------------------
- drivers/net/phy/mediatek/mtk-phy-lib.c | 254 ++++++++++++++++++++++
- drivers/net/phy/mediatek/mtk.h         |  86 ++++++++
- 6 files changed, 372 insertions(+), 255 deletions(-)
- create mode 100644 drivers/net/phy/mediatek/mtk-phy-lib.c
- create mode 100644 drivers/net/phy/mediatek/mtk.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -14428,7 +14428,9 @@ M:     SkyLake Huang <SkyLake.Huang@mediatek
- L:    netdev@vger.kernel.org
- S:    Maintained
- F:    drivers/net/phy/mediatek/mtk-ge-soc.c
-+F:    drivers/net/phy/mediatek/mtk-phy-lib.c
- F:    drivers/net/phy/mediatek/mtk-ge.c
-+F:    drivers/net/phy/mediatek/mtk.h
- F:    drivers/phy/mediatek/phy-mtk-xfi-tphy.c
- MEDIATEK I2C CONTROLLER DRIVER
---- a/drivers/net/phy/mediatek/Kconfig
-+++ b/drivers/net/phy/mediatek/Kconfig
-@@ -1,4 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0-only
-+config MTK_NET_PHYLIB
-+      tristate
-+
- config MEDIATEK_GE_PHY
-       tristate "MediaTek Gigabit Ethernet PHYs"
-       help
-@@ -13,6 +16,7 @@ config MEDIATEK_GE_SOC_PHY
-       tristate "MediaTek SoC Ethernet PHYs"
-       depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
-       depends on NVMEM_MTK_EFUSE
-+      select MTK_NET_PHYLIB
-       help
-         Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
---- a/drivers/net/phy/mediatek/Makefile
-+++ b/drivers/net/phy/mediatek/Makefile
-@@ -1,3 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_MTK_NET_PHYLIB)          += mtk-phy-lib.o
- obj-$(CONFIG_MEDIATEK_GE_PHY)         += mtk-ge.o
- obj-$(CONFIG_MEDIATEK_GE_SOC_PHY)     += mtk-ge-soc.o
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -8,6 +8,8 @@
- #include <linux/phy.h>
- #include <linux/regmap.h>
-+#include "mtk.h"
-+
- #define MTK_GPHY_ID_MT7981                    0x03a29461
- #define MTK_GPHY_ID_MT7988                    0x03a29481
-@@ -210,41 +212,6 @@
- #define MTK_PHY_DA_TX_R50_PAIR_D              0x540
- /* Registers on MDIO_MMD_VEND2 */
--#define MTK_PHY_LED0_ON_CTRL                  0x24
--#define MTK_PHY_LED1_ON_CTRL                  0x26
--#define   MTK_PHY_LED_ON_MASK                 GENMASK(6, 0)
--#define   MTK_PHY_LED_ON_LINK1000             BIT(0)
--#define   MTK_PHY_LED_ON_LINK100              BIT(1)
--#define   MTK_PHY_LED_ON_LINK10                       BIT(2)
--#define   MTK_PHY_LED_ON_LINK                 (MTK_PHY_LED_ON_LINK10 |\
--                                               MTK_PHY_LED_ON_LINK100 |\
--                                               MTK_PHY_LED_ON_LINK1000)
--#define   MTK_PHY_LED_ON_LINKDOWN             BIT(3)
--#define   MTK_PHY_LED_ON_FDX                  BIT(4) /* Full duplex */
--#define   MTK_PHY_LED_ON_HDX                  BIT(5) /* Half duplex */
--#define   MTK_PHY_LED_ON_FORCE_ON             BIT(6)
--#define   MTK_PHY_LED_ON_POLARITY             BIT(14)
--#define   MTK_PHY_LED_ON_ENABLE                       BIT(15)
--
--#define MTK_PHY_LED0_BLINK_CTRL                       0x25
--#define MTK_PHY_LED1_BLINK_CTRL                       0x27
--#define   MTK_PHY_LED_BLINK_1000TX            BIT(0)
--#define   MTK_PHY_LED_BLINK_1000RX            BIT(1)
--#define   MTK_PHY_LED_BLINK_100TX             BIT(2)
--#define   MTK_PHY_LED_BLINK_100RX             BIT(3)
--#define   MTK_PHY_LED_BLINK_10TX              BIT(4)
--#define   MTK_PHY_LED_BLINK_10RX              BIT(5)
--#define   MTK_PHY_LED_BLINK_RX                        (MTK_PHY_LED_BLINK_10RX |\
--                                               MTK_PHY_LED_BLINK_100RX |\
--                                               MTK_PHY_LED_BLINK_1000RX)
--#define   MTK_PHY_LED_BLINK_TX                        (MTK_PHY_LED_BLINK_10TX |\
--                                               MTK_PHY_LED_BLINK_100TX |\
--                                               MTK_PHY_LED_BLINK_1000TX)
--#define   MTK_PHY_LED_BLINK_COLLISION         BIT(6)
--#define   MTK_PHY_LED_BLINK_RX_CRC_ERR                BIT(7)
--#define   MTK_PHY_LED_BLINK_RX_IDLE_ERR               BIT(8)
--#define   MTK_PHY_LED_BLINK_FORCE_BLINK               BIT(9)
--
- #define MTK_PHY_LED1_DEFAULT_POLARITIES               BIT(1)
- #define MTK_PHY_RG_BG_RASEL                   0x115
-@@ -299,14 +266,6 @@ enum CAL_MODE {
-       SW_M
- };
--#define MTK_PHY_LED_STATE_FORCE_ON    0
--#define MTK_PHY_LED_STATE_FORCE_BLINK 1
--#define MTK_PHY_LED_STATE_NETDEV      2
--
--struct mtk_socphy_priv {
--      unsigned long           led_state;
--};
--
- struct mtk_socphy_shared {
-       u32                     boottrap;
-       struct mtk_socphy_priv  priv[4];
-@@ -1172,76 +1131,23 @@ static int mt798x_phy_config_init(struct
-       return mt798x_phy_calibration(phydev);
- }
--static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
--                                  bool on)
--{
--      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
--      struct mtk_socphy_priv *priv = phydev->priv;
--      bool changed;
--
--      if (on)
--              changed = !test_and_set_bit(bit_on, &priv->led_state);
--      else
--              changed = !!test_and_clear_bit(bit_on, &priv->led_state);
--
--      changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
--                                      (index ? 16 : 0), &priv->led_state);
--      if (changed)
--              return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
--                                    MTK_PHY_LED1_ON_CTRL :
--                                    MTK_PHY_LED0_ON_CTRL,
--                                    MTK_PHY_LED_ON_MASK,
--                                    on ? MTK_PHY_LED_ON_FORCE_ON : 0);
--      else
--              return 0;
--}
--
--static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
--                                     bool blinking)
--{
--      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
--                               (index ? 16 : 0);
--      struct mtk_socphy_priv *priv = phydev->priv;
--      bool changed;
--
--      if (blinking)
--              changed = !test_and_set_bit(bit_blink, &priv->led_state);
--      else
--              changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
--
--      changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
--                            (index ? 16 : 0), &priv->led_state);
--      if (changed)
--              return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
--                                   MTK_PHY_LED1_BLINK_CTRL :
--                                   MTK_PHY_LED0_BLINK_CTRL,
--                                   blinking ?
--                                   MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
--      else
--              return 0;
--}
--
- static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
-                                   unsigned long *delay_on,
-                                   unsigned long *delay_off)
- {
-       bool blinking = false;
--      int err = 0;
--
--      if (index > 1)
--              return -EINVAL;
-+      int err;
--      if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
--              blinking = true;
--              *delay_on = 50;
--              *delay_off = 50;
--      }
-+      err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking);
-+      if (err < 0)
-+              return err;
--      err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
-+      err = mtk_phy_hw_led_blink_set(phydev, index, blinking);
-       if (err)
-               return err;
--      return mt798x_phy_hw_led_on_set(phydev, index, false);
-+      return mtk_phy_hw_led_on_set(phydev, index, MTK_GPHY_LED_ON_MASK,
-+                                   false);
- }
- static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
-@@ -1249,11 +1155,12 @@ static int mt798x_phy_led_brightness_set
- {
-       int err;
--      err = mt798x_phy_hw_led_blink_set(phydev, index, false);
-+      err = mtk_phy_hw_led_blink_set(phydev, index, false);
-       if (err)
-               return err;
--      return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
-+      return mtk_phy_hw_led_on_set(phydev, index, MTK_GPHY_LED_ON_MASK,
-+                                   (value != LED_OFF));
- }
- static const unsigned long supported_triggers =
-@@ -1269,155 +1176,26 @@ static const unsigned long supported_tri
- static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-                                         unsigned long rules)
- {
--      if (index > 1)
--              return -EINVAL;
--
--      /* All combinations of the supported triggers are allowed */
--      if (rules & ~supported_triggers)
--              return -EOPNOTSUPP;
--
--      return 0;
--};
-+      return mtk_phy_led_hw_is_supported(phydev, index, rules,
-+                                         supported_triggers);
-+}
- static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
-                                        unsigned long *rules)
- {
--      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
--                               (index ? 16 : 0);
--      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
--      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
--      struct mtk_socphy_priv *priv = phydev->priv;
--      int on, blink;
--
--      if (index > 1)
--              return -EINVAL;
--
--      on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
--                        index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
--
--      if (on < 0)
--              return -EIO;
--
--      blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
--                           index ? MTK_PHY_LED1_BLINK_CTRL :
--                                   MTK_PHY_LED0_BLINK_CTRL);
--      if (blink < 0)
--              return -EIO;
--
--      if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX |
--                 MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) ||
--          (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
--              set_bit(bit_netdev, &priv->led_state);
--      else
--              clear_bit(bit_netdev, &priv->led_state);
--
--      if (on & MTK_PHY_LED_ON_FORCE_ON)
--              set_bit(bit_on, &priv->led_state);
--      else
--              clear_bit(bit_on, &priv->led_state);
--
--      if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
--              set_bit(bit_blink, &priv->led_state);
--      else
--              clear_bit(bit_blink, &priv->led_state);
--
--      if (!rules)
--              return 0;
--
--      if (on & MTK_PHY_LED_ON_LINK)
--              *rules |= BIT(TRIGGER_NETDEV_LINK);
--
--      if (on & MTK_PHY_LED_ON_LINK10)
--              *rules |= BIT(TRIGGER_NETDEV_LINK_10);
--
--      if (on & MTK_PHY_LED_ON_LINK100)
--              *rules |= BIT(TRIGGER_NETDEV_LINK_100);
--
--      if (on & MTK_PHY_LED_ON_LINK1000)
--              *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
--
--      if (on & MTK_PHY_LED_ON_FDX)
--              *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
--
--      if (on & MTK_PHY_LED_ON_HDX)
--              *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
--
--      if (blink & MTK_PHY_LED_BLINK_RX)
--              *rules |= BIT(TRIGGER_NETDEV_RX);
--
--      if (blink & MTK_PHY_LED_BLINK_TX)
--              *rules |= BIT(TRIGGER_NETDEV_TX);
--
--      return 0;
-+      return mtk_phy_led_hw_ctrl_get(phydev, index, rules,
-+                                     MTK_GPHY_LED_ON_SET,
-+                                     MTK_GPHY_LED_RX_BLINK_SET,
-+                                     MTK_GPHY_LED_TX_BLINK_SET);
- };
- static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
-                                        unsigned long rules)
- {
--      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
--      struct mtk_socphy_priv *priv = phydev->priv;
--      u16 on = 0, blink = 0;
--      int ret;
--
--      if (index > 1)
--              return -EINVAL;
--
--      if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
--              on |= MTK_PHY_LED_ON_FDX;
--
--      if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
--              on |= MTK_PHY_LED_ON_HDX;
--
--      if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
--              on |= MTK_PHY_LED_ON_LINK10;
--
--      if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
--              on |= MTK_PHY_LED_ON_LINK100;
--
--      if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
--              on |= MTK_PHY_LED_ON_LINK1000;
--
--      if (rules & BIT(TRIGGER_NETDEV_RX)) {
--              blink |= (on & MTK_PHY_LED_ON_LINK) ?
--                        (((on & MTK_PHY_LED_ON_LINK10) ?
--                          MTK_PHY_LED_BLINK_10RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK100) ?
--                          MTK_PHY_LED_BLINK_100RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK1000) ?
--                          MTK_PHY_LED_BLINK_1000RX : 0)) :
--                        MTK_PHY_LED_BLINK_RX;
--      }
--
--      if (rules & BIT(TRIGGER_NETDEV_TX)) {
--              blink |= (on & MTK_PHY_LED_ON_LINK) ?
--                        (((on & MTK_PHY_LED_ON_LINK10) ?
--                          MTK_PHY_LED_BLINK_10TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK100) ?
--                          MTK_PHY_LED_BLINK_100TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK1000) ?
--                          MTK_PHY_LED_BLINK_1000TX : 0)) :
--                        MTK_PHY_LED_BLINK_TX;
--      }
--
--      if (blink || on)
--              set_bit(bit_netdev, &priv->led_state);
--      else
--              clear_bit(bit_netdev, &priv->led_state);
--
--      ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
--                              MTK_PHY_LED1_ON_CTRL :
--                              MTK_PHY_LED0_ON_CTRL,
--                           MTK_PHY_LED_ON_FDX     |
--                           MTK_PHY_LED_ON_HDX     |
--                           MTK_PHY_LED_ON_LINK,
--                           on);
--
--      if (ret)
--              return ret;
--
--      return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
--                              MTK_PHY_LED1_BLINK_CTRL :
--                              MTK_PHY_LED0_BLINK_CTRL, blink);
-+      return mtk_phy_led_hw_ctrl_set(phydev, index, rules,
-+                                     MTK_GPHY_LED_ON_SET,
-+                                     MTK_GPHY_LED_RX_BLINK_SET,
-+                                     MTK_GPHY_LED_TX_BLINK_SET);
- };
- static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
-@@ -1492,14 +1270,6 @@ static int mt7988_phy_probe_shared(struc
-       return 0;
- }
--static void mt798x_phy_leds_state_init(struct phy_device *phydev)
--{
--      int i;
--
--      for (i = 0; i < 2; ++i)
--              mt798x_phy_led_hw_control_get(phydev, i, NULL);
--}
--
- static int mt7988_phy_probe(struct phy_device *phydev)
- {
-       struct mtk_socphy_shared *shared;
-@@ -1525,7 +1295,7 @@ static int mt7988_phy_probe(struct phy_d
-       phydev->priv = priv;
--      mt798x_phy_leds_state_init(phydev);
-+      mtk_phy_leds_state_init(phydev);
-       err = mt7988_phy_fix_leds_polarities(phydev);
-       if (err)
-@@ -1552,7 +1322,7 @@ static int mt7981_phy_probe(struct phy_d
-       phydev->priv = priv;
--      mt798x_phy_leds_state_init(phydev);
-+      mtk_phy_leds_state_init(phydev);
-       return mt798x_phy_calibration(phydev);
- }
---- /dev/null
-+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
-@@ -0,0 +1,254 @@
-+// SPDX-License-Identifier: GPL-2.0
-+#include <linux/phy.h>
-+#include <linux/module.h>
-+
-+#include <linux/netdevice.h>
-+
-+#include "mtk.h"
-+
-+int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+                              unsigned long rules,
-+                              unsigned long supported_triggers)
-+{
-+      if (index > 1)
-+              return -EINVAL;
-+
-+      /* All combinations of the supported triggers are allowed */
-+      if (rules & ~supported_triggers)
-+              return -EOPNOTSUPP;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_is_supported);
-+
-+int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index,
-+                          unsigned long *rules, u16 on_set,
-+                          u16 rx_blink_set, u16 tx_blink_set)
-+{
-+      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
-+                               (index ? 16 : 0);
-+      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
-+      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
-+      struct mtk_socphy_priv *priv = phydev->priv;
-+      int on, blink;
-+
-+      if (index > 1)
-+              return -EINVAL;
-+
-+      on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
-+                        index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
-+
-+      if (on < 0)
-+              return -EIO;
-+
-+      blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
-+                           index ? MTK_PHY_LED1_BLINK_CTRL :
-+                                   MTK_PHY_LED0_BLINK_CTRL);
-+      if (blink < 0)
-+              return -EIO;
-+
-+      if ((on & (on_set | MTK_PHY_LED_ON_FDX |
-+                 MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) ||
-+          (blink & (rx_blink_set | tx_blink_set)))
-+              set_bit(bit_netdev, &priv->led_state);
-+      else
-+              clear_bit(bit_netdev, &priv->led_state);
-+
-+      if (on & MTK_PHY_LED_ON_FORCE_ON)
-+              set_bit(bit_on, &priv->led_state);
-+      else
-+              clear_bit(bit_on, &priv->led_state);
-+
-+      if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
-+              set_bit(bit_blink, &priv->led_state);
-+      else
-+              clear_bit(bit_blink, &priv->led_state);
-+
-+      if (!rules)
-+              return 0;
-+
-+      if (on & on_set)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK);
-+
-+      if (on & MTK_PHY_LED_ON_LINK10)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_10);
-+
-+      if (on & MTK_PHY_LED_ON_LINK100)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_100);
-+
-+      if (on & MTK_PHY_LED_ON_LINK1000)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
-+
-+      if (on & MTK_PHY_LED_ON_LINK2500)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_2500);
-+
-+      if (on & MTK_PHY_LED_ON_FDX)
-+              *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
-+
-+      if (on & MTK_PHY_LED_ON_HDX)
-+              *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
-+
-+      if (blink & rx_blink_set)
-+              *rules |= BIT(TRIGGER_NETDEV_RX);
-+
-+      if (blink & tx_blink_set)
-+              *rules |= BIT(TRIGGER_NETDEV_TX);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_get);
-+
-+int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index,
-+                          unsigned long rules, u16 on_set,
-+                          u16 rx_blink_set, u16 tx_blink_set)
-+{
-+      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
-+      struct mtk_socphy_priv *priv = phydev->priv;
-+      u16 on = 0, blink = 0;
-+      int ret;
-+
-+      if (index > 1)
-+              return -EINVAL;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
-+              on |= MTK_PHY_LED_ON_FDX;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
-+              on |= MTK_PHY_LED_ON_HDX;
-+
-+      if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
-+              on |= MTK_PHY_LED_ON_LINK10;
-+
-+      if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
-+              on |= MTK_PHY_LED_ON_LINK100;
-+
-+      if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
-+              on |= MTK_PHY_LED_ON_LINK1000;
-+
-+      if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK)))
-+              on |= MTK_PHY_LED_ON_LINK2500;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_RX)) {
-+              blink |= (on & on_set) ?
-+                        (((on & MTK_PHY_LED_ON_LINK10) ?
-+                          MTK_PHY_LED_BLINK_10RX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK100) ?
-+                          MTK_PHY_LED_BLINK_100RX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK1000) ?
-+                          MTK_PHY_LED_BLINK_1000RX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK2500) ?
-+                          MTK_PHY_LED_BLINK_2500RX : 0)) :
-+                        rx_blink_set;
-+      }
-+
-+      if (rules & BIT(TRIGGER_NETDEV_TX)) {
-+              blink |= (on & on_set) ?
-+                        (((on & MTK_PHY_LED_ON_LINK10) ?
-+                          MTK_PHY_LED_BLINK_10TX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK100) ?
-+                          MTK_PHY_LED_BLINK_100TX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK1000) ?
-+                          MTK_PHY_LED_BLINK_1000TX : 0) |
-+                         ((on & MTK_PHY_LED_ON_LINK2500) ?
-+                          MTK_PHY_LED_BLINK_2500TX : 0)) :
-+                        tx_blink_set;
-+      }
-+
-+      if (blink || on)
-+              set_bit(bit_netdev, &priv->led_state);
-+      else
-+              clear_bit(bit_netdev, &priv->led_state);
-+
-+      ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                           MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
-+                           MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | on_set,
-+                           on);
-+
-+      if (ret)
-+              return ret;
-+
-+      return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                           MTK_PHY_LED1_BLINK_CTRL :
-+                           MTK_PHY_LED0_BLINK_CTRL, blink);
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_set);
-+
-+int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on,
-+                          unsigned long *delay_off, bool *blinking)
-+{
-+      if (index > 1)
-+              return -EINVAL;
-+
-+      if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
-+              *blinking = true;
-+              *delay_on = 50;
-+              *delay_off = 50;
-+      }
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_led_num_dly_cfg);
-+
-+int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
-+                        u16 led_on_mask, bool on)
-+{
-+      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
-+      struct mtk_socphy_priv *priv = phydev->priv;
-+      bool changed;
-+
-+      if (on)
-+              changed = !test_and_set_bit(bit_on, &priv->led_state);
-+      else
-+              changed = !!test_and_clear_bit(bit_on, &priv->led_state);
-+
-+      changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
-+                                      (index ? 16 : 0), &priv->led_state);
-+      if (changed)
-+              return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                                    MTK_PHY_LED1_ON_CTRL :
-+                                    MTK_PHY_LED0_ON_CTRL,
-+                                    led_on_mask,
-+                                    on ? MTK_PHY_LED_ON_FORCE_ON : 0);
-+      else
-+              return 0;
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_hw_led_on_set);
-+
-+int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, bool blinking)
-+{
-+      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
-+                               (index ? 16 : 0);
-+      struct mtk_socphy_priv *priv = phydev->priv;
-+      bool changed;
-+
-+      if (blinking)
-+              changed = !test_and_set_bit(bit_blink, &priv->led_state);
-+      else
-+              changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
-+
-+      changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
-+                            (index ? 16 : 0), &priv->led_state);
-+      if (changed)
-+              return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                                   MTK_PHY_LED1_BLINK_CTRL :
-+                                   MTK_PHY_LED0_BLINK_CTRL,
-+                                   blinking ?
-+                                   MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
-+      else
-+              return 0;
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_hw_led_blink_set);
-+
-+void mtk_phy_leds_state_init(struct phy_device *phydev)
-+{
-+      int i;
-+
-+      for (i = 0; i < 2; ++i)
-+              phydev->drv->led_hw_control_get(phydev, i, NULL);
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_leds_state_init);
-+
-+MODULE_DESCRIPTION("MediaTek Ethernet PHY driver common");
-+MODULE_AUTHOR("Sky Huang <SkyLake.Huang@mediatek.com>");
-+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/net/phy/mediatek/mtk.h
-@@ -0,0 +1,86 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Common definition for Mediatek Ethernet PHYs
-+ * Author: SkyLake Huang <SkyLake.Huang@mediatek.com>
-+ * Copyright (c) 2024 MediaTek Inc.
-+ */
-+
-+#ifndef _MTK_EPHY_H_
-+#define _MTK_EPHY_H_
-+
-+#define MTK_EXT_PAGE_ACCESS                   0x1f
-+
-+/* Registers on MDIO_MMD_VEND2 */
-+#define MTK_PHY_LED0_ON_CTRL                  0x24
-+#define MTK_PHY_LED1_ON_CTRL                  0x26
-+#define   MTK_GPHY_LED_ON_MASK                        GENMASK(6, 0)
-+#define   MTK_2P5GPHY_LED_ON_MASK             GENMASK(7, 0)
-+#define   MTK_PHY_LED_ON_LINK1000             BIT(0)
-+#define   MTK_PHY_LED_ON_LINK100              BIT(1)
-+#define   MTK_PHY_LED_ON_LINK10                       BIT(2)
-+#define   MTK_PHY_LED_ON_LINKDOWN             BIT(3)
-+#define   MTK_PHY_LED_ON_FDX                  BIT(4) /* Full duplex */
-+#define   MTK_PHY_LED_ON_HDX                  BIT(5) /* Half duplex */
-+#define   MTK_PHY_LED_ON_FORCE_ON             BIT(6)
-+#define   MTK_PHY_LED_ON_LINK2500             BIT(7)
-+#define   MTK_PHY_LED_ON_POLARITY             BIT(14)
-+#define   MTK_PHY_LED_ON_ENABLE                       BIT(15)
-+
-+#define MTK_PHY_LED0_BLINK_CTRL                       0x25
-+#define MTK_PHY_LED1_BLINK_CTRL                       0x27
-+#define   MTK_PHY_LED_BLINK_1000TX            BIT(0)
-+#define   MTK_PHY_LED_BLINK_1000RX            BIT(1)
-+#define   MTK_PHY_LED_BLINK_100TX             BIT(2)
-+#define   MTK_PHY_LED_BLINK_100RX             BIT(3)
-+#define   MTK_PHY_LED_BLINK_10TX              BIT(4)
-+#define   MTK_PHY_LED_BLINK_10RX              BIT(5)
-+#define   MTK_PHY_LED_BLINK_COLLISION         BIT(6)
-+#define   MTK_PHY_LED_BLINK_RX_CRC_ERR                BIT(7)
-+#define   MTK_PHY_LED_BLINK_RX_IDLE_ERR               BIT(8)
-+#define   MTK_PHY_LED_BLINK_FORCE_BLINK               BIT(9)
-+#define   MTK_PHY_LED_BLINK_2500TX            BIT(10)
-+#define   MTK_PHY_LED_BLINK_2500RX            BIT(11)
-+
-+#define MTK_GPHY_LED_ON_SET                   (MTK_PHY_LED_ON_LINK1000 | \
-+                                               MTK_PHY_LED_ON_LINK100 | \
-+                                               MTK_PHY_LED_ON_LINK10)
-+#define MTK_GPHY_LED_RX_BLINK_SET             (MTK_PHY_LED_BLINK_1000RX | \
-+                                               MTK_PHY_LED_BLINK_100RX | \
-+                                               MTK_PHY_LED_BLINK_10RX)
-+#define MTK_GPHY_LED_TX_BLINK_SET             (MTK_PHY_LED_BLINK_1000RX | \
-+                                               MTK_PHY_LED_BLINK_100RX | \
-+                                               MTK_PHY_LED_BLINK_10RX)
-+
-+#define MTK_2P5GPHY_LED_ON_SET                        (MTK_PHY_LED_ON_LINK2500 | \
-+                                               MTK_GPHY_LED_ON_SET)
-+#define MTK_2P5GPHY_LED_RX_BLINK_SET          (MTK_PHY_LED_BLINK_2500RX | \
-+                                               MTK_GPHY_LED_RX_BLINK_SET)
-+#define MTK_2P5GPHY_LED_TX_BLINK_SET          (MTK_PHY_LED_BLINK_2500RX | \
-+                                               MTK_GPHY_LED_TX_BLINK_SET)
-+
-+#define MTK_PHY_LED_STATE_FORCE_ON    0
-+#define MTK_PHY_LED_STATE_FORCE_BLINK 1
-+#define MTK_PHY_LED_STATE_NETDEV      2
-+
-+struct mtk_socphy_priv {
-+      unsigned long           led_state;
-+};
-+
-+int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+                              unsigned long rules,
-+                              unsigned long supported_triggers);
-+int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index,
-+                          unsigned long rules, u16 on_set,
-+                          u16 rx_blink_set, u16 tx_blink_set);
-+int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index,
-+                          unsigned long *rules, u16 on_set,
-+                          u16 rx_blink_set, u16 tx_blink_set);
-+int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on,
-+                          unsigned long *delay_off, bool *blinking);
-+int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
-+                        u16 led_on_mask, bool on);
-+int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
-+                           bool blinking);
-+void mtk_phy_leds_state_init(struct phy_device *phydev);
-+
-+#endif /* _MTK_EPHY_H_ */
diff --git a/target/linux/generic/backport-6.18/720-06-v6.13-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch b/target/linux/generic/backport-6.18/720-06-v6.13-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch
deleted file mode 100644 (file)
index 19f3a84..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-From 3efd0595fc7aaae300f5d9f4f0ae86f432c8d2c7 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Sat, 9 Nov 2024 00:34:53 +0800
-Subject: [PATCH 06/20] net: phy: mediatek: Improve readability of
- mtk-phy-lib.c's mtk_phy_led_hw_ctrl_set()
-
-This patch removes parens around TRIGGER_NETDEV_RX/TRIGGER_NETDEV_TX in
-mtk_phy_led_hw_ctrl_set(), which improves readability.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/mediatek/mtk-phy-lib.c | 44 ++++++++++++++------------
- 1 file changed, 24 insertions(+), 20 deletions(-)
-
---- a/drivers/net/phy/mediatek/mtk-phy-lib.c
-+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
-@@ -129,29 +129,33 @@ int mtk_phy_led_hw_ctrl_set(struct phy_d
-               on |= MTK_PHY_LED_ON_LINK2500;
-       if (rules & BIT(TRIGGER_NETDEV_RX)) {
--              blink |= (on & on_set) ?
--                        (((on & MTK_PHY_LED_ON_LINK10) ?
--                          MTK_PHY_LED_BLINK_10RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK100) ?
--                          MTK_PHY_LED_BLINK_100RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK1000) ?
--                          MTK_PHY_LED_BLINK_1000RX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK2500) ?
--                          MTK_PHY_LED_BLINK_2500RX : 0)) :
--                        rx_blink_set;
-+              if (on & on_set) {
-+                      if (on & MTK_PHY_LED_ON_LINK10)
-+                              blink |= MTK_PHY_LED_BLINK_10RX;
-+                      if (on & MTK_PHY_LED_ON_LINK100)
-+                              blink |= MTK_PHY_LED_BLINK_100RX;
-+                      if (on & MTK_PHY_LED_ON_LINK1000)
-+                              blink |= MTK_PHY_LED_BLINK_1000RX;
-+                      if (on & MTK_PHY_LED_ON_LINK2500)
-+                              blink |= MTK_PHY_LED_BLINK_2500RX;
-+              } else {
-+                      blink |= rx_blink_set;
-+              }
-       }
-       if (rules & BIT(TRIGGER_NETDEV_TX)) {
--              blink |= (on & on_set) ?
--                        (((on & MTK_PHY_LED_ON_LINK10) ?
--                          MTK_PHY_LED_BLINK_10TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK100) ?
--                          MTK_PHY_LED_BLINK_100TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK1000) ?
--                          MTK_PHY_LED_BLINK_1000TX : 0) |
--                         ((on & MTK_PHY_LED_ON_LINK2500) ?
--                          MTK_PHY_LED_BLINK_2500TX : 0)) :
--                        tx_blink_set;
-+              if (on & on_set) {
-+                      if (on & MTK_PHY_LED_ON_LINK10)
-+                              blink |= MTK_PHY_LED_BLINK_10TX;
-+                      if (on & MTK_PHY_LED_ON_LINK100)
-+                              blink |= MTK_PHY_LED_BLINK_100TX;
-+                      if (on & MTK_PHY_LED_ON_LINK1000)
-+                              blink |= MTK_PHY_LED_BLINK_1000TX;
-+                      if (on & MTK_PHY_LED_ON_LINK2500)
-+                              blink |= MTK_PHY_LED_BLINK_2500TX;
-+              } else {
-+                      blink |= tx_blink_set;
-+              }
-       }
-       if (blink || on)
diff --git a/target/linux/generic/backport-6.18/720-07-v6.13-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch b/target/linux/generic/backport-6.18/720-07-v6.13-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch
deleted file mode 100644 (file)
index a5828bc..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-From 50a97d716105a5f35aaecca0bdfe8e23cba0e87f Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Sat, 9 Nov 2024 00:34:54 +0800
-Subject: [PATCH 07/20] net: phy: mediatek: Integrate read/write page helper
- functions
-
-This patch integrates read/write page helper functions as MTK phy lib.
-They are basically the same in mtk-ge.c & mtk-ge-soc.c.
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/mediatek/Kconfig       |  1 +
- drivers/net/phy/mediatek/mtk-ge-soc.c  | 18 ++++--------------
- drivers/net/phy/mediatek/mtk-ge.c      | 20 ++++++--------------
- drivers/net/phy/mediatek/mtk-phy-lib.c | 12 ++++++++++++
- drivers/net/phy/mediatek/mtk.h         |  3 +++
- 5 files changed, 26 insertions(+), 28 deletions(-)
-
---- a/drivers/net/phy/mediatek/Kconfig
-+++ b/drivers/net/phy/mediatek/Kconfig
-@@ -4,6 +4,7 @@ config MTK_NET_PHYLIB
- config MEDIATEK_GE_PHY
-       tristate "MediaTek Gigabit Ethernet PHYs"
-+      select MTK_NET_PHYLIB
-       help
-         Supports the MediaTek non-built-in Gigabit Ethernet PHYs.
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -271,16 +271,6 @@ struct mtk_socphy_shared {
-       struct mtk_socphy_priv  priv[4];
- };
--static int mtk_socphy_read_page(struct phy_device *phydev)
--{
--      return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
--}
--
--static int mtk_socphy_write_page(struct phy_device *phydev, int page)
--{
--      return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
--}
--
- /* One calibration cycle consists of:
-  * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
-  *   until AD_CAL_COMP is ready to output calibration result.
-@@ -1337,8 +1327,8 @@ static struct phy_driver mtk_socphy_driv
-               .probe          = mt7981_phy_probe,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
--              .read_page      = mtk_socphy_read_page,
--              .write_page     = mtk_socphy_write_page,
-+              .read_page      = mtk_phy_read_page,
-+              .write_page     = mtk_phy_write_page,
-               .led_blink_set  = mt798x_phy_led_blink_set,
-               .led_brightness_set = mt798x_phy_led_brightness_set,
-               .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
-@@ -1354,8 +1344,8 @@ static struct phy_driver mtk_socphy_driv
-               .probe          = mt7988_phy_probe,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
--              .read_page      = mtk_socphy_read_page,
--              .write_page     = mtk_socphy_write_page,
-+              .read_page      = mtk_phy_read_page,
-+              .write_page     = mtk_phy_write_page,
-               .led_blink_set  = mt798x_phy_led_blink_set,
-               .led_brightness_set = mt798x_phy_led_brightness_set,
-               .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
---- a/drivers/net/phy/mediatek/mtk-ge.c
-+++ b/drivers/net/phy/mediatek/mtk-ge.c
-@@ -3,6 +3,8 @@
- #include <linux/module.h>
- #include <linux/phy.h>
-+#include "mtk.h"
-+
- #define MTK_EXT_PAGE_ACCESS           0x1f
- #define MTK_PHY_PAGE_STANDARD         0x0000
- #define MTK_PHY_PAGE_EXTENDED         0x0001
-@@ -11,16 +13,6 @@
- #define MTK_PHY_PAGE_EXTENDED_2A30    0x2a30
- #define MTK_PHY_PAGE_EXTENDED_52B5    0x52b5
--static int mtk_gephy_read_page(struct phy_device *phydev)
--{
--      return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
--}
--
--static int mtk_gephy_write_page(struct phy_device *phydev, int page)
--{
--      return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
--}
--
- static void mtk_gephy_config_init(struct phy_device *phydev)
- {
-       /* Enable HW auto downshift */
-@@ -77,8 +69,8 @@ static struct phy_driver mtk_gephy_drive
-               .handle_interrupt = genphy_handle_interrupt_no_ack,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
--              .read_page      = mtk_gephy_read_page,
--              .write_page     = mtk_gephy_write_page,
-+              .read_page      = mtk_phy_read_page,
-+              .write_page     = mtk_phy_write_page,
-       },
-       {
-               PHY_ID_MATCH_EXACT(0x03a29441),
-@@ -91,8 +83,8 @@ static struct phy_driver mtk_gephy_drive
-               .handle_interrupt = genphy_handle_interrupt_no_ack,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
--              .read_page      = mtk_gephy_read_page,
--              .write_page     = mtk_gephy_write_page,
-+              .read_page      = mtk_phy_read_page,
-+              .write_page     = mtk_phy_write_page,
-       },
- };
---- a/drivers/net/phy/mediatek/mtk-phy-lib.c
-+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
-@@ -6,6 +6,18 @@
- #include "mtk.h"
-+int mtk_phy_read_page(struct phy_device *phydev)
-+{
-+      return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_read_page);
-+
-+int mtk_phy_write_page(struct phy_device *phydev, int page)
-+{
-+      return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
-+}
-+EXPORT_SYMBOL_GPL(mtk_phy_write_page);
-+
- int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-                               unsigned long rules,
-                               unsigned long supported_triggers)
---- a/drivers/net/phy/mediatek/mtk.h
-+++ b/drivers/net/phy/mediatek/mtk.h
-@@ -66,6 +66,9 @@ struct mtk_socphy_priv {
-       unsigned long           led_state;
- };
-+int mtk_phy_read_page(struct phy_device *phydev);
-+int mtk_phy_write_page(struct phy_device *phydev, int page);
-+
- int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-                               unsigned long rules,
-                               unsigned long supported_triggers);
diff --git a/target/linux/generic/backport-6.18/720-08-v6.13-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch b/target/linux/generic/backport-6.18/720-08-v6.13-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch
deleted file mode 100644 (file)
index 1c87384..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From e6579df175d5b1baa605c82f8e759542262637cf Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Sat, 9 Nov 2024 00:34:55 +0800
-Subject: [PATCH 08/20] net: phy: mediatek: add MT7530 & MT7531's PHY ID macros
-
-This patch adds MT7530 & MT7531's PHY ID macros in mtk-ge.c so that
-it follows the same rule of mtk-ge-soc.c.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/mediatek/mtk-ge.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/mediatek/mtk-ge.c
-+++ b/drivers/net/phy/mediatek/mtk-ge.c
-@@ -5,6 +5,9 @@
- #include "mtk.h"
-+#define MTK_GPHY_ID_MT7530            0x03a29412
-+#define MTK_GPHY_ID_MT7531            0x03a29441
-+
- #define MTK_EXT_PAGE_ACCESS           0x1f
- #define MTK_PHY_PAGE_STANDARD         0x0000
- #define MTK_PHY_PAGE_EXTENDED         0x0001
-@@ -59,7 +62,7 @@ static int mt7531_phy_config_init(struct
- static struct phy_driver mtk_gephy_driver[] = {
-       {
--              PHY_ID_MATCH_EXACT(0x03a29412),
-+              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
-               .name           = "MediaTek MT7530 PHY",
-               .config_init    = mt7530_phy_config_init,
-               /* Interrupts are handled by the switch, not the PHY
-@@ -73,7 +76,7 @@ static struct phy_driver mtk_gephy_drive
-               .write_page     = mtk_phy_write_page,
-       },
-       {
--              PHY_ID_MATCH_EXACT(0x03a29441),
-+              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
-               .name           = "MediaTek MT7531 PHY",
-               .config_init    = mt7531_phy_config_init,
-               /* Interrupts are handled by the switch, not the PHY
-@@ -91,8 +94,8 @@ static struct phy_driver mtk_gephy_drive
- module_phy_driver(mtk_gephy_driver);
- static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
--      { PHY_ID_MATCH_EXACT(0x03a29441) },
--      { PHY_ID_MATCH_EXACT(0x03a29412) },
-+      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530) },
-+      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531) },
-       { }
- };
diff --git a/target/linux/generic/backport-6.18/720-09-v6.14-net-phy-Constify-struct-mdio_device_id.patch b/target/linux/generic/backport-6.18/720-09-v6.14-net-phy-Constify-struct-mdio_device_id.patch
deleted file mode 100644 (file)
index c0c840d..0000000
+++ /dev/null
@@ -1,700 +0,0 @@
-From e127f7380aaf2cd1614961d826a4af7ab297d37f Mon Sep 17 00:00:00 2001
-From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
-Date: Sun, 12 Jan 2025 15:14:50 +0100
-Subject: [PATCH 09/20] net: phy: Constify struct mdio_device_id
-
-'struct mdio_device_id' is not modified in these drivers.
-
-Constifying these structures moves some data to a read-only section, so
-increase overall security.
-
-On a x86_64, with allmodconfig, as an example:
-Before:
-======
-   text           data     bss     dec     hex filename
-  27014          12792       0   39806    9b7e drivers/net/phy/broadcom.o
-
-After:
-=====
-   text           data     bss     dec     hex filename
-  27206          12600       0   39806    9b7e drivers/net/phy/broadcom.o
-
-Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/403c381b7d9156b67ad68ffc44b8eee70c5e86a9.1736691226.git.christophe.jaillet@wanadoo.fr
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/adin.c                   | 2 +-
- drivers/net/phy/adin1100.c               | 2 +-
- drivers/net/phy/air_en8811h.c            | 2 +-
- drivers/net/phy/amd.c                    | 2 +-
- drivers/net/phy/aquantia/aquantia_main.c | 2 +-
- drivers/net/phy/ax88796b.c               | 2 +-
- drivers/net/phy/bcm-cygnus.c             | 2 +-
- drivers/net/phy/bcm54140.c               | 2 +-
- drivers/net/phy/bcm63xx.c                | 2 +-
- drivers/net/phy/bcm7xxx.c                | 2 +-
- drivers/net/phy/bcm84881.c               | 2 +-
- drivers/net/phy/broadcom.c               | 2 +-
- drivers/net/phy/cicada.c                 | 2 +-
- drivers/net/phy/cortina.c                | 2 +-
- drivers/net/phy/davicom.c                | 2 +-
- drivers/net/phy/dp83640.c                | 2 +-
- drivers/net/phy/dp83822.c                | 2 +-
- drivers/net/phy/dp83848.c                | 2 +-
- drivers/net/phy/dp83867.c                | 2 +-
- drivers/net/phy/dp83869.c                | 2 +-
- drivers/net/phy/dp83tc811.c              | 2 +-
- drivers/net/phy/dp83td510.c              | 2 +-
- drivers/net/phy/dp83tg720.c              | 2 +-
- drivers/net/phy/et1011c.c                | 2 +-
- drivers/net/phy/icplus.c                 | 2 +-
- drivers/net/phy/intel-xway.c             | 2 +-
- drivers/net/phy/lxt.c                    | 2 +-
- drivers/net/phy/marvell-88q2xxx.c        | 2 +-
- drivers/net/phy/marvell-88x2222.c        | 2 +-
- drivers/net/phy/marvell.c                | 2 +-
- drivers/net/phy/marvell10g.c             | 2 +-
- drivers/net/phy/mediatek/mtk-ge-soc.c    | 2 +-
- drivers/net/phy/mediatek/mtk-ge.c        | 2 +-
- drivers/net/phy/meson-gxl.c              | 2 +-
- drivers/net/phy/micrel.c                 | 2 +-
- drivers/net/phy/microchip.c              | 2 +-
- drivers/net/phy/microchip_t1.c           | 2 +-
- drivers/net/phy/microchip_t1s.c          | 2 +-
- drivers/net/phy/mscc/mscc_main.c         | 2 +-
- drivers/net/phy/mxl-gpy.c                | 2 +-
- drivers/net/phy/national.c               | 2 +-
- drivers/net/phy/ncn26000.c               | 2 +-
- drivers/net/phy/nxp-c45-tja11xx.c        | 2 +-
- drivers/net/phy/nxp-cbtx.c               | 2 +-
- drivers/net/phy/nxp-tja11xx.c            | 2 +-
- drivers/net/phy/qcom/at803x.c            | 2 +-
- drivers/net/phy/qcom/qca807x.c           | 2 +-
- drivers/net/phy/qcom/qca808x.c           | 2 +-
- drivers/net/phy/qcom/qca83xx.c           | 2 +-
- drivers/net/phy/qsemi.c                  | 2 +-
- drivers/net/phy/rockchip.c               | 2 +-
- drivers/net/phy/smsc.c                   | 2 +-
- drivers/net/phy/ste10Xp.c                | 2 +-
- drivers/net/phy/teranetics.c             | 2 +-
- drivers/net/phy/uPD60620.c               | 2 +-
- drivers/net/phy/vitesse.c                | 2 +-
- 56 files changed, 56 insertions(+), 56 deletions(-)
-
---- a/drivers/net/phy/adin.c
-+++ b/drivers/net/phy/adin.c
-@@ -1040,7 +1040,7 @@ static struct phy_driver adin_driver[] =
- module_phy_driver(adin_driver);
--static struct mdio_device_id __maybe_unused adin_tbl[] = {
-+static const struct mdio_device_id __maybe_unused adin_tbl[] = {
-       { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300) },
-       { }
---- a/drivers/net/phy/adin1100.c
-+++ b/drivers/net/phy/adin1100.c
-@@ -340,7 +340,7 @@ static struct phy_driver adin_driver[] =
- module_phy_driver(adin_driver);
--static struct mdio_device_id __maybe_unused adin_tbl[] = {
-+static const struct mdio_device_id __maybe_unused adin_tbl[] = {
-       { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1100) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1110) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_ADIN2111) },
---- a/drivers/net/phy/air_en8811h.c
-+++ b/drivers/net/phy/air_en8811h.c
-@@ -1075,7 +1075,7 @@ static struct phy_driver en8811h_driver[
- module_phy_driver(en8811h_driver);
--static struct mdio_device_id __maybe_unused en8811h_tbl[] = {
-+static const struct mdio_device_id __maybe_unused en8811h_tbl[] = {
-       { PHY_ID_MATCH_MODEL(EN8811H_PHY_ID) },
-       { }
- };
---- a/drivers/net/phy/amd.c
-+++ b/drivers/net/phy/amd.c
-@@ -111,7 +111,7 @@ static struct phy_driver am79c_drivers[]
- module_phy_driver(am79c_drivers);
--static struct mdio_device_id __maybe_unused amd_tbl[] = {
-+static const struct mdio_device_id __maybe_unused amd_tbl[] = {
-       { PHY_ID_AC101L, 0xfffffff0 },
-       { PHY_ID_AM79C874, 0xfffffff0 },
-       { }
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -1096,7 +1096,7 @@ static struct phy_driver aqr_driver[] =
- module_phy_driver(aqr_driver);
--static struct mdio_device_id __maybe_unused aqr_tbl[] = {
-+static const struct mdio_device_id __maybe_unused aqr_tbl[] = {
-       { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
---- a/drivers/net/phy/ax88796b.c
-+++ b/drivers/net/phy/ax88796b.c
-@@ -121,7 +121,7 @@ static struct phy_driver asix_driver[] =
- module_phy_driver(asix_driver);
--static struct mdio_device_id __maybe_unused asix_tbl[] = {
-+static const struct mdio_device_id __maybe_unused asix_tbl[] = {
-       { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772A) },
-       { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772C) },
-       { PHY_ID_ASIX_AX88796B, 0xfffffff0 },
---- a/drivers/net/phy/bcm-cygnus.c
-+++ b/drivers/net/phy/bcm-cygnus.c
-@@ -278,7 +278,7 @@ static struct phy_driver bcm_cygnus_phy_
- }
- };
--static struct mdio_device_id __maybe_unused bcm_cygnus_phy_tbl[] = {
-+static const struct mdio_device_id __maybe_unused bcm_cygnus_phy_tbl[] = {
-       { PHY_ID_BCM_CYGNUS, 0xfffffff0, },
-       { PHY_ID_BCM_OMEGA, 0xfffffff0, },
-       { }
---- a/drivers/net/phy/bcm54140.c
-+++ b/drivers/net/phy/bcm54140.c
-@@ -883,7 +883,7 @@ static struct phy_driver bcm54140_driver
- };
- module_phy_driver(bcm54140_drivers);
--static struct mdio_device_id __maybe_unused bcm54140_tbl[] = {
-+static const struct mdio_device_id __maybe_unused bcm54140_tbl[] = {
-       { PHY_ID_BCM54140, BCM54140_PHY_ID_MASK },
-       { }
- };
---- a/drivers/net/phy/bcm63xx.c
-+++ b/drivers/net/phy/bcm63xx.c
-@@ -93,7 +93,7 @@ static struct phy_driver bcm63xx_driver[
- module_phy_driver(bcm63xx_driver);
--static struct mdio_device_id __maybe_unused bcm63xx_tbl[] = {
-+static const struct mdio_device_id __maybe_unused bcm63xx_tbl[] = {
-       { 0x00406000, 0xfffffc00 },
-       { 0x002bdc00, 0xfffffc00 },
-       { }
---- a/drivers/net/phy/bcm7xxx.c
-+++ b/drivers/net/phy/bcm7xxx.c
-@@ -929,7 +929,7 @@ static struct phy_driver bcm7xxx_driver[
-       BCM7XXX_16NM_EPHY(PHY_ID_BCM7712, "Broadcom BCM7712"),
- };
--static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
-+static const struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
-       { PHY_ID_BCM72113, 0xfffffff0 },
-       { PHY_ID_BCM72116, 0xfffffff0, },
-       { PHY_ID_BCM72165, 0xfffffff0, },
---- a/drivers/net/phy/bcm84881.c
-+++ b/drivers/net/phy/bcm84881.c
-@@ -262,7 +262,7 @@ static struct phy_driver bcm84881_driver
- module_phy_driver(bcm84881_drivers);
- /* FIXME: module auto-loading for Clause 45 PHYs seems non-functional */
--static struct mdio_device_id __maybe_unused bcm84881_tbl[] = {
-+static const struct mdio_device_id __maybe_unused bcm84881_tbl[] = {
-       { 0xae025150, 0xfffffff0 },
-       { },
- };
---- a/drivers/net/phy/broadcom.c
-+++ b/drivers/net/phy/broadcom.c
-@@ -1734,7 +1734,7 @@ static struct phy_driver broadcom_driver
- module_phy_driver(broadcom_drivers);
--static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
-+static const struct mdio_device_id __maybe_unused broadcom_tbl[] = {
-       { PHY_ID_BCM5411, 0xfffffff0 },
-       { PHY_ID_BCM5421, 0xfffffff0 },
-       { PHY_ID_BCM54210E, 0xfffffff0 },
---- a/drivers/net/phy/cicada.c
-+++ b/drivers/net/phy/cicada.c
-@@ -145,7 +145,7 @@ static struct phy_driver cis820x_driver[
- module_phy_driver(cis820x_driver);
--static struct mdio_device_id __maybe_unused cicada_tbl[] = {
-+static const struct mdio_device_id __maybe_unused cicada_tbl[] = {
-       { 0x000fc410, 0x000ffff0 },
-       { 0x000fc440, 0x000fffc0 },
-       { }
---- a/drivers/net/phy/cortina.c
-+++ b/drivers/net/phy/cortina.c
-@@ -87,7 +87,7 @@ static struct phy_driver cortina_driver[
- module_phy_driver(cortina_driver);
--static struct mdio_device_id __maybe_unused cortina_tbl[] = {
-+static const struct mdio_device_id __maybe_unused cortina_tbl[] = {
-       { PHY_ID_CS4340, 0xffffffff},
-       {},
- };
---- a/drivers/net/phy/davicom.c
-+++ b/drivers/net/phy/davicom.c
-@@ -209,7 +209,7 @@ static struct phy_driver dm91xx_driver[]
- module_phy_driver(dm91xx_driver);
--static struct mdio_device_id __maybe_unused davicom_tbl[] = {
-+static const struct mdio_device_id __maybe_unused davicom_tbl[] = {
-       { 0x0181b880, 0x0ffffff0 },
-       { 0x0181b8b0, 0x0ffffff0 },
-       { 0x0181b8a0, 0x0ffffff0 },
---- a/drivers/net/phy/dp83640.c
-+++ b/drivers/net/phy/dp83640.c
-@@ -1548,7 +1548,7 @@ MODULE_LICENSE("GPL");
- module_init(dp83640_init);
- module_exit(dp83640_exit);
--static struct mdio_device_id __maybe_unused dp83640_tbl[] = {
-+static const struct mdio_device_id __maybe_unused dp83640_tbl[] = {
-       { DP83640_PHY_ID, 0xfffffff0 },
-       { }
- };
---- a/drivers/net/phy/dp83822.c
-+++ b/drivers/net/phy/dp83822.c
-@@ -825,7 +825,7 @@ static struct phy_driver dp83822_driver[
- };
- module_phy_driver(dp83822_driver);
--static struct mdio_device_id __maybe_unused dp83822_tbl[] = {
-+static const struct mdio_device_id __maybe_unused dp83822_tbl[] = {
-       { DP83822_PHY_ID, 0xfffffff0 },
-       { DP83825I_PHY_ID, 0xfffffff0 },
-       { DP83826C_PHY_ID, 0xfffffff0 },
---- a/drivers/net/phy/dp83848.c
-+++ b/drivers/net/phy/dp83848.c
-@@ -123,7 +123,7 @@ static int dp83848_config_init(struct ph
-       return 0;
- }
--static struct mdio_device_id __maybe_unused dp83848_tbl[] = {
-+static const struct mdio_device_id __maybe_unused dp83848_tbl[] = {
-       { TI_DP83848C_PHY_ID, 0xfffffff0 },
-       { NS_DP83848C_PHY_ID, 0xfffffff0 },
-       { TI_DP83620_PHY_ID, 0xfffffff0 },
---- a/drivers/net/phy/dp83867.c
-+++ b/drivers/net/phy/dp83867.c
-@@ -1210,7 +1210,7 @@ static struct phy_driver dp83867_driver[
- };
- module_phy_driver(dp83867_driver);
--static struct mdio_device_id __maybe_unused dp83867_tbl[] = {
-+static const struct mdio_device_id __maybe_unused dp83867_tbl[] = {
-       { DP83867_PHY_ID, 0xfffffff0 },
-       { }
- };
---- a/drivers/net/phy/dp83869.c
-+++ b/drivers/net/phy/dp83869.c
-@@ -928,7 +928,7 @@ static struct phy_driver dp83869_driver[
- };
- module_phy_driver(dp83869_driver);
--static struct mdio_device_id __maybe_unused dp83869_tbl[] = {
-+static const struct mdio_device_id __maybe_unused dp83869_tbl[] = {
-       { PHY_ID_MATCH_MODEL(DP83869_PHY_ID) },
-       { PHY_ID_MATCH_MODEL(DP83561_PHY_ID) },
-       { }
---- a/drivers/net/phy/dp83tc811.c
-+++ b/drivers/net/phy/dp83tc811.c
-@@ -403,7 +403,7 @@ static struct phy_driver dp83811_driver[
- };
- module_phy_driver(dp83811_driver);
--static struct mdio_device_id __maybe_unused dp83811_tbl[] = {
-+static const struct mdio_device_id __maybe_unused dp83811_tbl[] = {
-       { DP83TC811_PHY_ID, 0xfffffff0 },
-       { },
- };
---- a/drivers/net/phy/dp83td510.c
-+++ b/drivers/net/phy/dp83td510.c
-@@ -605,7 +605,7 @@ static struct phy_driver dp83td510_drive
- } };
- module_phy_driver(dp83td510_driver);
--static struct mdio_device_id __maybe_unused dp83td510_tbl[] = {
-+static const struct mdio_device_id __maybe_unused dp83td510_tbl[] = {
-       { PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID) },
-       { }
- };
---- a/drivers/net/phy/dp83tg720.c
-+++ b/drivers/net/phy/dp83tg720.c
-@@ -361,7 +361,7 @@ static struct phy_driver dp83tg720_drive
- } };
- module_phy_driver(dp83tg720_driver);
--static struct mdio_device_id __maybe_unused dp83tg720_tbl[] = {
-+static const struct mdio_device_id __maybe_unused dp83tg720_tbl[] = {
-       { PHY_ID_MATCH_MODEL(DP83TG720S_PHY_ID) },
-       { }
- };
---- a/drivers/net/phy/et1011c.c
-+++ b/drivers/net/phy/et1011c.c
-@@ -94,7 +94,7 @@ static struct phy_driver et1011c_driver[
- module_phy_driver(et1011c_driver);
--static struct mdio_device_id __maybe_unused et1011c_tbl[] = {
-+static const struct mdio_device_id __maybe_unused et1011c_tbl[] = {
-       { 0x0282f014, 0xfffffff0 },
-       { }
- };
---- a/drivers/net/phy/icplus.c
-+++ b/drivers/net/phy/icplus.c
-@@ -624,7 +624,7 @@ static struct phy_driver icplus_driver[]
- module_phy_driver(icplus_driver);
--static struct mdio_device_id __maybe_unused icplus_tbl[] = {
-+static const struct mdio_device_id __maybe_unused icplus_tbl[] = {
-       { PHY_ID_MATCH_MODEL(IP175C_PHY_ID) },
-       { PHY_ID_MATCH_MODEL(IP1001_PHY_ID) },
-       { PHY_ID_MATCH_EXACT(IP101A_PHY_ID) },
---- a/drivers/net/phy/intel-xway.c
-+++ b/drivers/net/phy/intel-xway.c
-@@ -456,7 +456,7 @@ static struct phy_driver xway_gphy[] = {
- };
- module_phy_driver(xway_gphy);
--static struct mdio_device_id __maybe_unused xway_gphy_tbl[] = {
-+static const struct mdio_device_id __maybe_unused xway_gphy_tbl[] = {
-       { PHY_ID_PHY11G_1_3, 0xffffffff },
-       { PHY_ID_PHY22F_1_3, 0xffffffff },
-       { PHY_ID_PHY11G_1_4, 0xffffffff },
---- a/drivers/net/phy/lxt.c
-+++ b/drivers/net/phy/lxt.c
-@@ -348,7 +348,7 @@ static struct phy_driver lxt97x_driver[]
- module_phy_driver(lxt97x_driver);
--static struct mdio_device_id __maybe_unused lxt_tbl[] = {
-+static const struct mdio_device_id __maybe_unused lxt_tbl[] = {
-       { 0x78100000, 0xfffffff0 },
-       { 0x001378e0, 0xfffffff0 },
-       { 0x00137a10, 0xfffffff0 },
---- a/drivers/net/phy/marvell-88q2xxx.c
-+++ b/drivers/net/phy/marvell-88q2xxx.c
-@@ -940,7 +940,7 @@ static struct phy_driver mv88q2xxx_drive
- module_phy_driver(mv88q2xxx_driver);
--static struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = {
-+static const struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = {
-       { MARVELL_PHY_ID_88Q2110, MARVELL_PHY_ID_MASK },
-       { MARVELL_PHY_ID_88Q2220, MARVELL_PHY_ID_MASK },
-       { /*sentinel*/ }
---- a/drivers/net/phy/marvell-88x2222.c
-+++ b/drivers/net/phy/marvell-88x2222.c
-@@ -613,7 +613,7 @@ static struct phy_driver mv2222_drivers[
- };
- module_phy_driver(mv2222_drivers);
--static struct mdio_device_id __maybe_unused mv2222_tbl[] = {
-+static const struct mdio_device_id __maybe_unused mv2222_tbl[] = {
-       { MARVELL_PHY_ID_88X2222, MARVELL_PHY_ID_MASK },
-       { }
- };
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -4218,7 +4218,7 @@ static struct phy_driver marvell_drivers
- module_phy_driver(marvell_drivers);
--static struct mdio_device_id __maybe_unused marvell_tbl[] = {
-+static const struct mdio_device_id __maybe_unused marvell_tbl[] = {
-       { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
-       { MARVELL_PHY_ID_88E3082, MARVELL_PHY_ID_MASK },
-       { MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
---- a/drivers/net/phy/marvell10g.c
-+++ b/drivers/net/phy/marvell10g.c
-@@ -1484,7 +1484,7 @@ static struct phy_driver mv3310_drivers[
- module_phy_driver(mv3310_drivers);
--static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
-+static const struct mdio_device_id __maybe_unused mv3310_tbl[] = {
-       { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
-       { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
-       { },
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -1356,7 +1356,7 @@ static struct phy_driver mtk_socphy_driv
- module_phy_driver(mtk_socphy_driver);
--static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
-+static const struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
-       { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
-       { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
-       { }
---- a/drivers/net/phy/mediatek/mtk-ge.c
-+++ b/drivers/net/phy/mediatek/mtk-ge.c
-@@ -93,7 +93,7 @@ static struct phy_driver mtk_gephy_drive
- module_phy_driver(mtk_gephy_driver);
--static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
-+static const struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
-       { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530) },
-       { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531) },
-       { }
---- a/drivers/net/phy/meson-gxl.c
-+++ b/drivers/net/phy/meson-gxl.c
-@@ -221,7 +221,7 @@ static struct phy_driver meson_gxl_phy[]
-       },
- };
--static struct mdio_device_id __maybe_unused meson_gxl_tbl[] = {
-+static const struct mdio_device_id __maybe_unused meson_gxl_tbl[] = {
-       { PHY_ID_MATCH_VENDOR(0x01814400) },
-       { PHY_ID_MATCH_VENDOR(0x01803301) },
-       { }
---- a/drivers/net/phy/micrel.c
-+++ b/drivers/net/phy/micrel.c
-@@ -5835,7 +5835,7 @@ MODULE_DESCRIPTION("Micrel PHY driver");
- MODULE_AUTHOR("David J. Choi");
- MODULE_LICENSE("GPL");
--static struct mdio_device_id __maybe_unused micrel_tbl[] = {
-+static const struct mdio_device_id __maybe_unused micrel_tbl[] = {
-       { PHY_ID_KSZ9021, 0x000ffffe },
-       { PHY_ID_KSZ9031, MICREL_PHY_ID_MASK },
-       { PHY_ID_KSZ9131, MICREL_PHY_ID_MASK },
---- a/drivers/net/phy/microchip.c
-+++ b/drivers/net/phy/microchip.c
-@@ -509,7 +509,7 @@ static struct phy_driver microchip_phy_d
- module_phy_driver(microchip_phy_driver);
--static struct mdio_device_id __maybe_unused microchip_tbl[] = {
-+static const struct mdio_device_id __maybe_unused microchip_tbl[] = {
-       { 0x0007c132, 0xfffffff2 },
-       { PHY_ID_MATCH_MODEL(PHY_ID_LAN937X_TX) },
-       { }
---- a/drivers/net/phy/microchip_t1.c
-+++ b/drivers/net/phy/microchip_t1.c
-@@ -1886,7 +1886,7 @@ static struct phy_driver microchip_t1_ph
- module_phy_driver(microchip_t1_phy_driver);
--static struct mdio_device_id __maybe_unused microchip_t1_tbl[] = {
-+static const struct mdio_device_id __maybe_unused microchip_t1_tbl[] = {
-       { PHY_ID_MATCH_MODEL(PHY_ID_LAN87XX) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_LAN937X) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_LAN887X) },
---- a/drivers/net/phy/microchip_t1s.c
-+++ b/drivers/net/phy/microchip_t1s.c
-@@ -323,7 +323,7 @@ static struct phy_driver microchip_t1s_d
- module_phy_driver(microchip_t1s_driver);
--static struct mdio_device_id __maybe_unused tbl[] = {
-+static const struct mdio_device_id __maybe_unused tbl[] = {
-       { PHY_ID_MATCH_EXACT(PHY_ID_LAN867X_REVB1) },
-       { PHY_ID_MATCH_EXACT(PHY_ID_LAN865X_REVB0) },
-       { }
---- a/drivers/net/phy/mscc/mscc_main.c
-+++ b/drivers/net/phy/mscc/mscc_main.c
-@@ -2710,7 +2710,7 @@ static struct phy_driver vsc85xx_driver[
- module_phy_driver(vsc85xx_driver);
--static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
-+static const struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
-       { PHY_ID_MATCH_VENDOR(PHY_VENDOR_MSCC) },
-       { }
- };
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -1047,7 +1047,7 @@ static struct phy_driver gpy_drivers[] =
- };
- module_phy_driver(gpy_drivers);
--static struct mdio_device_id __maybe_unused gpy_tbl[] = {
-+static const struct mdio_device_id __maybe_unused gpy_tbl[] = {
-       {PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx)},
-       {PHY_ID_GPY115B, PHY_ID_GPYx15B_MASK},
-       {PHY_ID_MATCH_MODEL(PHY_ID_GPY115C)},
---- a/drivers/net/phy/national.c
-+++ b/drivers/net/phy/national.c
-@@ -173,7 +173,7 @@ MODULE_DESCRIPTION("NatSemi PHY driver")
- MODULE_AUTHOR("Stuart Menefy");
- MODULE_LICENSE("GPL");
--static struct mdio_device_id __maybe_unused ns_tbl[] = {
-+static const struct mdio_device_id __maybe_unused ns_tbl[] = {
-       { DP83865_PHY_ID, 0xfffffff0 },
-       { }
- };
---- a/drivers/net/phy/ncn26000.c
-+++ b/drivers/net/phy/ncn26000.c
-@@ -159,7 +159,7 @@ static struct phy_driver ncn26000_driver
- module_phy_driver(ncn26000_driver);
--static struct mdio_device_id __maybe_unused ncn26000_tbl[] = {
-+static const struct mdio_device_id __maybe_unused ncn26000_tbl[] = {
-       { PHY_ID_MATCH_MODEL(PHY_ID_NCN26000) },
-       { }
- };
---- a/drivers/net/phy/nxp-c45-tja11xx.c
-+++ b/drivers/net/phy/nxp-c45-tja11xx.c
-@@ -2102,7 +2102,7 @@ static struct phy_driver nxp_c45_driver[
- module_phy_driver(nxp_c45_driver);
--static struct mdio_device_id __maybe_unused nxp_c45_tbl[] = {
-+static const struct mdio_device_id __maybe_unused nxp_c45_tbl[] = {
-       { PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120) },
-       { /*sentinel*/ },
---- a/drivers/net/phy/nxp-cbtx.c
-+++ b/drivers/net/phy/nxp-cbtx.c
-@@ -215,7 +215,7 @@ static struct phy_driver cbtx_driver[] =
- module_phy_driver(cbtx_driver);
--static struct mdio_device_id __maybe_unused cbtx_tbl[] = {
-+static const struct mdio_device_id __maybe_unused cbtx_tbl[] = {
-       { PHY_ID_MATCH_MODEL(PHY_ID_CBTX_SJA1110) },
-       { },
- };
---- a/drivers/net/phy/nxp-tja11xx.c
-+++ b/drivers/net/phy/nxp-tja11xx.c
-@@ -888,7 +888,7 @@ static struct phy_driver tja11xx_driver[
- module_phy_driver(tja11xx_driver);
--static struct mdio_device_id __maybe_unused tja11xx_tbl[] = {
-+static const struct mdio_device_id __maybe_unused tja11xx_tbl[] = {
-       { PHY_ID_MATCH_MODEL(PHY_ID_TJA1100) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_TJA1101) },
-       { PHY_ID_MATCH_MODEL(PHY_ID_TJA1102) },
---- a/drivers/net/phy/qcom/at803x.c
-+++ b/drivers/net/phy/qcom/at803x.c
-@@ -1071,7 +1071,7 @@ static struct phy_driver at803x_driver[]
- module_phy_driver(at803x_driver);
--static struct mdio_device_id __maybe_unused atheros_tbl[] = {
-+static const struct mdio_device_id __maybe_unused atheros_tbl[] = {
-       { ATH8030_PHY_ID, AT8030_PHY_ID_MASK },
-       { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) },
-       { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
---- a/drivers/net/phy/qcom/qca807x.c
-+++ b/drivers/net/phy/qcom/qca807x.c
-@@ -828,7 +828,7 @@ static struct phy_driver qca807x_drivers
- };
- module_phy_driver(qca807x_drivers);
--static struct mdio_device_id __maybe_unused qca807x_tbl[] = {
-+static const struct mdio_device_id __maybe_unused qca807x_tbl[] = {
-       { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) },
-       { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) },
-       { }
---- a/drivers/net/phy/qcom/qca808x.c
-+++ b/drivers/net/phy/qcom/qca808x.c
-@@ -655,7 +655,7 @@ static struct phy_driver qca808x_driver[
- module_phy_driver(qca808x_driver);
--static struct mdio_device_id __maybe_unused qca808x_tbl[] = {
-+static const struct mdio_device_id __maybe_unused qca808x_tbl[] = {
-       { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
-       { }
- };
---- a/drivers/net/phy/qcom/qca83xx.c
-+++ b/drivers/net/phy/qcom/qca83xx.c
-@@ -261,7 +261,7 @@ static struct phy_driver qca83xx_driver[
- module_phy_driver(qca83xx_driver);
--static struct mdio_device_id __maybe_unused qca83xx_tbl[] = {
-+static const struct mdio_device_id __maybe_unused qca83xx_tbl[] = {
-       { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
-       { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
-       { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
---- a/drivers/net/phy/qsemi.c
-+++ b/drivers/net/phy/qsemi.c
-@@ -155,7 +155,7 @@ static struct phy_driver qs6612_driver[]
- module_phy_driver(qs6612_driver);
--static struct mdio_device_id __maybe_unused qs6612_tbl[] = {
-+static const struct mdio_device_id __maybe_unused qs6612_tbl[] = {
-       { 0x00181440, 0xfffffff0 },
-       { }
- };
---- a/drivers/net/phy/rockchip.c
-+++ b/drivers/net/phy/rockchip.c
-@@ -188,7 +188,7 @@ static struct phy_driver rockchip_phy_dr
- module_phy_driver(rockchip_phy_driver);
--static struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = {
-+static const struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = {
-       { INTERNAL_EPHY_ID, 0xfffffff0 },
-       { }
- };
---- a/drivers/net/phy/smsc.c
-+++ b/drivers/net/phy/smsc.c
-@@ -885,7 +885,7 @@ MODULE_DESCRIPTION("SMSC PHY driver");
- MODULE_AUTHOR("Herbert Valerio Riedel");
- MODULE_LICENSE("GPL");
--static struct mdio_device_id __maybe_unused smsc_tbl[] = {
-+static const struct mdio_device_id __maybe_unused smsc_tbl[] = {
-       { 0x0007c0a0, 0xfffffff0 },
-       { 0x0007c0b0, 0xfffffff0 },
-       { 0x0007c0c0, 0xfffffff0 },
---- a/drivers/net/phy/ste10Xp.c
-+++ b/drivers/net/phy/ste10Xp.c
-@@ -124,7 +124,7 @@ static struct phy_driver ste10xp_pdriver
- module_phy_driver(ste10xp_pdriver);
--static struct mdio_device_id __maybe_unused ste10Xp_tbl[] = {
-+static const struct mdio_device_id __maybe_unused ste10Xp_tbl[] = {
-       { STE101P_PHY_ID, 0xfffffff0 },
-       { STE100P_PHY_ID, 0xffffffff },
-       { }
---- a/drivers/net/phy/teranetics.c
-+++ b/drivers/net/phy/teranetics.c
-@@ -87,7 +87,7 @@ static struct phy_driver teranetics_driv
- module_phy_driver(teranetics_driver);
--static struct mdio_device_id __maybe_unused teranetics_tbl[] = {
-+static const struct mdio_device_id __maybe_unused teranetics_tbl[] = {
-       { PHY_ID_TN2020, 0xffffffff },
-       { }
- };
---- a/drivers/net/phy/uPD60620.c
-+++ b/drivers/net/phy/uPD60620.c
-@@ -90,7 +90,7 @@ static struct phy_driver upd60620_driver
- module_phy_driver(upd60620_driver);
--static struct mdio_device_id __maybe_unused upd60620_tbl[] = {
-+static const struct mdio_device_id __maybe_unused upd60620_tbl[] = {
-       { UPD60620_PHY_ID, 0xfffffffe },
-       { }
- };
---- a/drivers/net/phy/vitesse.c
-+++ b/drivers/net/phy/vitesse.c
-@@ -674,7 +674,7 @@ static struct phy_driver vsc82xx_driver[
- module_phy_driver(vsc82xx_driver);
--static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
-+static const struct mdio_device_id __maybe_unused vitesse_tbl[] = {
-       { PHY_ID_VSC8234, 0x000ffff0 },
-       { PHY_ID_VSC8244, 0x000fffc0 },
-       { PHY_ID_VSC8572, 0x000ffff0 },
diff --git a/target/linux/generic/backport-6.18/720-10-v6.15-net-phy-mediatek-Change-to-more-meaningful-macros.patch b/target/linux/generic/backport-6.18/720-10-v6.15-net-phy-mediatek-Change-to-more-meaningful-macros.patch
deleted file mode 100644 (file)
index 545e929..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-From 7e06c3dbfa5f1e39eba92eb79d854fab2a7ad5fe Mon Sep 17 00:00:00 2001
-From: Sky Huang <skylake.huang@mediatek.com>
-Date: Thu, 13 Feb 2025 16:05:49 +0800
-Subject: [PATCH 10/20] net: phy: mediatek: Change to more meaningful macros
-
-Replace magic number with more meaningful macros in mtk-ge.c.
-Also, move some common macros into mtk-phy-lib.c.
-
-Signed-off-by: Sky Huang <skylake.huang@mediatek.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250213080553.921434-2-SkyLake.Huang@mediatek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek/mtk-ge-soc.c |  1 -
- drivers/net/phy/mediatek/mtk-ge.c     | 71 +++++++++++++++++++++------
- drivers/net/phy/mediatek/mtk.h        |  2 +
- 3 files changed, 57 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -24,7 +24,6 @@
- #define MTK_PHY_SMI_DET_ON_THRESH_MASK                GENMASK(13, 8)
- #define MTK_PHY_PAGE_EXTENDED_2A30            0x2a30
--#define MTK_PHY_PAGE_EXTENDED_52B5            0x52b5
- #define ANALOG_INTERNAL_OPERATION_MAX_US      20
- #define TXRESERVE_MIN                         0
---- a/drivers/net/phy/mediatek/mtk-ge.c
-+++ b/drivers/net/phy/mediatek/mtk-ge.c
-@@ -8,18 +8,38 @@
- #define MTK_GPHY_ID_MT7530            0x03a29412
- #define MTK_GPHY_ID_MT7531            0x03a29441
--#define MTK_EXT_PAGE_ACCESS           0x1f
--#define MTK_PHY_PAGE_STANDARD         0x0000
--#define MTK_PHY_PAGE_EXTENDED         0x0001
--#define MTK_PHY_PAGE_EXTENDED_2               0x0002
--#define MTK_PHY_PAGE_EXTENDED_3               0x0003
--#define MTK_PHY_PAGE_EXTENDED_2A30    0x2a30
--#define MTK_PHY_PAGE_EXTENDED_52B5    0x52b5
-+#define MTK_PHY_PAGE_EXTENDED_1                       0x0001
-+#define MTK_PHY_AUX_CTRL_AND_STATUS           0x14
-+#define   MTK_PHY_ENABLE_DOWNSHIFT            BIT(4)
-+
-+#define MTK_PHY_PAGE_EXTENDED_2                       0x0002
-+#define MTK_PHY_PAGE_EXTENDED_3                       0x0003
-+#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11     0x11
-+
-+#define MTK_PHY_PAGE_EXTENDED_2A30            0x2a30
-+
-+/* Registers on MDIO_MMD_VEND1 */
-+#define MTK_PHY_GBE_MODE_TX_DELAY_SEL         0x13
-+#define MTK_PHY_TEST_MODE_TX_DELAY_SEL                0x14
-+#define   MTK_TX_DELAY_PAIR_B_MASK            GENMASK(10, 8)
-+#define   MTK_TX_DELAY_PAIR_D_MASK            GENMASK(2, 0)
-+
-+#define MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL    0xa6
-+#define   MTK_MCC_NEARECHO_OFFSET_MASK                GENMASK(15, 8)
-+
-+#define MTK_PHY_RXADC_CTRL_RG7                        0xc6
-+#define   MTK_PHY_DA_AD_BUF_BIAS_LP_MASK      GENMASK(9, 8)
-+
-+#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123    0x123
-+#define   MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK      GENMASK(15, 8)
-+#define   MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK      GENMASK(7, 0)
- static void mtk_gephy_config_init(struct phy_device *phydev)
- {
-       /* Enable HW auto downshift */
--      phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
-+      phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
-+                       MTK_PHY_AUX_CTRL_AND_STATUS,
-+                       0, MTK_PHY_ENABLE_DOWNSHIFT);
-       /* Increase SlvDPSready time */
-       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-@@ -29,10 +49,20 @@ static void mtk_gephy_config_init(struct
-       phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-       /* Adjust 100_mse_threshold */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
--
--      /* Disable mcc */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123,
-+                     MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK |
-+                     MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK,
-+                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK,
-+                                0xff) |
-+                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK,
-+                                0xff));
-+
-+      /* If echo time is narrower than 0x3, it will be regarded as noise */
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                     MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL,
-+                     MTK_MCC_NEARECHO_OFFSET_MASK,
-+                     FIELD_PREP(MTK_MCC_NEARECHO_OFFSET_MASK, 0x3));
- }
- static int mt7530_phy_config_init(struct phy_device *phydev)
-@@ -40,7 +70,8 @@ static int mt7530_phy_config_init(struct
-       mtk_gephy_config_init(phydev);
-       /* Increase post_update_timer */
--      phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
-+      phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3,
-+                      MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11, 0x4b);
-       return 0;
- }
-@@ -51,11 +82,19 @@ static int mt7531_phy_config_init(struct
-       /* PHY link down power saving enable */
-       phy_set_bits(phydev, 0x17, BIT(4));
--      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
-+                     MTK_PHY_DA_AD_BUF_BIAS_LP_MASK,
-+                     FIELD_PREP(MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3));
-       /* Set TX Pair delay selection */
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
--      phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_GBE_MODE_TX_DELAY_SEL,
-+                     MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK,
-+                     FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) |
-+                     FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4));
-+      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TEST_MODE_TX_DELAY_SEL,
-+                     MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK,
-+                     FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) |
-+                     FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4));
-       return 0;
- }
---- a/drivers/net/phy/mediatek/mtk.h
-+++ b/drivers/net/phy/mediatek/mtk.h
-@@ -9,6 +9,8 @@
- #define _MTK_EPHY_H_
- #define MTK_EXT_PAGE_ACCESS                   0x1f
-+#define MTK_PHY_PAGE_STANDARD                 0x0000
-+#define MTK_PHY_PAGE_EXTENDED_52B5            0x52b5
- /* Registers on MDIO_MMD_VEND2 */
- #define MTK_PHY_LED0_ON_CTRL                  0x24
diff --git a/target/linux/generic/backport-6.18/720-11-v6.15-net-phy-mediatek-Add-token-ring-access-helper-functi.patch b/target/linux/generic/backport-6.18/720-11-v6.15-net-phy-mediatek-Add-token-ring-access-helper-functi.patch
deleted file mode 100644 (file)
index 40ce29f..0000000
+++ /dev/null
@@ -1,448 +0,0 @@
-From 6e7370079669b0d55c9464bb7c3fb8fb7368b912 Mon Sep 17 00:00:00 2001
-From: Sky Huang <skylake.huang@mediatek.com>
-Date: Thu, 13 Feb 2025 16:05:50 +0800
-Subject: [PATCH 11/20] net: phy: mediatek: Add token ring access helper
- functions in mtk-phy-lib
-
-This patch adds TR(token ring) manipulations and adds correct
-macro names for those magic numbers. TR is a way to access
-proprietary registers on page 52b5. Use these helper functions
-so we can see which fields we're going to modify/set/clear.
-
-TR functions with __* prefix mean that the operations inside
-aren't wrapped by page select/restore functions.
-
-This patch doesn't really change registers' settings but just
-enhances readability and maintainability.
-
-Signed-off-by: Sky Huang <skylake.huang@mediatek.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250213080553.921434-3-SkyLake.Huang@mediatek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek/mtk-ge-soc.c  | 231 +++++++++++++++++--------
- drivers/net/phy/mediatek/mtk-ge.c      |  11 +-
- drivers/net/phy/mediatek/mtk-phy-lib.c |  63 +++++++
- drivers/net/phy/mediatek/mtk.h         |   5 +
- 4 files changed, 230 insertions(+), 80 deletions(-)
-
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -25,6 +25,90 @@
- #define MTK_PHY_PAGE_EXTENDED_2A30            0x2a30
-+/* Registers on Token Ring debug nodes */
-+/* ch_addr = 0x0, node_addr = 0x7, data_addr = 0x15 */
-+/* NormMseLoThresh */
-+#define NORMAL_MSE_LO_THRESH_MASK             GENMASK(15, 8)
-+
-+/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
-+/* RemAckCntLimitCtrl */
-+#define REMOTE_ACK_COUNT_LIMIT_CTRL_MASK      GENMASK(2, 1)
-+
-+/* ch_addr = 0x1, node_addr = 0xd, data_addr = 0x20 */
-+/* VcoSlicerThreshBitsHigh */
-+#define VCO_SLICER_THRESH_HIGH_MASK           GENMASK(23, 0)
-+
-+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x0 */
-+/* DfeTailEnableVgaThresh1000 */
-+#define DFE_TAIL_EANBLE_VGA_TRHESH_1000               GENMASK(5, 1)
-+
-+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x1 */
-+/* MrvlTrFix100Kp */
-+#define MRVL_TR_FIX_100KP_MASK                        GENMASK(22, 20)
-+/* MrvlTrFix100Kf */
-+#define MRVL_TR_FIX_100KF_MASK                        GENMASK(19, 17)
-+/* MrvlTrFix1000Kp */
-+#define MRVL_TR_FIX_1000KP_MASK                       GENMASK(16, 14)
-+/* MrvlTrFix1000Kf */
-+#define MRVL_TR_FIX_1000KF_MASK                       GENMASK(13, 11)
-+
-+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x12 */
-+/* VgaDecRate */
-+#define VGA_DECIMATION_RATE_MASK              GENMASK(8, 5)
-+
-+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */
-+/* SlvDSPreadyTime */
-+#define SLAVE_DSP_READY_TIME_MASK             GENMASK(22, 15)
-+/* MasDSPreadyTime */
-+#define MASTER_DSP_READY_TIME_MASK            GENMASK(14, 7)
-+
-+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x20 */
-+/* ResetSyncOffset */
-+#define RESET_SYNC_OFFSET_MASK                        GENMASK(11, 8)
-+
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x0 */
-+/* FfeUpdGainForceVal */
-+#define FFE_UPDATE_GAIN_FORCE_VAL_MASK                GENMASK(9, 7)
-+/* FfeUpdGainForce */
-+#define FFE_UPDATE_GAIN_FORCE                 BIT(6)
-+
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x6 */
-+/* SS: Steady-state, KP: Proportional Gain */
-+/* SSTrKp100 */
-+#define SS_TR_KP100_MASK                      GENMASK(21, 19)
-+/* SSTrKf100 */
-+#define SS_TR_KF100_MASK                      GENMASK(18, 16)
-+/* SSTrKp1000Mas */
-+#define SS_TR_KP1000_MASTER_MASK              GENMASK(15, 13)
-+/* SSTrKf1000Mas */
-+#define SS_TR_KF1000_MASTER_MASK              GENMASK(12, 10)
-+/* SSTrKp1000Slv */
-+#define SS_TR_KP1000_SLAVE_MASK                       GENMASK(9, 7)
-+/* SSTrKf1000Slv */
-+#define SS_TR_KF1000_SLAVE_MASK                       GENMASK(6, 4)
-+
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xd */
-+/* RegEEE_st2TrKf1000 */
-+#define EEE1000_STAGE2_TR_KF_MASK             GENMASK(13, 11)
-+
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xf */
-+/* RegEEE_slv_waketr_timer_tar */
-+#define SLAVE_WAKETR_TIMER_MASK                       GENMASK(20, 11)
-+/* RegEEE_slv_remtx_timer_tar */
-+#define SLAVE_REMTX_TIMER_MASK                        GENMASK(10, 1)
-+
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x10 */
-+/* RegEEE_slv_wake_int_timer_tar */
-+#define SLAVE_WAKEINT_TIMER_MASK              GENMASK(10, 1)
-+
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x14 */
-+/* RegEEE_trfreeze_timer2 */
-+#define TR_FREEZE_TIMER2_MASK                 GENMASK(9, 0)
-+
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x1c */
-+/* RegEEE100Stg1_tar */
-+#define EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK        GENMASK(8, 0)
-+
- #define ANALOG_INTERNAL_OPERATION_MAX_US      20
- #define TXRESERVE_MIN                         0
- #define TXRESERVE_MAX                         7
-@@ -700,40 +784,41 @@ restore:
- static void mt798x_phy_common_finetune(struct phy_device *phydev)
- {
-       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
--      __phy_write(phydev, 0x11, 0xc71);
--      __phy_write(phydev, 0x12, 0xc);
--      __phy_write(phydev, 0x10, 0x8fae);
-+      __mtk_tr_modify(phydev, 0x1, 0xf, 0x17,
-+                      SLAVE_DSP_READY_TIME_MASK | MASTER_DSP_READY_TIME_MASK,
-+                      FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x18) |
-+                      FIELD_PREP(MASTER_DSP_READY_TIME_MASK, 0x18));
-       /* EnabRandUpdTrig = 1 */
-       __phy_write(phydev, 0x11, 0x2f00);
-       __phy_write(phydev, 0x12, 0xe);
-       __phy_write(phydev, 0x10, 0x8fb0);
--      /* NormMseLoThresh = 85 */
--      __phy_write(phydev, 0x11, 0x55a0);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x83aa);
--
--      /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
--      __phy_write(phydev, 0x11, 0x240);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x9680);
-+      __mtk_tr_modify(phydev, 0x0, 0x7, 0x15,
-+                      NORMAL_MSE_LO_THRESH_MASK,
-+                      FIELD_PREP(NORMAL_MSE_LO_THRESH_MASK, 0x55));
-+
-+      __mtk_tr_modify(phydev, 0x2, 0xd, 0x0,
-+                      FFE_UPDATE_GAIN_FORCE_VAL_MASK,
-+                      FIELD_PREP(FFE_UPDATE_GAIN_FORCE_VAL_MASK, 0x4) |
-+                                 FFE_UPDATE_GAIN_FORCE);
-       /* TrFreeze = 0 (mt7988 default) */
-       __phy_write(phydev, 0x11, 0x0);
-       __phy_write(phydev, 0x12, 0x0);
-       __phy_write(phydev, 0x10, 0x9686);
--      /* SSTrKp100 = 5 */
--      /* SSTrKf100 = 6 */
--      /* SSTrKp1000Mas = 5 */
--      /* SSTrKf1000Mas = 6 */
--      /* SSTrKp1000Slv = 5 */
--      /* SSTrKf1000Slv = 6 */
--      __phy_write(phydev, 0x11, 0xbaef);
--      __phy_write(phydev, 0x12, 0x2e);
--      __phy_write(phydev, 0x10, 0x968c);
-+      __mtk_tr_modify(phydev, 0x2, 0xd, 0x6,
-+                      SS_TR_KP100_MASK | SS_TR_KF100_MASK |
-+                      SS_TR_KP1000_MASTER_MASK | SS_TR_KF1000_MASTER_MASK |
-+                      SS_TR_KP1000_SLAVE_MASK | SS_TR_KF1000_SLAVE_MASK,
-+                      FIELD_PREP(SS_TR_KP100_MASK, 0x5) |
-+                      FIELD_PREP(SS_TR_KF100_MASK, 0x6) |
-+                      FIELD_PREP(SS_TR_KP1000_MASTER_MASK, 0x5) |
-+                      FIELD_PREP(SS_TR_KF1000_MASTER_MASK, 0x6) |
-+                      FIELD_PREP(SS_TR_KP1000_SLAVE_MASK, 0x5) |
-+                      FIELD_PREP(SS_TR_KF1000_SLAVE_MASK, 0x6));
-+
-       phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
- }
-@@ -756,27 +841,29 @@ static void mt7981_phy_finetune(struct p
-       }
-       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      /* ResetSyncOffset = 6 */
--      __phy_write(phydev, 0x11, 0x600);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x8fc0);
--
--      /* VgaDecRate = 1 */
--      __phy_write(phydev, 0x11, 0x4c2a);
--      __phy_write(phydev, 0x12, 0x3e);
--      __phy_write(phydev, 0x10, 0x8fa4);
-+      __mtk_tr_modify(phydev, 0x1, 0xf, 0x20,
-+                      RESET_SYNC_OFFSET_MASK,
-+                      FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x6));
-+
-+      __mtk_tr_modify(phydev, 0x1, 0xf, 0x12,
-+                      VGA_DECIMATION_RATE_MASK,
-+                      FIELD_PREP(VGA_DECIMATION_RATE_MASK, 0x1));
-       /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
-        * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
-        */
--      __phy_write(phydev, 0x11, 0xd10a);
--      __phy_write(phydev, 0x12, 0x34);
--      __phy_write(phydev, 0x10, 0x8f82);
-+      __mtk_tr_modify(phydev, 0x1, 0xf, 0x1,
-+                      MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK |
-+                      MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK,
-+                      FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x3) |
-+                      FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x2) |
-+                      FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x3) |
-+                      FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x2));
-       /* VcoSlicerThreshBitsHigh */
--      __phy_write(phydev, 0x11, 0x5555);
--      __phy_write(phydev, 0x12, 0x55);
--      __phy_write(phydev, 0x10, 0x8ec0);
-+      __mtk_tr_modify(phydev, 0x1, 0xd, 0x20,
-+                      VCO_SLICER_THRESH_HIGH_MASK,
-+                      FIELD_PREP(VCO_SLICER_THRESH_HIGH_MASK, 0x555555));
-       phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-       /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
-@@ -828,25 +915,23 @@ static void mt7988_phy_finetune(struct p
-       phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
-       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      /* ResetSyncOffset = 5 */
--      __phy_write(phydev, 0x11, 0x500);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x8fc0);
-+      __mtk_tr_modify(phydev, 0x1, 0xf, 0x20,
-+                      RESET_SYNC_OFFSET_MASK,
-+                      FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x5));
-       /* VgaDecRate is 1 at default on mt7988 */
--      /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
--       * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
--       */
--      __phy_write(phydev, 0x11, 0xb90a);
--      __phy_write(phydev, 0x12, 0x6f);
--      __phy_write(phydev, 0x10, 0x8f82);
--
--      /* RemAckCntLimitCtrl = 1 */
--      __phy_write(phydev, 0x11, 0xfbba);
--      __phy_write(phydev, 0x12, 0xc3);
--      __phy_write(phydev, 0x10, 0x87f8);
--
-+      __mtk_tr_modify(phydev, 0x1, 0xf, 0x1,
-+                      MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK |
-+                      MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK,
-+                      FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x6) |
-+                      FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x7) |
-+                      FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x6) |
-+                      FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x7));
-+
-+      __mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
-+                      REMOTE_ACK_COUNT_LIMIT_CTRL_MASK,
-+                      FIELD_PREP(REMOTE_ACK_COUNT_LIMIT_CTRL_MASK, 0x1));
-       phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-       /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
-@@ -927,40 +1012,36 @@ static void mt798x_phy_eee(struct phy_de
-       __phy_write(phydev, 0x12, 0x0);
-       __phy_write(phydev, 0x10, 0x9690);
--      /* REG_EEE_st2TrKf1000 = 2 */
--      __phy_write(phydev, 0x11, 0x114f);
--      __phy_write(phydev, 0x12, 0x2);
--      __phy_write(phydev, 0x10, 0x969a);
--
--      /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
--      __phy_write(phydev, 0x11, 0x3028);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x969e);
--
--      /* RegEEE_slv_wake_int_timer_tar = 8 */
--      __phy_write(phydev, 0x11, 0x5010);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x96a0);
--
--      /* RegEEE_trfreeze_timer2 = 586 */
--      __phy_write(phydev, 0x11, 0x24a);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x96a8);
--
--      /* RegEEE100Stg1_tar = 16 */
--      __phy_write(phydev, 0x11, 0x3210);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x96b8);
-+      __mtk_tr_modify(phydev, 0x2, 0xd, 0xd,
-+                      EEE1000_STAGE2_TR_KF_MASK,
-+                      FIELD_PREP(EEE1000_STAGE2_TR_KF_MASK, 0x2));
-+
-+      __mtk_tr_modify(phydev, 0x2, 0xd, 0xf,
-+                      SLAVE_WAKETR_TIMER_MASK | SLAVE_REMTX_TIMER_MASK,
-+                      FIELD_PREP(SLAVE_WAKETR_TIMER_MASK, 0x6) |
-+                      FIELD_PREP(SLAVE_REMTX_TIMER_MASK, 0x14));
-+
-+      __mtk_tr_modify(phydev, 0x2, 0xd, 0x10,
-+                      SLAVE_WAKEINT_TIMER_MASK,
-+                      FIELD_PREP(SLAVE_WAKEINT_TIMER_MASK, 0x8));
-+
-+      __mtk_tr_modify(phydev, 0x2, 0xd, 0x14,
-+                      TR_FREEZE_TIMER2_MASK,
-+                      FIELD_PREP(TR_FREEZE_TIMER2_MASK, 0x24a));
-+
-+      __mtk_tr_modify(phydev, 0x2, 0xd, 0x1c,
-+                      EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK,
-+                      FIELD_PREP(EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK,
-+                                 0x10));
-       /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
-       __phy_write(phydev, 0x11, 0x1463);
-       __phy_write(phydev, 0x12, 0x0);
-       __phy_write(phydev, 0x10, 0x96ca);
--      /* DfeTailEnableVgaThresh1000 = 27 */
--      __phy_write(phydev, 0x11, 0x36);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x8f80);
-+      __mtk_tr_modify(phydev, 0x1, 0xf, 0x0,
-+                      DFE_TAIL_EANBLE_VGA_TRHESH_1000,
-+                      FIELD_PREP(DFE_TAIL_EANBLE_VGA_TRHESH_1000, 0x1b));
-       phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
---- a/drivers/net/phy/mediatek/mtk-ge.c
-+++ b/drivers/net/phy/mediatek/mtk-ge.c
-@@ -18,6 +18,10 @@
- #define MTK_PHY_PAGE_EXTENDED_2A30            0x2a30
-+/* Registers on Token Ring debug nodes */
-+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */
-+#define SLAVE_DSP_READY_TIME_MASK             GENMASK(22, 15)
-+
- /* Registers on MDIO_MMD_VEND1 */
- #define MTK_PHY_GBE_MODE_TX_DELAY_SEL         0x13
- #define MTK_PHY_TEST_MODE_TX_DELAY_SEL                0x14
-@@ -42,11 +46,8 @@ static void mtk_gephy_config_init(struct
-                        0, MTK_PHY_ENABLE_DOWNSHIFT);
-       /* Increase SlvDPSready time */
--      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      __phy_write(phydev, 0x10, 0xafae);
--      __phy_write(phydev, 0x12, 0x2f);
--      __phy_write(phydev, 0x10, 0x8fae);
--      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+      mtk_tr_modify(phydev, 0x1, 0xf, 0x17, SLAVE_DSP_READY_TIME_MASK,
-+                    FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x5e));
-       /* Adjust 100_mse_threshold */
-       phy_modify_mmd(phydev, MDIO_MMD_VEND1,
---- a/drivers/net/phy/mediatek/mtk-phy-lib.c
-+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
-@@ -6,6 +6,69 @@
- #include "mtk.h"
-+/* Difference between functions with mtk_tr* and __mtk_tr* prefixes is
-+ * mtk_tr* functions: wrapped by page switching operations
-+ * __mtk_tr* functions: no page switching operations
-+ */
-+
-+static void __mtk_tr_access(struct phy_device *phydev, bool read, u8 ch_addr,
-+                          u8 node_addr, u8 data_addr)
-+{
-+      u16 tr_cmd = BIT(15); /* bit 14 & 0 are reserved */
-+
-+      if (read)
-+              tr_cmd |= BIT(13);
-+
-+      tr_cmd |= (((ch_addr & 0x3) << 11) |
-+                 ((node_addr & 0xf) << 7) |
-+                 ((data_addr & 0x3f) << 1));
-+      dev_dbg(&phydev->mdio.dev, "tr_cmd: 0x%x\n", tr_cmd);
-+      __phy_write(phydev, 0x10, tr_cmd);
-+}
-+
-+static void __mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                        u8 data_addr, u16 *tr_high, u16 *tr_low)
-+{
-+      __mtk_tr_access(phydev, true, ch_addr, node_addr, data_addr);
-+      *tr_low = __phy_read(phydev, 0x11);
-+      *tr_high = __phy_read(phydev, 0x12);
-+      dev_dbg(&phydev->mdio.dev, "tr_high read: 0x%x, tr_low read: 0x%x\n",
-+              *tr_high, *tr_low);
-+}
-+
-+static void __mtk_tr_write(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                         u8 data_addr, u32 tr_data)
-+{
-+      __phy_write(phydev, 0x11, tr_data & 0xffff);
-+      __phy_write(phydev, 0x12, tr_data >> 16);
-+      dev_dbg(&phydev->mdio.dev, "tr_high write: 0x%x, tr_low write: 0x%x\n",
-+              tr_data >> 16, tr_data & 0xffff);
-+      __mtk_tr_access(phydev, false, ch_addr, node_addr, data_addr);
-+}
-+
-+void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                   u8 data_addr, u32 mask, u32 set)
-+{
-+      u32 tr_data;
-+      u16 tr_high;
-+      u16 tr_low;
-+
-+      __mtk_tr_read(phydev, ch_addr, node_addr, data_addr, &tr_high, &tr_low);
-+      tr_data = (tr_high << 16) | tr_low;
-+      tr_data = (tr_data & ~mask) | set;
-+      __mtk_tr_write(phydev, ch_addr, node_addr, data_addr, tr_data);
-+}
-+EXPORT_SYMBOL_GPL(__mtk_tr_modify);
-+
-+void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                 u8 data_addr, u32 mask, u32 set)
-+{
-+      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-+      __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, mask, set);
-+      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+}
-+EXPORT_SYMBOL_GPL(mtk_tr_modify);
-+
- int mtk_phy_read_page(struct phy_device *phydev)
- {
-       return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
---- a/drivers/net/phy/mediatek/mtk.h
-+++ b/drivers/net/phy/mediatek/mtk.h
-@@ -68,6 +68,11 @@ struct mtk_socphy_priv {
-       unsigned long           led_state;
- };
-+void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                   u8 data_addr, u32 mask, u32 set);
-+void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                 u8 data_addr, u32 mask, u32 set);
-+
- int mtk_phy_read_page(struct phy_device *phydev);
- int mtk_phy_write_page(struct phy_device *phydev, int page);
diff --git a/target/linux/generic/backport-6.18/720-12-v6.15-net-phy-mediatek-Add-token-ring-set-bit-operation-su.patch b/target/linux/generic/backport-6.18/720-12-v6.15-net-phy-mediatek-Add-token-ring-set-bit-operation-su.patch
deleted file mode 100644 (file)
index 972a9c0..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-From c7e2fb3421ef5ebbb4c91f44bd735ab10edd755a Mon Sep 17 00:00:00 2001
-From: Sky Huang <skylake.huang@mediatek.com>
-Date: Thu, 13 Feb 2025 16:05:51 +0800
-Subject: [PATCH 12/20] net: phy: mediatek: Add token ring set bit operation
- support
-
-Previously in mtk-ge-soc.c, we set some register bits via token
-ring, which were implemented in three __phy_write().
-Now we can do the same thing via __mtk_tr_set_bits() helper.
-
-Signed-off-by: Sky Huang <skylake.huang@mediatek.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250213080553.921434-4-SkyLake.Huang@mediatek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek/mtk-ge-soc.c  | 10 ++++++----
- drivers/net/phy/mediatek/mtk-phy-lib.c |  7 +++++++
- drivers/net/phy/mediatek/mtk.h         |  2 ++
- 3 files changed, 15 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -62,6 +62,10 @@
- /* MasDSPreadyTime */
- #define MASTER_DSP_READY_TIME_MASK            GENMASK(14, 7)
-+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x18 */
-+/* EnabRandUpdTrig */
-+#define ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER  BIT(8)
-+
- /* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x20 */
- /* ResetSyncOffset */
- #define RESET_SYNC_OFFSET_MASK                        GENMASK(11, 8)
-@@ -789,10 +793,8 @@ static void mt798x_phy_common_finetune(s
-                       FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x18) |
-                       FIELD_PREP(MASTER_DSP_READY_TIME_MASK, 0x18));
--      /* EnabRandUpdTrig = 1 */
--      __phy_write(phydev, 0x11, 0x2f00);
--      __phy_write(phydev, 0x12, 0xe);
--      __phy_write(phydev, 0x10, 0x8fb0);
-+      __mtk_tr_set_bits(phydev, 0x1, 0xf, 0x18,
-+                        ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER);
-       __mtk_tr_modify(phydev, 0x0, 0x7, 0x15,
-                       NORMAL_MSE_LO_THRESH_MASK,
---- a/drivers/net/phy/mediatek/mtk-phy-lib.c
-+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
-@@ -69,6 +69,13 @@ void mtk_tr_modify(struct phy_device *ph
- }
- EXPORT_SYMBOL_GPL(mtk_tr_modify);
-+void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                     u8 data_addr, u32 set)
-+{
-+      __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, 0, set);
-+}
-+EXPORT_SYMBOL_GPL(__mtk_tr_set_bits);
-+
- int mtk_phy_read_page(struct phy_device *phydev)
- {
-       return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
---- a/drivers/net/phy/mediatek/mtk.h
-+++ b/drivers/net/phy/mediatek/mtk.h
-@@ -72,6 +72,8 @@ void __mtk_tr_modify(struct phy_device *
-                    u8 data_addr, u32 mask, u32 set);
- void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-                  u8 data_addr, u32 mask, u32 set);
-+void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                     u8 data_addr, u32 set);
- int mtk_phy_read_page(struct phy_device *phydev);
- int mtk_phy_write_page(struct phy_device *phydev, int page);
diff --git a/target/linux/generic/backport-6.18/720-13-v6.15-net-phy-mediatek-Add-token-ring-clear-bit-operation-.patch b/target/linux/generic/backport-6.18/720-13-v6.15-net-phy-mediatek-Add-token-ring-clear-bit-operation-.patch
deleted file mode 100644 (file)
index 47d891e..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-From 7851c73a416b15aff6f9ada9c88affc5f48ff011 Mon Sep 17 00:00:00 2001
-From: Sky Huang <skylake.huang@mediatek.com>
-Date: Thu, 13 Feb 2025 16:05:52 +0800
-Subject: [PATCH 13/20] net: phy: mediatek: Add token ring clear bit operation
- support
-
-Similar to __mtk_tr_set_bits() support. Previously in mtk-ge-soc.c,
-we clear some register bits via token ring, which were also implemented
-in three __phy_write(). Now we can do the same thing via
-__mtk_tr_clr_bits() helper.
-
-Signed-off-by: Sky Huang <skylake.huang@mediatek.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250213080553.921434-5-SkyLake.Huang@mediatek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek/mtk-ge-soc.c  | 30 +++++++++++++++-----------
- drivers/net/phy/mediatek/mtk-phy-lib.c |  7 ++++++
- drivers/net/phy/mediatek/mtk.h         |  2 ++
- 3 files changed, 27 insertions(+), 12 deletions(-)
-
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -76,6 +76,10 @@
- /* FfeUpdGainForce */
- #define FFE_UPDATE_GAIN_FORCE                 BIT(6)
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x3 */
-+/* TrFreeze */
-+#define TR_FREEZE_MASK                                GENMASK(11, 0)
-+
- /* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x6 */
- /* SS: Steady-state, KP: Proportional Gain */
- /* SSTrKp100 */
-@@ -91,6 +95,11 @@
- /* SSTrKf1000Slv */
- #define SS_TR_KF1000_SLAVE_MASK                       GENMASK(6, 4)
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x8 */
-+/* clear this bit if wanna select from AFE */
-+/* Regsigdet_sel_1000 */
-+#define EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE      BIT(4)
-+
- /* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xd */
- /* RegEEE_st2TrKf1000 */
- #define EEE1000_STAGE2_TR_KF_MASK             GENMASK(13, 11)
-@@ -113,6 +122,10 @@
- /* RegEEE100Stg1_tar */
- #define EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK        GENMASK(8, 0)
-+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x25 */
-+/* REGEEE_wake_slv_tr_wait_dfesigdet_en */
-+#define WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN   BIT(11)
-+
- #define ANALOG_INTERNAL_OPERATION_MAX_US      20
- #define TXRESERVE_MIN                         0
- #define TXRESERVE_MAX                         7
-@@ -805,10 +818,7 @@ static void mt798x_phy_common_finetune(s
-                       FIELD_PREP(FFE_UPDATE_GAIN_FORCE_VAL_MASK, 0x4) |
-                                  FFE_UPDATE_GAIN_FORCE);
--      /* TrFreeze = 0 (mt7988 default) */
--      __phy_write(phydev, 0x11, 0x0);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x9686);
-+      __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x3, TR_FREEZE_MASK);
-       __mtk_tr_modify(phydev, 0x2, 0xd, 0x6,
-                       SS_TR_KP100_MASK | SS_TR_KF100_MASK |
-@@ -1009,10 +1019,8 @@ static void mt798x_phy_eee(struct phy_de
-                        MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
-       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--      /* Regsigdet_sel_1000 = 0 */
--      __phy_write(phydev, 0x11, 0xb);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x9690);
-+      __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x8,
-+                        EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE);
-       __mtk_tr_modify(phydev, 0x2, 0xd, 0xd,
-                       EEE1000_STAGE2_TR_KF_MASK,
-@@ -1036,10 +1044,8 @@ static void mt798x_phy_eee(struct phy_de
-                       FIELD_PREP(EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK,
-                                  0x10));
--      /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
--      __phy_write(phydev, 0x11, 0x1463);
--      __phy_write(phydev, 0x12, 0x0);
--      __phy_write(phydev, 0x10, 0x96ca);
-+      __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x25,
-+                        WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN);
-       __mtk_tr_modify(phydev, 0x1, 0xf, 0x0,
-                       DFE_TAIL_EANBLE_VGA_TRHESH_1000,
---- a/drivers/net/phy/mediatek/mtk-phy-lib.c
-+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
-@@ -76,6 +76,13 @@ void __mtk_tr_set_bits(struct phy_device
- }
- EXPORT_SYMBOL_GPL(__mtk_tr_set_bits);
-+void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                     u8 data_addr, u32 clr)
-+{
-+      __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, clr, 0);
-+}
-+EXPORT_SYMBOL_GPL(__mtk_tr_clr_bits);
-+
- int mtk_phy_read_page(struct phy_device *phydev)
- {
-       return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
---- a/drivers/net/phy/mediatek/mtk.h
-+++ b/drivers/net/phy/mediatek/mtk.h
-@@ -74,6 +74,8 @@ void mtk_tr_modify(struct phy_device *ph
-                  u8 data_addr, u32 mask, u32 set);
- void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-                      u8 data_addr, u32 set);
-+void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
-+                     u8 data_addr, u32 clr);
- int mtk_phy_read_page(struct phy_device *phydev);
- int mtk_phy_write_page(struct phy_device *phydev, int page);
diff --git a/target/linux/generic/backport-6.18/720-14-v6.15-net-phy-mediatek-Move-some-macros-to-phy-lib-for-lat.patch b/target/linux/generic/backport-6.18/720-14-v6.15-net-phy-mediatek-Move-some-macros-to-phy-lib-for-lat.patch
deleted file mode 100644 (file)
index 858de09..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From bae8c61522c4d5a5250a24dcb57d120ea593fab1 Mon Sep 17 00:00:00 2001
-From: Sky Huang <skylake.huang@mediatek.com>
-Date: Thu, 13 Feb 2025 16:05:53 +0800
-Subject: [PATCH 14/20] net: phy: mediatek: Move some macros to phy-lib for
- later use
-
-Move some macros to phy-lib because MediaTek's 2.5G built-in
-ethernet PHY will also use them.
-
-Signed-off-by: Sky Huang <skylake.huang@mediatek.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250213080553.921434-6-SkyLake.Huang@mediatek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek/mtk-ge.c | 4 ----
- drivers/net/phy/mediatek/mtk.h    | 4 ++++
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/mediatek/mtk-ge.c
-+++ b/drivers/net/phy/mediatek/mtk-ge.c
-@@ -8,10 +8,6 @@
- #define MTK_GPHY_ID_MT7530            0x03a29412
- #define MTK_GPHY_ID_MT7531            0x03a29441
--#define MTK_PHY_PAGE_EXTENDED_1                       0x0001
--#define MTK_PHY_AUX_CTRL_AND_STATUS           0x14
--#define   MTK_PHY_ENABLE_DOWNSHIFT            BIT(4)
--
- #define MTK_PHY_PAGE_EXTENDED_2                       0x0002
- #define MTK_PHY_PAGE_EXTENDED_3                       0x0003
- #define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11     0x11
---- a/drivers/net/phy/mediatek/mtk.h
-+++ b/drivers/net/phy/mediatek/mtk.h
-@@ -8,7 +8,11 @@
- #ifndef _MTK_EPHY_H_
- #define _MTK_EPHY_H_
-+#define MTK_PHY_AUX_CTRL_AND_STATUS           0x14
-+#define   MTK_PHY_ENABLE_DOWNSHIFT            BIT(4)
-+
- #define MTK_EXT_PAGE_ACCESS                   0x1f
-+#define MTK_PHY_PAGE_EXTENDED_1                       0x0001
- #define MTK_PHY_PAGE_STANDARD                 0x0000
- #define MTK_PHY_PAGE_EXTENDED_52B5            0x52b5
diff --git a/target/linux/generic/backport-6.18/720-15-v6.16-net-phy-mediatek-permit-to-compile-test-GE-SOC-PHY-d.patch b/target/linux/generic/backport-6.18/720-15-v6.16-net-phy-mediatek-permit-to-compile-test-GE-SOC-PHY-d.patch
deleted file mode 100644 (file)
index 9778ea1..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From e5566162af8b9690e096d2e6089e4ed955a0d13d Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 10 Apr 2025 12:04:03 +0200
-Subject: [PATCH] net: phy: mediatek: permit to compile test GE SOC PHY driver
-
-When commit 462a3daad679 ("net: phy: mediatek: fix compile-test
-dependencies") fixed the dependency, it should have also introduced
-an or on COMPILE_TEST to permit this driver to be compile-tested even if
-NVMEM_MTK_EFUSE wasn't selected. The driver makes use of NVMEM API that
-are always compiled (return error) so the driver can actually be
-compiled even without that config.
-
-Fix and simplify the dependency condition of this kernel config.
-
-Fixes: 462a3daad679 ("net: phy: mediatek: fix compile-test dependencies")
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Acked-by: Arnd Bergmann <arnd@arndb.de>
-Link: https://patch.msgid.link/20250410100410.348-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek/Kconfig | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/phy/mediatek/Kconfig
-+++ b/drivers/net/phy/mediatek/Kconfig
-@@ -15,8 +15,7 @@ config MEDIATEK_GE_PHY
- config MEDIATEK_GE_SOC_PHY
-       tristate "MediaTek SoC Ethernet PHYs"
--      depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
--      depends on NVMEM_MTK_EFUSE
-+      depends on (ARM64 && ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || COMPILE_TEST
-       select MTK_NET_PHYLIB
-       help
-         Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
diff --git a/target/linux/generic/backport-6.18/720-16-v6.16-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch b/target/linux/generic/backport-6.18/720-16-v6.16-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch
deleted file mode 100644 (file)
index 5498ecb..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-From 4590c8bc10951feee3e439bf7fff1b458c2e6fad Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 10 Apr 2025 12:04:04 +0200
-Subject: [PATCH 17/20] net: phy: mediatek: add Airoha PHY ID to SoC driver
-
-Airoha AN7581 SoC ship with a Switch based on the MT753x Switch embedded
-in other SoC like the MT7581 and the MT7988. Similar to these they
-require configuring some pin to enable LED PHYs.
-
-Add support for the PHY ID for the Airoha embedded Switch and define a
-simple probe function to toggle these pins. Also fill the LED functions
-and add dedicated function to define LED polarity.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://patch.msgid.link/20250410100410.348-2-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek/Kconfig      |  4 +-
- drivers/net/phy/mediatek/mtk-ge-soc.c | 62 +++++++++++++++++++++++++++
- 2 files changed, 65 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/mediatek/Kconfig
-+++ b/drivers/net/phy/mediatek/Kconfig
-@@ -15,7 +15,9 @@ config MEDIATEK_GE_PHY
- config MEDIATEK_GE_SOC_PHY
-       tristate "MediaTek SoC Ethernet PHYs"
--      depends on (ARM64 && ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || COMPILE_TEST
-+      depends on ARM64 || COMPILE_TEST
-+      depends on ARCH_AIROHA || (ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || \
-+                 COMPILE_TEST
-       select MTK_NET_PHYLIB
-       help
-         Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -10,8 +10,11 @@
- #include "mtk.h"
-+#define MTK_PHY_MAX_LEDS                      2
-+
- #define MTK_GPHY_ID_MT7981                    0x03a29461
- #define MTK_GPHY_ID_MT7988                    0x03a29481
-+#define MTK_GPHY_ID_AN7581                    0x03a294c1
- #define MTK_EXT_PAGE_ACCESS                   0x1f
- #define MTK_PHY_PAGE_STANDARD                 0x0000
-@@ -1405,6 +1408,53 @@ static int mt7981_phy_probe(struct phy_d
-       return mt798x_phy_calibration(phydev);
- }
-+static int an7581_phy_probe(struct phy_device *phydev)
-+{
-+      struct mtk_socphy_priv *priv;
-+      struct pinctrl *pinctrl;
-+
-+      /* Toggle pinctrl to enable PHY LED */
-+      pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
-+      if (IS_ERR(pinctrl))
-+              dev_err(&phydev->mdio.bus->dev,
-+                      "Failed to setup PHY LED pinctrl\n");
-+
-+      priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+
-+      phydev->priv = priv;
-+
-+      return 0;
-+}
-+
-+static int an7581_phy_led_polarity_set(struct phy_device *phydev, int index,
-+                                     unsigned long modes)
-+{
-+      u32 mode;
-+      u16 val;
-+
-+      if (index >= MTK_PHY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-+              switch (mode) {
-+              case PHY_LED_ACTIVE_LOW:
-+                      val = MTK_PHY_LED_ON_POLARITY;
-+                      break;
-+              case PHY_LED_ACTIVE_HIGH:
-+                      val = 0;
-+                      break;
-+              default:
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
-+                            MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
-+                            MTK_PHY_LED_ON_POLARITY, val);
-+}
-+
- static struct phy_driver mtk_socphy_driver[] = {
-       {
-               PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
-@@ -1440,6 +1490,17 @@ static struct phy_driver mtk_socphy_driv
-               .led_hw_control_set = mt798x_phy_led_hw_control_set,
-               .led_hw_control_get = mt798x_phy_led_hw_control_get,
-       },
-+      {
-+              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581),
-+              .name           = "Airoha AN7581 PHY",
-+              .probe          = an7581_phy_probe,
-+              .led_blink_set  = mt798x_phy_led_blink_set,
-+              .led_brightness_set = mt798x_phy_led_brightness_set,
-+              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
-+              .led_hw_control_set = mt798x_phy_led_hw_control_set,
-+              .led_hw_control_get = mt798x_phy_led_hw_control_get,
-+              .led_polarity_set = an7581_phy_led_polarity_set,
-+      },
- };
- module_phy_driver(mtk_socphy_driver);
-@@ -1447,6 +1508,7 @@ module_phy_driver(mtk_socphy_driver);
- static const struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
-       { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
-       { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
-+      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581) },
-       { }
- };
diff --git a/target/linux/generic/backport-6.18/720-17-v6.16-net-phy-mediatek-init-val-in-.phy_led_polarity_set-f.patch b/target/linux/generic/backport-6.18/720-17-v6.16-net-phy-mediatek-init-val-in-.phy_led_polarity_set-f.patch
deleted file mode 100644 (file)
index 1b1dda2..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From 34501d047ac0a6cbb13285ba9d15f75c1deb7da7 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Tue, 15 Apr 2025 12:53:05 +0200
-Subject: [PATCH 18/20] net: phy: mediatek: init val in .phy_led_polarity_set
- for AN7581
-
-Fix smatch warning for uninitialised val in .phy_led_polarity_set for
-AN7581 driver.
-
-Correctly init to 0 to set polarity high by default.
-
-Reported-by: Simon Horman <horms@kernel.org>
-Fixes: 6a325aed130b ("net: phy: mediatek: add Airoha PHY ID to SoC driver")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://patch.msgid.link/20250415105313.3409-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek/mtk-ge-soc.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/phy/mediatek/mtk-ge-soc.c
-+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
-@@ -1431,8 +1431,8 @@ static int an7581_phy_probe(struct phy_d
- static int an7581_phy_led_polarity_set(struct phy_device *phydev, int index,
-                                      unsigned long modes)
- {
-+      u16 val = 0;
-       u32 mode;
--      u16 val;
-       if (index >= MTK_PHY_MAX_LEDS)
-               return -EINVAL;
-@@ -1443,7 +1443,6 @@ static int an7581_phy_led_polarity_set(s
-                       val = MTK_PHY_LED_ON_POLARITY;
-                       break;
-               case PHY_LED_ACTIVE_HIGH:
--                      val = 0;
-                       break;
-               default:
-                       return -EINVAL;
diff --git a/target/linux/generic/backport-6.18/721-01-v6.15-net-ethernet-mediatek-add-EEE-support.patch b/target/linux/generic/backport-6.18/721-01-v6.15-net-ethernet-mediatek-add-EEE-support.patch
deleted file mode 100644 (file)
index 7a94897..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-From 952d7325362ffbefa6ce5619fb4e53c2159ec7a7 Mon Sep 17 00:00:00 2001
-From: Qingfang Deng <dqfext@gmail.com>
-Date: Mon, 17 Feb 2025 17:40:21 +0800
-Subject: [PATCH] net: ethernet: mediatek: add EEE support
-
-Add EEE support to MediaTek SoC Ethernet. The register fields are
-similar to the ones in MT7531, except that the LPI threshold is in
-milliseconds.
-
-Signed-off-by: Qingfang Deng <dqfext@gmail.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 64 +++++++++++++++++++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 ++++
- 2 files changed, 75 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -782,6 +782,7 @@ static void mtk_mac_link_up(struct phyli
-       mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-       mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
-+               MAC_MCR_EEE100M | MAC_MCR_EEE1G |
-                MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
-                MAC_MCR_FORCE_RX_FC);
-@@ -807,6 +808,15 @@ static void mtk_mac_link_up(struct phyli
-       if (rx_pause)
-               mcr |= MAC_MCR_FORCE_RX_FC;
-+      if (mode == MLO_AN_PHY && phy && mac->tx_lpi_enabled && phy_init_eee(phy, false) >= 0) {
-+              mcr |= MAC_MCR_EEE100M | MAC_MCR_EEE1G;
-+              mtk_w32(mac->hw,
-+                      FIELD_PREP(MAC_EEE_WAKEUP_TIME_1000, 17) |
-+                      FIELD_PREP(MAC_EEE_WAKEUP_TIME_100, 36) |
-+                      FIELD_PREP(MAC_EEE_LPI_TXIDLE_THD, mac->txidle_thd_ms),
-+                      MTK_MAC_EEECR(mac->id));
-+      }
-+
-       mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK;
-       mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-@@ -4523,6 +4533,61 @@ static int mtk_set_pauseparam(struct net
-       return phylink_ethtool_set_pauseparam(mac->phylink, pause);
- }
-+static int mtk_get_eee(struct net_device *dev, struct ethtool_keee *eee)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      u32 reg;
-+      int ret;
-+
-+      ret = phylink_ethtool_get_eee(mac->phylink, eee);
-+      if (ret)
-+              return ret;
-+
-+      reg = mtk_r32(mac->hw, MTK_MAC_EEECR(mac->id));
-+      eee->tx_lpi_enabled = mac->tx_lpi_enabled;
-+      eee->tx_lpi_timer = FIELD_GET(MAC_EEE_LPI_TXIDLE_THD, reg) * 1000;
-+
-+      return 0;
-+}
-+
-+static int mtk_set_eee(struct net_device *dev, struct ethtool_keee *eee)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      u32 txidle_thd_ms, reg;
-+      int ret;
-+
-+      /* Tx idle timer in ms */
-+      txidle_thd_ms = DIV_ROUND_UP(eee->tx_lpi_timer, 1000);
-+      if (!FIELD_FIT(MAC_EEE_LPI_TXIDLE_THD, txidle_thd_ms))
-+              return -EINVAL;
-+
-+      reg = FIELD_PREP(MAC_EEE_LPI_TXIDLE_THD, txidle_thd_ms);
-+
-+      /* PHY Wake-up time, this field does not have a reset value, so use the
-+       * reset value from MT7531 (36us for 100BaseT and 17us for 1000BaseT).
-+       */
-+      reg |= FIELD_PREP(MAC_EEE_WAKEUP_TIME_1000, 17) |
-+             FIELD_PREP(MAC_EEE_WAKEUP_TIME_100, 36);
-+
-+      if (!txidle_thd_ms)
-+              /* Force LPI Mode without a delay */
-+              reg |= MAC_EEE_LPI_MODE;
-+
-+      ret = phylink_ethtool_set_eee(mac->phylink, eee);
-+      if (ret)
-+              return ret;
-+
-+      mac->tx_lpi_enabled = eee->tx_lpi_enabled;
-+      mac->txidle_thd_ms = txidle_thd_ms;
-+      mtk_w32(mac->hw, reg, MTK_MAC_EEECR(mac->id));
-+      if (eee->eee_enabled && eee->eee_active && eee->tx_lpi_enabled)
-+              mtk_m32(mac->hw, 0, MAC_MCR_EEE100M | MAC_MCR_EEE1G, MTK_MAC_MCR(mac->id));
-+      else
-+              mtk_m32(mac->hw, MAC_MCR_EEE100M | MAC_MCR_EEE1G, 0, MTK_MAC_MCR(mac->id));
-+
-+      return 0;
-+}
-+
- static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb,
-                           struct net_device *sb_dev)
- {
-@@ -4555,6 +4620,8 @@ static const struct ethtool_ops mtk_etht
-       .set_pauseparam         = mtk_set_pauseparam,
-       .get_rxnfc              = mtk_get_rxnfc,
-       .set_rxnfc              = mtk_set_rxnfc,
-+      .get_eee                = mtk_get_eee,
-+      .set_eee                = mtk_set_eee,
- };
- static const struct net_device_ops mtk_netdev_ops = {
-@@ -4615,6 +4682,8 @@ static int mtk_add_mac(struct mtk_eth *e
-       }
-       mac = netdev_priv(eth->netdev[id]);
-       eth->mac[id] = mac;
-+      mac->tx_lpi_enabled = true;
-+      mac->txidle_thd_ms = 1;
-       mac->id = id;
-       mac->hw = eth;
-       mac->of_node = np;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -461,6 +461,8 @@
- #define MAC_MCR_RX_FIFO_CLR_DIS       BIT(12)
- #define MAC_MCR_BACKOFF_EN    BIT(9)
- #define MAC_MCR_BACKPR_EN     BIT(8)
-+#define MAC_MCR_EEE1G         BIT(7)
-+#define MAC_MCR_EEE100M               BIT(6)
- #define MAC_MCR_FORCE_RX_FC   BIT(5)
- #define MAC_MCR_FORCE_TX_FC   BIT(4)
- #define MAC_MCR_SPEED_1000    BIT(3)
-@@ -469,6 +471,15 @@
- #define MAC_MCR_FORCE_LINK    BIT(0)
- #define MAC_MCR_FORCE_LINK_DOWN       (MAC_MCR_FORCE_MODE)
-+/* Mac EEE control registers */
-+#define MTK_MAC_EEECR(x)              (0x10104 + (x * 0x100))
-+#define MAC_EEE_WAKEUP_TIME_1000      GENMASK(31, 24)
-+#define MAC_EEE_WAKEUP_TIME_100               GENMASK(23, 16)
-+#define MAC_EEE_LPI_TXIDLE_THD                GENMASK(15, 8)
-+#define MAC_EEE_CKG_TXIDLE            BIT(3)
-+#define MAC_EEE_CKG_RXLPI             BIT(2)
-+#define MAC_EEE_LPI_MODE              BIT(0)
-+
- /* Mac status registers */
- #define MTK_MAC_MSR(x)                (0x10108 + (x * 0x100))
- #define MAC_MSR_EEE1G         BIT(7)
-@@ -1316,6 +1327,8 @@ struct mtk_mac {
-       int                             id;
-       phy_interface_t                 interface;
-       u8                              ppe_idx;
-+      bool                            tx_lpi_enabled;
-+      u8                              txidle_thd_ms;
-       int                             speed;
-       struct device_node              *of_node;
-       struct phylink                  *phylink;
diff --git a/target/linux/generic/backport-6.18/730-01-v6.13-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch b/target/linux/generic/backport-6.18/730-01-v6.13-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch
deleted file mode 100644 (file)
index aabaa33..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-From a2e1ba275eae96a8171deb19e9c7c2f5978fee7b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 4 Oct 2024 17:18:16 +0100
-Subject: [PATCH] net: phy: aquantia: allow forcing order of MDI pairs
-
-Despite supporting Auto MDI-X, it looks like Aquantia only supports
-swapping pair (1,2) with pair (3,6) like it used to be for MDI-X on
-100MBit/s networks.
-
-When all 4 pairs are in use (for 1000MBit/s or faster) the link does not
-come up with pair order is not configured correctly, either using
-MDI_CFG pin or using the "PMA Receive Reserved Vendor Provisioning 1"
-register.
-
-Normally, the order of MDI pairs being either ABCD or DCBA is configured
-by pulling the MDI_CFG pin.
-
-However, some hardware designs require overriding the value configured
-by that bootstrap pin. The PHY allows doing that by setting a bit in
-"PMA Receive Reserved Vendor Provisioning 1" register which allows
-ignoring the state of the MDI_CFG pin and another bit configuring
-whether the order of MDI pairs should be normal (ABCD) or reverse
-(DCBA). Pair polarity is not affected and remains identical in both
-settings.
-
-Introduce property "marvell,mdi-cfg-order" which allows forcing either
-normal or reverse order of the MDI pairs from DT.
-
-If the property isn't present, the behavior is unchanged and MDI pair
-order configuration is untouched (ie. either the result of MDI_CFG pin
-pull-up/pull-down, or pair order override already configured by the
-bootloader before Linux is started).
-
-Forcing normal pair order is required on the Adtran SDG-8733A Wi-Fi 7
-residential gateway.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/9ed760ff87d5fc456f31e407ead548bbb754497d.1728058550.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/aquantia/aquantia_main.c | 33 ++++++++++++++++++++++++
- 1 file changed, 33 insertions(+)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -11,6 +11,7 @@
- #include <linux/module.h>
- #include <linux/delay.h>
- #include <linux/bitfield.h>
-+#include <linux/of.h>
- #include <linux/phy.h>
- #include "aquantia.h"
-@@ -71,6 +72,11 @@
- #define MDIO_AN_TX_VEND_INT_MASK2             0xd401
- #define MDIO_AN_TX_VEND_INT_MASK2_LINK                BIT(0)
-+#define PMAPMD_RSVD_VEND_PROV                 0xe400
-+#define PMAPMD_RSVD_VEND_PROV_MDI_CONF                GENMASK(1, 0)
-+#define PMAPMD_RSVD_VEND_PROV_MDI_REVERSE     BIT(0)
-+#define PMAPMD_RSVD_VEND_PROV_MDI_FORCE               BIT(1)
-+
- #define MDIO_AN_RX_LP_STAT1                   0xe820
- #define MDIO_AN_RX_LP_STAT1_1000BASET_FULL    BIT(15)
- #define MDIO_AN_RX_LP_STAT1_1000BASET_HALF    BIT(14)
-@@ -485,6 +491,29 @@ static void aqr107_chip_info(struct phy_
-                  fw_major, fw_minor, build_id, prov_id);
- }
-+static int aqr107_config_mdi(struct phy_device *phydev)
-+{
-+      struct device_node *np = phydev->mdio.dev.of_node;
-+      u32 mdi_conf;
-+      int ret;
-+
-+      ret = of_property_read_u32(np, "marvell,mdi-cfg-order", &mdi_conf);
-+
-+      /* Do nothing in case property "marvell,mdi-cfg-order" is not present */
-+      if (ret == -ENOENT)
-+              return 0;
-+
-+      if (ret)
-+              return ret;
-+
-+      if (mdi_conf & ~PMAPMD_RSVD_VEND_PROV_MDI_REVERSE)
-+              return -EINVAL;
-+
-+      return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_RSVD_VEND_PROV,
-+                            PMAPMD_RSVD_VEND_PROV_MDI_CONF,
-+                            mdi_conf | PMAPMD_RSVD_VEND_PROV_MDI_FORCE);
-+}
-+
- static int aqr107_config_init(struct phy_device *phydev)
- {
-       struct aqr107_priv *priv = phydev->priv;
-@@ -514,6 +543,10 @@ static int aqr107_config_init(struct phy
-       if (ret)
-               return ret;
-+      ret = aqr107_config_mdi(phydev);
-+      if (ret)
-+              return ret;
-+
-       /* Restore LED polarity state after reset */
-       for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {
-               ret = aqr_phy_led_active_low_set(phydev, led_active_low, true);
diff --git a/target/linux/generic/backport-6.18/730-02-v6.13-net-phy-aquantia-fix-return-value-check-in-aqr107_co.patch b/target/linux/generic/backport-6.18/730-02-v6.13-net-phy-aquantia-fix-return-value-check-in-aqr107_co.patch
deleted file mode 100644 (file)
index 565edbd..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From ce21b8fb255ebf0b49913fb4c62741d7eb05c6f6 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 11 Oct 2024 22:28:43 +0100
-Subject: [PATCH] net: phy: aquantia: fix return value check in
- aqr107_config_mdi()
-
-of_property_read_u32() returns -EINVAL in case the property cannot be
-found rather than -ENOENT. Fix the check to not abort probing in case
-of the property being missing, and also in case CONFIG_OF is not set
-which will result in -ENOSYS.
-
-Fixes: a2e1ba275eae ("net: phy: aquantia: allow forcing order of MDI pairs")
-Reported-by: Jon Hunter <jonathanh@nvidia.com>
-Closes: https://lore.kernel.org/all/114b4c03-5d16-42ed-945d-cf78eabea12b@nvidia.com/
-Suggested-by: Hans-Frieder Vogt <hfdevel@gmx.net>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/aquantia/aquantia_main.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -500,7 +500,7 @@ static int aqr107_config_mdi(struct phy_
-       ret = of_property_read_u32(np, "marvell,mdi-cfg-order", &mdi_conf);
-       /* Do nothing in case property "marvell,mdi-cfg-order" is not present */
--      if (ret == -ENOENT)
-+      if (ret == -EINVAL || ret == -ENOSYS)
-               return 0;
-       if (ret)
diff --git a/target/linux/generic/backport-6.18/730-03-v6.13-net-phy-support-active-high-property-for-PHY-LEDs.patch b/target/linux/generic/backport-6.18/730-03-v6.13-net-phy-support-active-high-property-for-PHY-LEDs.patch
deleted file mode 100644 (file)
index 6822dc0..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From a274465cc3bef2dfd9c9ea5100848dda0a8641e1 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 10 Oct 2024 13:54:19 +0100
-Subject: [PATCH 1/4] net: phy: support 'active-high' property for PHY LEDs
-
-In addition to 'active-low' and 'inactive-high-impedance' also
-support 'active-high' property for PHY LED pin configuration.
-As only either 'active-high' or 'active-low' can be set at the
-same time, WARN and return an error in case both are set.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/91598487773d768f254d5faf06cf65b13e972f0e.1728558223.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/phy_device.c | 6 ++++++
- include/linux/phy.h          | 5 +++--
- 2 files changed, 9 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -3387,11 +3387,17 @@ static int of_phy_led(struct phy_device
-       if (index > U8_MAX)
-               return -EINVAL;
-+      if (of_property_read_bool(led, "active-high"))
-+              set_bit(PHY_LED_ACTIVE_HIGH, &modes);
-       if (of_property_read_bool(led, "active-low"))
-               set_bit(PHY_LED_ACTIVE_LOW, &modes);
-       if (of_property_read_bool(led, "inactive-high-impedance"))
-               set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes);
-+      if (WARN_ON(modes & BIT(PHY_LED_ACTIVE_LOW) &&
-+                  modes & BIT(PHY_LED_ACTIVE_HIGH)))
-+              return -EINVAL;
-+
-       if (modes) {
-               /* Return error if asked to set polarity modes but not supported */
-               if (!phydev->drv->led_polarity_set)
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -902,8 +902,9 @@ struct phy_plca_status {
- /* Modes for PHY LED configuration */
- enum phy_led_modes {
--      PHY_LED_ACTIVE_LOW = 0,
--      PHY_LED_INACTIVE_HIGH_IMPEDANCE = 1,
-+      PHY_LED_ACTIVE_HIGH = 0,
-+      PHY_LED_ACTIVE_LOW = 1,
-+      PHY_LED_INACTIVE_HIGH_IMPEDANCE = 2,
-       /* keep it last */
-       __PHY_LED_MODES_NUM,
diff --git a/target/linux/generic/backport-6.18/730-04-v6.13-net-phy-aquantia-correctly-describe-LED-polarity-ove.patch b/target/linux/generic/backport-6.18/730-04-v6.13-net-phy-aquantia-correctly-describe-LED-polarity-ove.patch
deleted file mode 100644 (file)
index 155f796..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-From 9d55e68b19f222e6334ef4021c5527998f5ab537 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 10 Oct 2024 13:55:00 +0100
-Subject: [PATCH 2/4] net: phy: aquantia: correctly describe LED polarity
- override
-
-Use newly defined 'active-high' property to set the
-VEND1_GLOBAL_LED_DRIVE_VDD bit and let 'active-low' clear that bit. This
-reflects the technical reality which was inverted in the previous
-description in which the 'active-low' property was used to actually set
-the VEND1_GLOBAL_LED_DRIVE_VDD bit, which means that VDD (ie. supply
-voltage) of the LED is driven rather than GND.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/86a413b4387c42dcb54f587cc2433a06f16aae83.1728558223.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/aquantia/aquantia.h      |  1 +
- drivers/net/phy/aquantia/aquantia_leds.c | 19 ++++++++++++++-----
- drivers/net/phy/aquantia/aquantia_main.c | 12 +++++++++---
- 3 files changed, 24 insertions(+), 8 deletions(-)
-
---- a/drivers/net/phy/aquantia/aquantia.h
-+++ b/drivers/net/phy/aquantia/aquantia.h
-@@ -177,6 +177,7 @@ static const struct aqr107_hw_stat aqr10
- struct aqr107_priv {
-       u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
-       unsigned long leds_active_low;
-+      unsigned long leds_active_high;
- };
- #if IS_REACHABLE(CONFIG_HWMON)
---- a/drivers/net/phy/aquantia/aquantia_leds.c
-+++ b/drivers/net/phy/aquantia/aquantia_leds.c
-@@ -121,13 +121,13 @@ int aqr_phy_led_active_low_set(struct ph
- {
-       return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_DRIVE(index),
-                             VEND1_GLOBAL_LED_DRIVE_VDD,
--                            enable ? VEND1_GLOBAL_LED_DRIVE_VDD : 0);
-+                            enable ? 0 : VEND1_GLOBAL_LED_DRIVE_VDD);
- }
- int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, unsigned long modes)
- {
-+      bool force_active_low = false, force_active_high = false;
-       struct aqr107_priv *priv = phydev->priv;
--      bool active_low = false;
-       u32 mode;
-       if (index >= AQR_MAX_LEDS)
-@@ -136,7 +136,10 @@ int aqr_phy_led_polarity_set(struct phy_
-       for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-               switch (mode) {
-               case PHY_LED_ACTIVE_LOW:
--                      active_low = true;
-+                      force_active_low = true;
-+                      break;
-+              case PHY_LED_ACTIVE_HIGH:
-+                      force_active_high = true;
-                       break;
-               default:
-                       return -EINVAL;
-@@ -144,8 +147,14 @@ int aqr_phy_led_polarity_set(struct phy_
-       }
-       /* Save LED driver vdd state to restore on SW reset */
--      if (active_low)
-+      if (force_active_low)
-               priv->leds_active_low |= BIT(index);
--      return aqr_phy_led_active_low_set(phydev, index, active_low);
-+      if (force_active_high)
-+              priv->leds_active_high |= BIT(index);
-+
-+      if (force_active_high || force_active_low)
-+              return aqr_phy_led_active_low_set(phydev, index, force_active_low);
-+
-+      unreachable();
- }
---- a/drivers/net/phy/aquantia/aquantia_main.c
-+++ b/drivers/net/phy/aquantia/aquantia_main.c
-@@ -517,7 +517,7 @@ static int aqr107_config_mdi(struct phy_
- static int aqr107_config_init(struct phy_device *phydev)
- {
-       struct aqr107_priv *priv = phydev->priv;
--      u32 led_active_low;
-+      u32 led_idx;
-       int ret;
-       /* Check that the PHY interface type is compatible */
-@@ -548,8 +548,14 @@ static int aqr107_config_init(struct phy
-               return ret;
-       /* Restore LED polarity state after reset */
--      for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {
--              ret = aqr_phy_led_active_low_set(phydev, led_active_low, true);
-+      for_each_set_bit(led_idx, &priv->leds_active_low, AQR_MAX_LEDS) {
-+              ret = aqr_phy_led_active_low_set(phydev, led_idx, true);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      for_each_set_bit(led_idx, &priv->leds_active_high, AQR_MAX_LEDS) {
-+              ret = aqr_phy_led_active_low_set(phydev, led_idx, false);
-               if (ret)
-                       return ret;
-       }
diff --git a/target/linux/generic/backport-6.18/730-05-v6.13-net-phy-mxl-gpy-add-basic-LED-support.patch b/target/linux/generic/backport-6.18/730-05-v6.13-net-phy-mxl-gpy-add-basic-LED-support.patch
deleted file mode 100644 (file)
index c785f8a..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-From 78997e9a5e4d8a4df561e083a92c91ae23010e07 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 1 Oct 2024 01:17:18 +0100
-Subject: [PATCH] net: phy: mxl-gpy: add basic LED support
-
-Add basic support for LEDs connected to MaxLinear GPY2xx and GPY115 PHYs.
-The PHYs allow up to 4 LEDs to be connected.
-Implement controlling LEDs in software as well as netdev trigger offloading
-and LED polarity setup.
-
-The hardware claims to support 16 PWM brightness levels but there is no
-documentation on how to use that feature, hence this is not supported.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/b6ec9050339f8244ff898898a1cecc33b13a48fc.1727741563.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mxl-gpy.c | 218 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 218 insertions(+)
-
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -38,6 +38,7 @@
- #define PHY_MIISTAT           0x18    /* MII state */
- #define PHY_IMASK             0x19    /* interrupt mask */
- #define PHY_ISTAT             0x1A    /* interrupt status */
-+#define PHY_LED                       0x1B    /* LEDs */
- #define PHY_FWV                       0x1E    /* firmware version */
- #define PHY_MIISTAT_SPD_MASK  GENMASK(2, 0)
-@@ -61,6 +62,11 @@
-                                PHY_IMASK_ADSC | \
-                                PHY_IMASK_ANC)
-+#define GPY_MAX_LEDS          4
-+#define PHY_LED_POLARITY(idx) BIT(12 + (idx))
-+#define PHY_LED_HWCONTROL(idx)        BIT(8 + (idx))
-+#define PHY_LED_ON(idx)               BIT(idx)
-+
- #define PHY_FWV_REL_MASK      BIT(15)
- #define PHY_FWV_MAJOR_MASK    GENMASK(11, 8)
- #define PHY_FWV_MINOR_MASK    GENMASK(7, 0)
-@@ -72,6 +78,23 @@
- #define PHY_MDI_MDI_X_CD      0x1
- #define PHY_MDI_MDI_X_CROSS   0x0
-+/* LED */
-+#define VSPEC1_LED(idx)               (1 + (idx))
-+#define VSPEC1_LED_BLINKS     GENMASK(15, 12)
-+#define VSPEC1_LED_PULSE      GENMASK(11, 8)
-+#define VSPEC1_LED_CON                GENMASK(7, 4)
-+#define VSPEC1_LED_BLINKF     GENMASK(3, 0)
-+
-+#define VSPEC1_LED_LINK10     BIT(0)
-+#define VSPEC1_LED_LINK100    BIT(1)
-+#define VSPEC1_LED_LINK1000   BIT(2)
-+#define VSPEC1_LED_LINK2500   BIT(3)
-+
-+#define VSPEC1_LED_TXACT      BIT(0)
-+#define VSPEC1_LED_RXACT      BIT(1)
-+#define VSPEC1_LED_COL                BIT(2)
-+#define VSPEC1_LED_NO_CON     BIT(3)
-+
- /* SGMII */
- #define VSPEC1_SGMII_CTRL     0x08
- #define VSPEC1_SGMII_CTRL_ANEN        BIT(12)         /* Aneg enable */
-@@ -835,6 +858,156 @@ static int gpy115_loopback(struct phy_de
-       return genphy_soft_reset(phydev);
- }
-+static int gpy_led_brightness_set(struct phy_device *phydev,
-+                                u8 index, enum led_brightness value)
-+{
-+      int ret;
-+
-+      if (index >= GPY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      /* clear HWCONTROL and set manual LED state */
-+      ret = phy_modify(phydev, PHY_LED,
-+                       ((value == LED_OFF) ? PHY_LED_HWCONTROL(index) : 0) |
-+                       PHY_LED_ON(index),
-+                       (value == LED_OFF) ? 0 : PHY_LED_ON(index));
-+      if (ret)
-+              return ret;
-+
-+      /* ToDo: set PWM brightness */
-+
-+      /* clear HW LED setup */
-+      if (value == LED_OFF)
-+              return phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index), 0);
-+      else
-+              return 0;
-+}
-+
-+static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) |
-+                                               BIT(TRIGGER_NETDEV_LINK_100) |
-+                                               BIT(TRIGGER_NETDEV_LINK_1000) |
-+                                               BIT(TRIGGER_NETDEV_LINK_2500) |
-+                                               BIT(TRIGGER_NETDEV_RX) |
-+                                               BIT(TRIGGER_NETDEV_TX));
-+
-+static int gpy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+                                 unsigned long rules)
-+{
-+      if (index >= GPY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      /* All combinations of the supported triggers are allowed */
-+      if (rules & ~supported_triggers)
-+              return -EOPNOTSUPP;
-+
-+      return 0;
-+}
-+
-+static int gpy_led_hw_control_get(struct phy_device *phydev, u8 index,
-+                                unsigned long *rules)
-+{
-+      int val;
-+
-+      if (index >= GPY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index));
-+      if (val < 0)
-+              return val;
-+
-+      if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK10)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_10);
-+
-+      if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK100)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_100);
-+
-+      if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK1000)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
-+
-+      if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK2500)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_2500);
-+
-+      if (FIELD_GET(VSPEC1_LED_CON, val) == (VSPEC1_LED_LINK10 |
-+                                             VSPEC1_LED_LINK100 |
-+                                             VSPEC1_LED_LINK1000 |
-+                                             VSPEC1_LED_LINK2500))
-+              *rules |= BIT(TRIGGER_NETDEV_LINK);
-+
-+      if (FIELD_GET(VSPEC1_LED_PULSE, val) & VSPEC1_LED_TXACT)
-+              *rules |= BIT(TRIGGER_NETDEV_TX);
-+
-+      if (FIELD_GET(VSPEC1_LED_PULSE, val) & VSPEC1_LED_RXACT)
-+              *rules |= BIT(TRIGGER_NETDEV_RX);
-+
-+      return 0;
-+}
-+
-+static int gpy_led_hw_control_set(struct phy_device *phydev, u8 index,
-+                                unsigned long rules)
-+{
-+      u16 val = 0;
-+      int ret;
-+
-+      if (index >= GPY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_LINK) ||
-+          rules & BIT(TRIGGER_NETDEV_LINK_10))
-+              val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK10);
-+
-+      if (rules & BIT(TRIGGER_NETDEV_LINK) ||
-+          rules & BIT(TRIGGER_NETDEV_LINK_100))
-+              val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK100);
-+
-+      if (rules & BIT(TRIGGER_NETDEV_LINK) ||
-+          rules & BIT(TRIGGER_NETDEV_LINK_1000))
-+              val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK1000);
-+
-+      if (rules & BIT(TRIGGER_NETDEV_LINK) ||
-+          rules & BIT(TRIGGER_NETDEV_LINK_2500))
-+              val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK2500);
-+
-+      if (rules & BIT(TRIGGER_NETDEV_TX))
-+              val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_TXACT);
-+
-+      if (rules & BIT(TRIGGER_NETDEV_RX))
-+              val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_RXACT);
-+
-+      /* allow RX/TX pulse without link indication */
-+      if ((rules & BIT(TRIGGER_NETDEV_TX) || rules & BIT(TRIGGER_NETDEV_RX)) &&
-+          !(val & VSPEC1_LED_CON))
-+              val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_NO_CON) | VSPEC1_LED_CON;
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index), val);
-+      if (ret)
-+              return ret;
-+
-+      return phy_set_bits(phydev, PHY_LED, PHY_LED_HWCONTROL(index));
-+}
-+
-+static int gpy_led_polarity_set(struct phy_device *phydev, int index,
-+                              unsigned long modes)
-+{
-+      bool active_low = false;
-+      u32 mode;
-+
-+      if (index >= GPY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-+              switch (mode) {
-+              case PHY_LED_ACTIVE_LOW:
-+                      active_low = true;
-+                      break;
-+              default:
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      return phy_modify(phydev, PHY_LED, PHY_LED_POLARITY(index),
-+                        active_low ? 0 : PHY_LED_POLARITY(index));
-+}
-+
- static struct phy_driver gpy_drivers[] = {
-       {
-               PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx),
-@@ -852,6 +1025,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               .phy_id         = PHY_ID_GPY115B,
-@@ -870,6 +1048,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy115_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               PHY_ID_MATCH_MODEL(PHY_ID_GPY115C),
-@@ -887,6 +1070,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy115_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               .phy_id         = PHY_ID_GPY211B,
-@@ -905,6 +1093,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               PHY_ID_MATCH_MODEL(PHY_ID_GPY211C),
-@@ -922,6 +1115,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               .phy_id         = PHY_ID_GPY212B,
-@@ -940,6 +1138,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               PHY_ID_MATCH_MODEL(PHY_ID_GPY212C),
-@@ -957,6 +1160,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               .phy_id         = PHY_ID_GPY215B,
-@@ -975,6 +1183,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               PHY_ID_MATCH_MODEL(PHY_ID_GPY215C),
-@@ -992,6 +1205,11 @@ static struct phy_driver gpy_drivers[] =
-               .set_wol        = gpy_set_wol,
-               .get_wol        = gpy_get_wol,
-               .set_loopback   = gpy_loopback,
-+              .led_brightness_set = gpy_led_brightness_set,
-+              .led_hw_is_supported = gpy_led_hw_is_supported,
-+              .led_hw_control_get = gpy_led_hw_control_get,
-+              .led_hw_control_set = gpy_led_hw_control_set,
-+              .led_polarity_set = gpy_led_polarity_set,
-       },
-       {
-               PHY_ID_MATCH_MODEL(PHY_ID_GPY241B),
diff --git a/target/linux/generic/backport-6.18/730-06-v6.13-net-phy-mxl-gpy-add-missing-support-for-TRIGGER_NETD.patch b/target/linux/generic/backport-6.18/730-06-v6.13-net-phy-mxl-gpy-add-missing-support-for-TRIGGER_NETD.patch
deleted file mode 100644 (file)
index 39bef9b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From f95b4725e796b12e5f347a0d161e1d3843142aa8 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 4 Oct 2024 16:56:35 +0100
-Subject: [PATCH] net: phy: mxl-gpy: add missing support for
- TRIGGER_NETDEV_LINK_10
-
-The PHY also support 10MBit/s links as well as the corresponding link
-indication trigger to be offloaded. Add TRIGGER_NETDEV_LINK_10 to the
-supported triggers.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/cc5da0a989af8b0d49d823656d88053c4de2ab98.1728057367.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mxl-gpy.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -884,6 +884,7 @@ static int gpy_led_brightness_set(struct
- }
- static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) |
-+                                               BIT(TRIGGER_NETDEV_LINK_10) |
-                                                BIT(TRIGGER_NETDEV_LINK_100) |
-                                                BIT(TRIGGER_NETDEV_LINK_1000) |
-                                                BIT(TRIGGER_NETDEV_LINK_2500) |
diff --git a/target/linux/generic/backport-6.18/730-07-v6.13-net-phy-mxl-gpy-correctly-describe-LED-polarity.patch b/target/linux/generic/backport-6.18/730-07-v6.13-net-phy-mxl-gpy-correctly-describe-LED-polarity.patch
deleted file mode 100644 (file)
index 5fd3dcc..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-From eb89c79c1b8f17fc1611540768678e60df89ac42 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 10 Oct 2024 13:55:17 +0100
-Subject: [PATCH 3/4] net: phy: mxl-gpy: correctly describe LED polarity
-
-According the datasheet covering the LED (0x1b) register:
-0B Active High LEDx pin driven high when activated
-1B Active Low LEDx pin driven low when activated
-
-Make use of the now available 'active-high' property and correctly
-reflect the polarity setting which was previously inverted.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/180ccafa837f09908b852a8a874a3808c5ecd2d0.1728558223.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/mxl-gpy.c | 16 ++++++++++++----
- 1 file changed, 12 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -989,7 +989,7 @@ static int gpy_led_hw_control_set(struct
- static int gpy_led_polarity_set(struct phy_device *phydev, int index,
-                               unsigned long modes)
- {
--      bool active_low = false;
-+      bool force_active_low = false, force_active_high = false;
-       u32 mode;
-       if (index >= GPY_MAX_LEDS)
-@@ -998,15 +998,23 @@ static int gpy_led_polarity_set(struct p
-       for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-               switch (mode) {
-               case PHY_LED_ACTIVE_LOW:
--                      active_low = true;
-+                      force_active_low = true;
-+                      break;
-+              case PHY_LED_ACTIVE_HIGH:
-+                      force_active_high = true;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
--      return phy_modify(phydev, PHY_LED, PHY_LED_POLARITY(index),
--                        active_low ? 0 : PHY_LED_POLARITY(index));
-+      if (force_active_low)
-+              return phy_set_bits(phydev, PHY_LED, PHY_LED_POLARITY(index));
-+
-+      if (force_active_high)
-+              return phy_clear_bits(phydev, PHY_LED, PHY_LED_POLARITY(index));
-+
-+      unreachable();
- }
- static struct phy_driver gpy_drivers[] = {
diff --git a/target/linux/generic/backport-6.18/730-08-v6.13-net-phy-intel-xway-add-support-for-PHY-LEDs.patch b/target/linux/generic/backport-6.18/730-08-v6.13-net-phy-intel-xway-add-support-for-PHY-LEDs.patch
deleted file mode 100644 (file)
index c57b577..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-From 1758af47b98c17da464cb45f476875150955dd48 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 10 Oct 2024 13:55:29 +0100
-Subject: [PATCH 4/4] net: phy: intel-xway: add support for PHY LEDs
-
-The intel-xway PHY driver predates the PHY LED framework and currently
-initializes all LED pins to equal default values.
-
-Add PHY LED functions to the drivers and don't set default values if
-LEDs are defined in device tree.
-
-According the datasheets 3 LEDs are supported on all Intel XWAY PHYs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/81f4717ab9acf38f3239727a4540ae96fd01109b.1728558223.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/intel-xway.c | 253 +++++++++++++++++++++++++++++++++--
- 1 file changed, 244 insertions(+), 9 deletions(-)
-
---- a/drivers/net/phy/intel-xway.c
-+++ b/drivers/net/phy/intel-xway.c
-@@ -151,6 +151,13 @@
- #define XWAY_MMD_LED3H                        0x01E8
- #define XWAY_MMD_LED3L                        0x01E9
-+#define XWAY_GPHY_MAX_LEDS            3
-+#define XWAY_GPHY_LED_INV(idx)                BIT(12 + (idx))
-+#define XWAY_GPHY_LED_EN(idx)         BIT(8 + (idx))
-+#define XWAY_GPHY_LED_DA(idx)         BIT(idx)
-+#define XWAY_MMD_LEDxH(idx)           (XWAY_MMD_LED0H + 2 * (idx))
-+#define XWAY_MMD_LEDxL(idx)           (XWAY_MMD_LED0L + 2 * (idx))
-+
- #define PHY_ID_PHY11G_1_3             0x030260D1
- #define PHY_ID_PHY22F_1_3             0x030260E1
- #define PHY_ID_PHY11G_1_4             0xD565A400
-@@ -229,20 +236,12 @@ static int xway_gphy_rgmii_init(struct p
-                         XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
- }
--static int xway_gphy_config_init(struct phy_device *phydev)
-+static int xway_gphy_init_leds(struct phy_device *phydev)
- {
-       int err;
-       u32 ledxh;
-       u32 ledxl;
--      /* Mask all interrupts */
--      err = phy_write(phydev, XWAY_MDIO_IMASK, 0);
--      if (err)
--              return err;
--
--      /* Clear all pending interrupts */
--      phy_read(phydev, XWAY_MDIO_ISTAT);
--
-       /* Ensure that integrated led function is enabled for all leds */
-       err = phy_write(phydev, XWAY_MDIO_LED,
-                       XWAY_MDIO_LED_LED0_EN |
-@@ -276,6 +275,26 @@ static int xway_gphy_config_init(struct
-       phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh);
-       phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl);
-+      return 0;
-+}
-+
-+static int xway_gphy_config_init(struct phy_device *phydev)
-+{
-+      struct device_node *np = phydev->mdio.dev.of_node;
-+      int err;
-+
-+      /* Mask all interrupts */
-+      err = phy_write(phydev, XWAY_MDIO_IMASK, 0);
-+      if (err)
-+              return err;
-+
-+      /* Use default LED configuration if 'leds' node isn't defined */
-+      if (!of_get_child_by_name(np, "leds"))
-+              xway_gphy_init_leds(phydev);
-+
-+      /* Clear all pending interrupts */
-+      phy_read(phydev, XWAY_MDIO_ISTAT);
-+
-       err = xway_gphy_rgmii_init(phydev);
-       if (err)
-               return err;
-@@ -347,6 +366,172 @@ static irqreturn_t xway_gphy_handle_inte
-       return IRQ_HANDLED;
- }
-+static int xway_gphy_led_brightness_set(struct phy_device *phydev,
-+                                      u8 index, enum led_brightness value)
-+{
-+      int ret;
-+
-+      if (index >= XWAY_GPHY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      /* clear EN and set manual LED state */
-+      ret = phy_modify(phydev, XWAY_MDIO_LED,
-+                       ((value == LED_OFF) ? XWAY_GPHY_LED_EN(index) : 0) |
-+                       XWAY_GPHY_LED_DA(index),
-+                       (value == LED_OFF) ? 0 : XWAY_GPHY_LED_DA(index));
-+      if (ret)
-+              return ret;
-+
-+      /* clear HW LED setup */
-+      if (value == LED_OFF) {
-+              ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index), 0);
-+              if (ret)
-+                      return ret;
-+
-+              return phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index), 0);
-+      } else {
-+              return 0;
-+      }
-+}
-+
-+static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) |
-+                                               BIT(TRIGGER_NETDEV_LINK_10) |
-+                                               BIT(TRIGGER_NETDEV_LINK_100) |
-+                                               BIT(TRIGGER_NETDEV_LINK_1000) |
-+                                               BIT(TRIGGER_NETDEV_RX) |
-+                                               BIT(TRIGGER_NETDEV_TX));
-+
-+static int xway_gphy_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+                                       unsigned long rules)
-+{
-+      if (index >= XWAY_GPHY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      /* activity triggers are not possible without combination with a link
-+       * trigger.
-+       */
-+      if (rules & (BIT(TRIGGER_NETDEV_RX) | BIT(TRIGGER_NETDEV_TX)) &&
-+          !(rules & (BIT(TRIGGER_NETDEV_LINK) |
-+                     BIT(TRIGGER_NETDEV_LINK_10) |
-+                     BIT(TRIGGER_NETDEV_LINK_100) |
-+                     BIT(TRIGGER_NETDEV_LINK_1000))))
-+              return -EOPNOTSUPP;
-+
-+      /* All other combinations of the supported triggers are allowed */
-+      if (rules & ~supported_triggers)
-+              return -EOPNOTSUPP;
-+
-+      return 0;
-+}
-+
-+static int xway_gphy_led_hw_control_get(struct phy_device *phydev, u8 index,
-+                                      unsigned long *rules)
-+{
-+      int lval, hval;
-+
-+      if (index >= XWAY_GPHY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      hval = phy_read_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index));
-+      if (hval < 0)
-+              return hval;
-+
-+      lval = phy_read_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index));
-+      if (lval < 0)
-+              return lval;
-+
-+      if (hval & XWAY_MMD_LEDxH_CON_LINK10)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_10);
-+
-+      if (hval & XWAY_MMD_LEDxH_CON_LINK100)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_100);
-+
-+      if (hval & XWAY_MMD_LEDxH_CON_LINK1000)
-+              *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
-+
-+      if ((hval & XWAY_MMD_LEDxH_CON_LINK10) &&
-+          (hval & XWAY_MMD_LEDxH_CON_LINK100) &&
-+          (hval & XWAY_MMD_LEDxH_CON_LINK1000))
-+              *rules |= BIT(TRIGGER_NETDEV_LINK);
-+
-+      if (lval & XWAY_MMD_LEDxL_PULSE_TXACT)
-+              *rules |= BIT(TRIGGER_NETDEV_TX);
-+
-+      if (lval & XWAY_MMD_LEDxL_PULSE_RXACT)
-+              *rules |= BIT(TRIGGER_NETDEV_RX);
-+
-+      return 0;
-+}
-+
-+static int xway_gphy_led_hw_control_set(struct phy_device *phydev, u8 index,
-+                                      unsigned long rules)
-+{
-+      u16 hval = 0, lval = 0;
-+      int ret;
-+
-+      if (index >= XWAY_GPHY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_LINK) ||
-+          rules & BIT(TRIGGER_NETDEV_LINK_10))
-+              hval |= XWAY_MMD_LEDxH_CON_LINK10;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_LINK) ||
-+          rules & BIT(TRIGGER_NETDEV_LINK_100))
-+              hval |= XWAY_MMD_LEDxH_CON_LINK100;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_LINK) ||
-+          rules & BIT(TRIGGER_NETDEV_LINK_1000))
-+              hval |= XWAY_MMD_LEDxH_CON_LINK1000;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_TX))
-+              lval |= XWAY_MMD_LEDxL_PULSE_TXACT;
-+
-+      if (rules & BIT(TRIGGER_NETDEV_RX))
-+              lval |= XWAY_MMD_LEDxL_PULSE_RXACT;
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index), hval);
-+      if (ret)
-+              return ret;
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index), lval);
-+      if (ret)
-+              return ret;
-+
-+      return phy_set_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_EN(index));
-+}
-+
-+static int xway_gphy_led_polarity_set(struct phy_device *phydev, int index,
-+                                    unsigned long modes)
-+{
-+      bool force_active_low = false, force_active_high = false;
-+      u32 mode;
-+
-+      if (index >= XWAY_GPHY_MAX_LEDS)
-+              return -EINVAL;
-+
-+      for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-+              switch (mode) {
-+              case PHY_LED_ACTIVE_LOW:
-+                      force_active_low = true;
-+                      break;
-+              case PHY_LED_ACTIVE_HIGH:
-+                      force_active_high = true;
-+                      break;
-+              default:
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      if (force_active_low)
-+              return phy_set_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_INV(index));
-+
-+      if (force_active_high)
-+              return phy_clear_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_INV(index));
-+
-+      unreachable();
-+}
-+
- static struct phy_driver xway_gphy[] = {
-       {
-               .phy_id         = PHY_ID_PHY11G_1_3,
-@@ -359,6 +544,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY22F_1_3,
-               .phy_id_mask    = 0xffffffff,
-@@ -370,6 +560,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY11G_1_4,
-               .phy_id_mask    = 0xffffffff,
-@@ -381,6 +576,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY22F_1_4,
-               .phy_id_mask    = 0xffffffff,
-@@ -392,6 +592,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY11G_1_5,
-               .phy_id_mask    = 0xffffffff,
-@@ -402,6 +607,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY22F_1_5,
-               .phy_id_mask    = 0xffffffff,
-@@ -412,6 +622,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY11G_VR9_1_1,
-               .phy_id_mask    = 0xffffffff,
-@@ -422,6 +637,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY22F_VR9_1_1,
-               .phy_id_mask    = 0xffffffff,
-@@ -432,6 +652,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY11G_VR9_1_2,
-               .phy_id_mask    = 0xffffffff,
-@@ -442,6 +667,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       }, {
-               .phy_id         = PHY_ID_PHY22F_VR9_1_2,
-               .phy_id_mask    = 0xffffffff,
-@@ -452,6 +682,11 @@ static struct phy_driver xway_gphy[] = {
-               .config_intr    = xway_gphy_config_intr,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-+              .led_brightness_set = xway_gphy_led_brightness_set,
-+              .led_hw_is_supported = xway_gphy_led_hw_is_supported,
-+              .led_hw_control_get = xway_gphy_led_hw_control_get,
-+              .led_hw_control_set = xway_gphy_led_hw_control_set,
-+              .led_polarity_set = xway_gphy_led_polarity_set,
-       },
- };
- module_phy_driver(xway_gphy);
diff --git a/target/linux/generic/backport-6.18/730-09-v6.18-net-phy-mxl-gpy-fix-link-properties-on-USXGMII-and-i.patch b/target/linux/generic/backport-6.18/730-09-v6.18-net-phy-mxl-gpy-fix-link-properties-on-USXGMII-and-i.patch
deleted file mode 100644 (file)
index 6f3bbfc..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From 081156ce13f8fa4e97b5148dc54d8c0ddf02117b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 20 Nov 2025 15:02:19 +0000
-Subject: [PATCH] net: phy: mxl-gpy: fix link properties on USXGMII and
- internal PHYs
-
-gpy_update_interface() returns early in case the PHY is internal or
-connected via USXGMII. In this case the gigabit master/slave property
-as well as MDI/MDI-X status also won't be read which seems wrong.
-Always read those properties by moving the logic to retrieve them to
-gpy_read_status().
-
-Fixes: fd8825cd8c6fc ("net: phy: mxl-gpy: Add PHY Auto/MDI/MDI-X set driver for GPY211 chips")
-Fixes: 311abcdddc00a ("net: phy: add support to get Master-Slave configuration")
-Suggested-by: "Russell King (Oracle)" <linux@armlinux.org.uk>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://patch.msgid.link/71fccf3f56742116eb18cc070d2a9810479ea7f9.1763650701.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/mxl-gpy.c | 18 +++++++++++-------
- 1 file changed, 11 insertions(+), 7 deletions(-)
-
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -584,13 +584,7 @@ static int gpy_update_interface(struct p
-               break;
-       }
--      if (phydev->speed == SPEED_2500 || phydev->speed == SPEED_1000) {
--              ret = genphy_read_master_slave(phydev);
--              if (ret < 0)
--                      return ret;
--      }
--
--      return gpy_update_mdix(phydev);
-+      return 0;
- }
- static int gpy_read_status(struct phy_device *phydev)
-@@ -645,6 +639,16 @@ static int gpy_read_status(struct phy_de
-               ret = gpy_update_interface(phydev);
-               if (ret < 0)
-                       return ret;
-+
-+              if (phydev->speed == SPEED_2500 || phydev->speed == SPEED_1000) {
-+                      ret = genphy_read_master_slave(phydev);
-+                      if (ret < 0)
-+                              return ret;
-+              }
-+
-+              ret = gpy_update_mdix(phydev);
-+              if (ret < 0)
-+                      return ret;
-       }
-       return 0;
diff --git a/target/linux/generic/backport-6.18/731-v6.18-net-mediatek-wed-Introduce-MT7992-WED-support-to-MT7.patch b/target/linux/generic/backport-6.18/731-v6.18-net-mediatek-wed-Introduce-MT7992-WED-support-to-MT7.patch
deleted file mode 100644 (file)
index 8b1844d..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 12 Aug 2025 06:57:23 +0200
-Subject: [PATCH] net: mediatek: wed: Introduce MT7992 WED support to MT7988
- SoC
-
-Introduce the second WDMA RX ring in WED driver for MT7988 SoC since the
-Mediatek MT7992 WiFi chipset supports two separated WDMA rings.
-Add missing MT7988 configurations to properly support WED for MT7992 in
-MT76 driver.
-
-Co-developed-by: Rex Lu <rex.lu@mediatek.com>
-Signed-off-by: Rex Lu <rex.lu@mediatek.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://patch.msgid.link/20250812-mt7992-wed-support-v3-1-9ada78a819a4@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -59,7 +59,9 @@ struct mtk_wed_flow_block_priv {
- static const struct mtk_wed_soc_data mt7622_data = {
-       .regmap = {
-               .tx_bm_tkid             = 0x088,
--              .wpdma_rx_ring0         = 0x770,
-+              .wpdma_rx_ring = {
-+                      0x770,
-+              },
-               .reset_idx_tx_mask      = GENMASK(3, 0),
-               .reset_idx_rx_mask      = GENMASK(17, 16),
-       },
-@@ -70,7 +72,9 @@ static const struct mtk_wed_soc_data mt7
- static const struct mtk_wed_soc_data mt7986_data = {
-       .regmap = {
-               .tx_bm_tkid             = 0x0c8,
--              .wpdma_rx_ring0         = 0x770,
-+              .wpdma_rx_ring = {
-+                      0x770,
-+              },
-               .reset_idx_tx_mask      = GENMASK(1, 0),
-               .reset_idx_rx_mask      = GENMASK(7, 6),
-       },
-@@ -81,7 +85,10 @@ static const struct mtk_wed_soc_data mt7
- static const struct mtk_wed_soc_data mt7988_data = {
-       .regmap = {
-               .tx_bm_tkid             = 0x0c8,
--              .wpdma_rx_ring0         = 0x7d0,
-+              .wpdma_rx_ring = {
-+                      0x7d0,
-+                      0x7d8,
-+              },
-               .reset_idx_tx_mask      = GENMASK(1, 0),
-               .reset_idx_rx_mask      = GENMASK(7, 6),
-       },
-@@ -621,8 +628,8 @@ mtk_wed_amsdu_init(struct mtk_wed_device
-               return ret;
-       }
--      /* eagle E1 PCIE1 tx ring 22 flow control issue */
--      if (dev->wlan.id == 0x7991)
-+      /* Kite and Eagle E1 PCIE1 tx ring 22 flow control issue */
-+      if (dev->wlan.id == 0x7991 || dev->wlan.id == 0x7992)
-               wed_clr(dev, MTK_WED_AMSDU_FIFO, MTK_WED_AMSDU_IS_PRIOR0_RING);
-       wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
-@@ -1239,7 +1246,11 @@ mtk_wed_set_wpdma(struct mtk_wed_device
-               return;
-       wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
--      wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx);
-+      wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring[0],
-+              dev->wlan.wpdma_rx[0]);
-+      if (mtk_wed_is_v3_or_greater(dev->hw))
-+              wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring[1],
-+                      dev->wlan.wpdma_rx[1]);
-       if (!dev->wlan.hw_rro)
-               return;
-@@ -2335,6 +2346,16 @@ mtk_wed_start(struct mtk_wed_device *dev
-               if (!dev->rx_wdma[i].desc)
-                       mtk_wed_wdma_rx_ring_setup(dev, i, 16, false);
-+      if (dev->wlan.hw_rro) {
-+              for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) {
-+                      u32 addr = MTK_WED_RRO_MSDU_PG_CTRL0(i) +
-+                                 MTK_WED_RING_OFS_COUNT;
-+
-+                      if (!wed_r32(dev, addr))
-+                              wed_w32(dev, addr, 1);
-+              }
-+      }
-+
-       mtk_wed_hw_init(dev);
-       mtk_wed_configure_irq(dev, irq_mask);
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -17,7 +17,7 @@ struct mtk_wed_wo;
- struct mtk_wed_soc_data {
-       struct {
-               u32 tx_bm_tkid;
--              u32 wpdma_rx_ring0;
-+              u32 wpdma_rx_ring[MTK_WED_RX_QUEUES];
-               u32 reset_idx_tx_mask;
-               u32 reset_idx_rx_mask;
-       } regmap;
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -147,7 +147,7 @@ struct mtk_wed_device {
-               u32 wpdma_tx;
-               u32 wpdma_txfree;
-               u32 wpdma_rx_glo;
--              u32 wpdma_rx;
-+              u32 wpdma_rx[MTK_WED_RX_QUEUES];
-               u32 wpdma_rx_rro[MTK_WED_RX_QUEUES];
-               u32 wpdma_rx_pg;
diff --git a/target/linux/generic/backport-6.18/732-v6.18-wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch b/target/linux/generic/backport-6.18/732-v6.18-wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch
deleted file mode 100644 (file)
index 883de54..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 8 Oct 2025 12:41:48 +0200
-Subject: [PATCH] wifi: mt76: wed: use proper wed reference in mt76 wed driver
- callabacks
-
-MT7996 driver can use both wed and wed_hif2 devices to offload traffic
-from/to the wireless NIC. In the current codebase we assume to always
-use the primary wed device in wed callbacks resulting in the following
-crash if the hw runs wed_hif2 (e.g. 6GHz link).
-
-[  297.455876] Unable to handle kernel read from unreadable memory at virtual address 000000000000080a
-[  297.464928] Mem abort info:
-[  297.467722]   ESR = 0x0000000096000005
-[  297.471461]   EC = 0x25: DABT (current EL), IL = 32 bits
-[  297.476766]   SET = 0, FnV = 0
-[  297.479809]   EA = 0, S1PTW = 0
-[  297.482940]   FSC = 0x05: level 1 translation fault
-[  297.487809] Data abort info:
-[  297.490679]   ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
-[  297.496156]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
-[  297.501196]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
-[  297.506500] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000107480000
-[  297.512927] [000000000000080a] pgd=08000001097fb003, p4d=08000001097fb003, pud=08000001097fb003, pmd=0000000000000000
-[  297.523532] Internal error: Oops: 0000000096000005 [#1] SMP
-[  297.715393] CPU: 2 UID: 0 PID: 45 Comm: kworker/u16:2 Tainted: G           O       6.12.50 #0
-[  297.723908] Tainted: [O]=OOT_MODULE
-[  297.727384] Hardware name: Banana Pi BPI-R4 (2x SFP+) (DT)
-[  297.732857] Workqueue: nf_ft_offload_del nf_flow_rule_route_ipv6 [nf_flow_table]
-[  297.740254] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
-[  297.747205] pc : mt76_wed_offload_disable+0x64/0xa0 [mt76]
-[  297.752688] lr : mtk_wed_flow_remove+0x58/0x80
-[  297.757126] sp : ffffffc080fe3ae0
-[  297.760430] x29: ffffffc080fe3ae0 x28: ffffffc080fe3be0 x27: 00000000deadbef7
-[  297.767557] x26: ffffff80c5ebca00 x25: 0000000000000001 x24: ffffff80c85f4c00
-[  297.774683] x23: ffffff80c1875b78 x22: ffffffc080d42cd0 x21: ffffffc080660018
-[  297.781809] x20: ffffff80c6a076d0 x19: ffffff80c6a043c8 x18: 0000000000000000
-[  297.788935] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000
-[  297.796060] x14: 0000000000000019 x13: ffffff80c0ad8ec0 x12: 00000000fa83b2da
-[  297.803185] x11: ffffff80c02700c0 x10: ffffff80c0ad8ec0 x9 : ffffff81fef96200
-[  297.810311] x8 : ffffff80c02700c0 x7 : ffffff80c02700d0 x6 : 0000000000000002
-[  297.817435] x5 : 0000000000000400 x4 : 0000000000000000 x3 : 0000000000000000
-[  297.824561] x2 : 0000000000000001 x1 : 0000000000000800 x0 : ffffff80c6a063c8
-[  297.831686] Call trace:
-[  297.834123]  mt76_wed_offload_disable+0x64/0xa0 [mt76]
-[  297.839254]  mtk_wed_flow_remove+0x58/0x80
-[  297.843342]  mtk_flow_offload_cmd+0x434/0x574
-[  297.847689]  mtk_wed_setup_tc_block_cb+0x30/0x40
-[  297.852295]  nf_flow_offload_ipv6_hook+0x7f4/0x964 [nf_flow_table]
-[  297.858466]  nf_flow_rule_route_ipv6+0x438/0x4a4 [nf_flow_table]
-[  297.864463]  process_one_work+0x174/0x300
-[  297.868465]  worker_thread+0x278/0x430
-[  297.872204]  kthread+0xd8/0xdc
-[  297.875251]  ret_from_fork+0x10/0x20
-[  297.878820] Code: 928b5ae0 8b000273 91400a60 f943fa61 (79401421)
-[  297.884901] ---[ end trace 0000000000000000 ]---
-
-Fix the issue detecting the proper wed reference to use running wed
-callabacks.
-
--- Partial backport for data structure change only (rest is in the mt76 package)
-
-Fixes: 83eafc9251d6 ("wifi: mt76: mt7996: add wed tx support")
-Tested-by: Daniel Pawlik <pawlik.dan@gmail.com>
-Tested-by: Matteo Croce <teknoraver@meta.com>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Link: https://patch.msgid.link/20251008-wed-fixes-v1-1-8f7678583385@kernel.org
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -154,6 +154,7 @@ struct mtk_wed_device {
-               bool wcid_512;
-               bool hw_rro;
-               bool msi;
-+              bool hif2;
-               u16 token_start;
-               unsigned int nbuf;
diff --git a/target/linux/generic/backport-6.18/733-v6.18-net-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-fo.patch b/target/linux/generic/backport-6.18/733-v6.18-net-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-fo.patch
deleted file mode 100644 (file)
index c1bb1b9..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-From: Rex Lu <rex.lu@mediatek.com>
-Date: Thu, 9 Oct 2025 08:29:34 +0200
-Subject: [PATCH] net: mtk: wed: add dma mask limitation and GFP_DMA32 for
- device with more than 4GB DRAM
-
-Limit tx/rx buffer address to 32-bit address space for board with more
-than 4GB DRAM.
-
-Fixes: 804775dfc2885 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)")
-Fixes: 6757d345dd7db ("net: ethernet: mtk_wed: introduce hw_rro support for MT7988")
-Tested-by: Daniel Pawlik <pawlik.dan@gmail.com>
-Tested-by: Matteo Croce <teknoraver@meta.com>
-Signed-off-by: Rex Lu <rex.lu@mediatek.com>
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -677,7 +677,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d
-               void *buf;
-               int s;
--              page = __dev_alloc_page(GFP_KERNEL);
-+              page = __dev_alloc_page(GFP_KERNEL | GFP_DMA32);
-               if (!page)
-                       return -ENOMEM;
-@@ -800,7 +800,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_we
-               struct page *page;
-               int s;
--              page = __dev_alloc_page(GFP_KERNEL);
-+              page = __dev_alloc_page(GFP_KERNEL | GFP_DMA32);
-               if (!page)
-                       return -ENOMEM;
-@@ -2438,6 +2438,10 @@ mtk_wed_attach(struct mtk_wed_device *de
-       dev->version = hw->version;
-       dev->hw->pcie_base = mtk_wed_get_pcie_base(dev);
-+      ret = dma_set_mask_and_coherent(hw->dev, DMA_BIT_MASK(32));
-+      if (ret)
-+              goto out;
-+
-       if (hw->eth->dma_dev == hw->eth->dev &&
-           of_dma_is_coherent(hw->eth->dev->of_node))
-               mtk_eth_set_dma_device(hw->eth, hw->dev);
diff --git a/target/linux/generic/backport-6.18/735-v6.13-net-phy-avoid-undefined-behavior-in-_led_polarity_se.patch b/target/linux/generic/backport-6.18/735-v6.13-net-phy-avoid-undefined-behavior-in-_led_polarity_se.patch
deleted file mode 100644 (file)
index 622d2c3..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-From cff865c700711ecc3824b2dfe181637f3ed23c80 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Tue, 17 Dec 2024 09:10:34 +0100
-Subject: net: phy: avoid undefined behavior in *_led_polarity_set()
-
-gcc runs into undefined behavior at the end of the three led_polarity_set()
-callback functions if it were called with a zero 'modes' argument and it
-just ends the function there without returning from it.
-
-This gets flagged by 'objtool' as a function that continues on
-to the next one:
-
-drivers/net/phy/aquantia/aquantia_leds.o: warning: objtool: aqr_phy_led_polarity_set+0xf: can't find jump dest instruction at .text+0x5d9
-drivers/net/phy/intel-xway.o: warning: objtool: xway_gphy_led_polarity_set() falls through to next function xway_gphy_config_init()
-drivers/net/phy/mxl-gpy.o: warning: objtool: gpy_led_polarity_set() falls through to next function gpy_led_hw_control_get()
-
-There is no point to micro-optimize the behavior here to save a single-digit
-number of bytes in the kernel, so just change this to a "return -EINVAL"
-as we do when any unexpected bits are set.
-
-Fixes: 1758af47b98c ("net: phy: intel-xway: add support for PHY LEDs")
-Fixes: 9d55e68b19f2 ("net: phy: aquantia: correctly describe LED polarity override")
-Fixes: eb89c79c1b8f ("net: phy: mxl-gpy: correctly describe LED polarity")
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20241217081056.238792-1-arnd@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/aquantia/aquantia_leds.c | 2 +-
- drivers/net/phy/intel-xway.c             | 2 +-
- drivers/net/phy/mxl-gpy.c                | 2 +-
- 3 files changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/aquantia/aquantia_leds.c
-+++ b/drivers/net/phy/aquantia/aquantia_leds.c
-@@ -156,5 +156,5 @@ int aqr_phy_led_polarity_set(struct phy_
-       if (force_active_high || force_active_low)
-               return aqr_phy_led_active_low_set(phydev, index, force_active_low);
--      unreachable();
-+      return -EINVAL;
- }
---- a/drivers/net/phy/intel-xway.c
-+++ b/drivers/net/phy/intel-xway.c
-@@ -529,7 +529,7 @@ static int xway_gphy_led_polarity_set(st
-       if (force_active_high)
-               return phy_clear_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_INV(index));
--      unreachable();
-+      return -EINVAL;
- }
- static struct phy_driver xway_gphy[] = {
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -1005,7 +1005,7 @@ static int gpy_led_polarity_set(struct p
-       if (force_active_high)
-               return phy_clear_bits(phydev, PHY_LED, PHY_LED_POLARITY(index));
--      unreachable();
-+      return -EINVAL;
- }
- static unsigned int gpy_inband_caps(struct phy_device *phydev,
diff --git a/target/linux/generic/backport-6.18/740-v6.13-net-dsa-mv88e6xxx-Support-LED-control.patch b/target/linux/generic/backport-6.18/740-v6.13-net-dsa-mv88e6xxx-Support-LED-control.patch
deleted file mode 100644 (file)
index 19268cf..0000000
+++ /dev/null
@@ -1,1250 +0,0 @@
-From 7b590490e3aa6bfa38bf6e2069a529017fd3c1d2 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Fri, 13 Oct 2023 00:08:35 +0200
-Subject: [PATCH] net: dsa: mv88e6xxx: Support LED control
-
-This adds control over the hardware LEDs in the Marvell
-MV88E6xxx DSA switch and enables it for MV88E6352.
-
-This fixes an imminent problem on the Inteno XG6846 which
-has a WAN LED that simply do not work with hardware
-defaults: driver amendment is necessary.
-
-The patch is modeled after Christian Marangis LED support
-code for the QCA8k DSA switch, I got help with the register
-definitions from Tim Harvey.
-
-After this patch it is possible to activate hardware link
-indication like this (or with a similar script):
-
-  cd /sys/class/leds/Marvell\ 88E6352:05:00:green:wan/
-  echo netdev > trigger
-  echo 1 > link
-
-This makes the green link indicator come up on any link
-speed. It is also possible to be more elaborate, like this:
-
-  cd /sys/class/leds/Marvell\ 88E6352:05:00:green:wan/
-  echo netdev > trigger
-  echo 1 > link_1000
-  cd /sys/class/leds/Marvell\ 88E6352:05:01:amber:wan/
-  echo netdev > trigger
-  echo 1 > link_100
-
-Making the green LED come on for a gigabit link and the
-amber LED come on for a 100 mbit link.
-
-Each port has 2 LED slots (the hardware may use just one or
-none) and the hardware triggers are specified in four bits per
-LED, and some of the hardware triggers are only available on the
-SFP (fiber) uplink. The restrictions are described in the
-port.h header file where the registers are described. For
-example, selector 1 set for LED 1 on port 5 or 6 will indicate
-Fiber 1000 (gigabit) and activity with a blinking LED, but
-ONLY for an SFP connection. If port 5/6 is used with something
-not SFP, this selector is a noop: something else need to be
-selected.
-
-After the previous series rewriting the MV88E6xxx DT
-bindings to use YAML a "leds" subnode is already valid
-for each port, in my scratch device tree it looks like
-this:
-
-   leds {
-     #address-cells = <1>;
-     #size-cells = <0>;
-
-     led@0 {
-       reg = <0>;
-       color = <LED_COLOR_ID_GREEN>;
-       function = LED_FUNCTION_LAN;
-       default-state = "off";
-       linux,default-trigger = "netdev";
-     };
-     led@1 {
-       reg = <1>;
-       color = <LED_COLOR_ID_AMBER>;
-       function = LED_FUNCTION_LAN;
-       default-state = "off";
-     };
-   };
-
-This DT config is not yet configuring everything: when the netdev
-default trigger is assigned the hw acceleration callbacks are
-not called, and there is no way to set the netdev sub-trigger
-type (such as link_1000) from the device tree, such as if you want
-a gigabit link indicator. This has to be done from userspace at
-this point.
-
-We add LED operations to all switches in the 6352 family:
-6172, 6176, 6240 and 6352.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/net/dsa/mv88e6xxx/Kconfig  |  10 +
- drivers/net/dsa/mv88e6xxx/Makefile |   1 +
- drivers/net/dsa/mv88e6xxx/chip.c   |  38 +-
- drivers/net/dsa/mv88e6xxx/chip.h   |  11 +
- drivers/net/dsa/mv88e6xxx/leds.c   | 839 +++++++++++++++++++++++++++++
- drivers/net/dsa/mv88e6xxx/port.c   |   1 +
- drivers/net/dsa/mv88e6xxx/port.h   | 133 +++++
- 7 files changed, 1031 insertions(+), 2 deletions(-)
- create mode 100644 drivers/net/dsa/mv88e6xxx/leds.c
-
---- a/drivers/net/dsa/mv88e6xxx/Kconfig
-+++ b/drivers/net/dsa/mv88e6xxx/Kconfig
-@@ -17,3 +17,13 @@ config NET_DSA_MV88E6XXX_PTP
-       help
-         Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch
-         chips that support it.
-+
-+config NET_DSA_MV88E6XXX_LEDS
-+      bool "LED support for Marvell 88E6xxx"
-+      default y
-+      depends on NET_DSA_MV88E6XXX
-+      depends on LEDS_CLASS=y || LEDS_CLASS=NET_DSA_MV88E6XXX
-+      depends on LEDS_TRIGGERS
-+      help
-+        This enabled support for controlling the LEDs attached to the
-+        Marvell 88E6xxx switch chips.
---- a/drivers/net/dsa/mv88e6xxx/Makefile
-+++ b/drivers/net/dsa/mv88e6xxx/Makefile
-@@ -9,6 +9,7 @@ mv88e6xxx-objs += global2.o
- mv88e6xxx-objs += global2_avb.o
- mv88e6xxx-objs += global2_scratch.o
- mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += hwtstamp.o
-+mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_LEDS) += leds.o
- mv88e6xxx-objs += pcs-6185.o
- mv88e6xxx-objs += pcs-6352.o
- mv88e6xxx-objs += pcs-639x.o
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -27,6 +27,7 @@
- #include <linux/of_irq.h>
- #include <linux/of_mdio.h>
- #include <linux/platform_data/mv88e6xxx.h>
-+#include <linux/property.h>
- #include <linux/netdevice.h>
- #include <linux/gpio/consumer.h>
- #include <linux/phylink.h>
-@@ -3412,14 +3413,43 @@ static int mv88e6xxx_setup_upstream_port
- static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
- {
-       struct device_node *phy_handle = NULL;
-+      struct fwnode_handle *ports_fwnode;
-+      struct fwnode_handle *port_fwnode;
-       struct dsa_switch *ds = chip->ds;
-+      struct mv88e6xxx_port *p;
-       struct dsa_port *dp;
-       int tx_amp;
-       int err;
-       u16 reg;
-+      u32 val;
--      chip->ports[port].chip = chip;
--      chip->ports[port].port = port;
-+      p = &chip->ports[port];
-+      p->chip = chip;
-+      p->port = port;
-+
-+      /* Look up corresponding fwnode if any */
-+      ports_fwnode = device_get_named_child_node(chip->dev, "ethernet-ports");
-+      if (!ports_fwnode)
-+              ports_fwnode = device_get_named_child_node(chip->dev, "ports");
-+      if (ports_fwnode) {
-+              fwnode_for_each_child_node(ports_fwnode, port_fwnode) {
-+                      if (fwnode_property_read_u32(port_fwnode, "reg", &val))
-+                              continue;
-+                      if (val == port) {
-+                              p->fwnode = port_fwnode;
-+                              p->fiber = fwnode_property_present(port_fwnode, "sfp");
-+                              break;
-+                      }
-+              }
-+      } else {
-+              dev_dbg(chip->dev, "no ethernet ports node defined for the device\n");
-+      }
-+
-+      if (chip->info->ops->port_setup_leds) {
-+              err = chip->info->ops->port_setup_leds(chip, port);
-+              if (err && err != -EOPNOTSUPP)
-+                      return err;
-+      }
-       err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
-                                      SPEED_UNFORCED, DUPLEX_UNFORCED,
-@@ -4653,6 +4683,7 @@ static const struct mv88e6xxx_ops mv88e6
-       .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
-       .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
-       .port_get_cmode = mv88e6352_port_get_cmode,
-+      .port_setup_leds = mv88e6xxx_port_setup_leds,
-       .port_setup_message_port = mv88e6xxx_setup_message_port,
-       .stats_snapshot = mv88e6320_g1_stats_snapshot,
-       .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
-@@ -4755,6 +4786,7 @@ static const struct mv88e6xxx_ops mv88e6
-       .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
-       .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
-       .port_get_cmode = mv88e6352_port_get_cmode,
-+      .port_setup_leds = mv88e6xxx_port_setup_leds,
-       .port_setup_message_port = mv88e6xxx_setup_message_port,
-       .stats_snapshot = mv88e6320_g1_stats_snapshot,
-       .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
-@@ -5030,6 +5062,7 @@ static const struct mv88e6xxx_ops mv88e6
-       .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
-       .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
-       .port_get_cmode = mv88e6352_port_get_cmode,
-+      .port_setup_leds = mv88e6xxx_port_setup_leds,
-       .port_setup_message_port = mv88e6xxx_setup_message_port,
-       .stats_snapshot = mv88e6320_g1_stats_snapshot,
-       .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
-@@ -5460,6 +5493,7 @@ static const struct mv88e6xxx_ops mv88e6
-       .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
-       .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
-       .port_get_cmode = mv88e6352_port_get_cmode,
-+      .port_setup_leds = mv88e6xxx_port_setup_leds,
-       .port_setup_message_port = mv88e6xxx_setup_message_port,
-       .stats_snapshot = mv88e6320_g1_stats_snapshot,
-       .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
---- a/drivers/net/dsa/mv88e6xxx/chip.h
-+++ b/drivers/net/dsa/mv88e6xxx/chip.h
-@@ -13,7 +13,9 @@
- #include <linux/irq.h>
- #include <linux/gpio/consumer.h>
- #include <linux/kthread.h>
-+#include <linux/leds.h>
- #include <linux/phy.h>
-+#include <linux/property.h>
- #include <linux/ptp_clock_kernel.h>
- #include <linux/timecounter.h>
- #include <net/dsa.h>
-@@ -276,6 +278,7 @@ struct mv88e6xxx_vlan {
- struct mv88e6xxx_port {
-       struct mv88e6xxx_chip *chip;
-       int port;
-+      struct fwnode_handle *fwnode;
-       struct mv88e6xxx_vlan bridge_pvid;
-       u64 serdes_stats[2];
-       u64 atu_member_violation;
-@@ -290,6 +293,11 @@ struct mv88e6xxx_port {
-       struct devlink_region *region;
-       void *pcs_private;
-+      /* LED related information */
-+      bool fiber;
-+      struct led_classdev led0;
-+      struct led_classdev led1;
-+
-       /* MacAuth Bypass control flag */
-       bool mab;
- };
-@@ -574,6 +582,9 @@ struct mv88e6xxx_ops {
-                             phy_interface_t mode);
-       int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
-+      /* LED control */
-+      int (*port_setup_leds)(struct mv88e6xxx_chip *chip, int port);
-+
-       /* Some devices have a per port register indicating what is
-        * the upstream port this port should forward to.
-        */
---- /dev/null
-+++ b/drivers/net/dsa/mv88e6xxx/leds.c
-@@ -0,0 +1,839 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+#include <linux/bitfield.h>
-+#include <linux/leds.h>
-+#include <linux/property.h>
-+
-+#include "chip.h"
-+#include "global2.h"
-+#include "port.h"
-+
-+/* Offset 0x16: LED control */
-+
-+static int mv88e6xxx_port_led_write(struct mv88e6xxx_chip *chip, int port, u16 reg)
-+{
-+      reg |= MV88E6XXX_PORT_LED_CONTROL_UPDATE;
-+
-+      return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_LED_CONTROL, reg);
-+}
-+
-+static int mv88e6xxx_port_led_read(struct mv88e6xxx_chip *chip, int port,
-+                                 u16 ptr, u16 *val)
-+{
-+      int err;
-+
-+      err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_LED_CONTROL, ptr);
-+      if (err)
-+              return err;
-+
-+      err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_LED_CONTROL, val);
-+      *val &= 0x3ff;
-+
-+      return err;
-+}
-+
-+static int mv88e6xxx_led_brightness_set(struct mv88e6xxx_port *p, int led,
-+                                      int brightness)
-+{
-+      u16 reg;
-+      int err;
-+
-+      err = mv88e6xxx_port_led_read(p->chip, p->port,
-+                                    MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL,
-+                                    &reg);
-+      if (err)
-+              return err;
-+
-+      if (led == 1)
-+              reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK;
-+      else
-+              reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK;
-+
-+      if (brightness) {
-+              /* Selector 0x0f == Force LED ON */
-+              if (led == 1)
-+                      reg |= MV88E6XXX_PORT_LED_CONTROL_LED1_SELF;
-+              else
-+                      reg |= MV88E6XXX_PORT_LED_CONTROL_LED0_SELF;
-+      } else {
-+              /* Selector 0x0e == Force LED OFF */
-+              if (led == 1)
-+                      reg |= MV88E6XXX_PORT_LED_CONTROL_LED1_SELE;
-+              else
-+                      reg |= MV88E6XXX_PORT_LED_CONTROL_LED0_SELE;
-+      }
-+
-+      reg |= MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL;
-+
-+      return mv88e6xxx_port_led_write(p->chip, p->port, reg);
-+}
-+
-+static int mv88e6xxx_led0_brightness_set_blocking(struct led_classdev *ldev,
-+                                                enum led_brightness brightness)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
-+      int err;
-+
-+      mv88e6xxx_reg_lock(p->chip);
-+      err = mv88e6xxx_led_brightness_set(p, 0, brightness);
-+      mv88e6xxx_reg_unlock(p->chip);
-+
-+      return err;
-+}
-+
-+static int mv88e6xxx_led1_brightness_set_blocking(struct led_classdev *ldev,
-+                                                enum led_brightness brightness)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
-+      int err;
-+
-+      mv88e6xxx_reg_lock(p->chip);
-+      err = mv88e6xxx_led_brightness_set(p, 1, brightness);
-+      mv88e6xxx_reg_unlock(p->chip);
-+
-+      return err;
-+}
-+
-+struct mv88e6xxx_led_hwconfig {
-+      int led;
-+      u8 portmask;
-+      unsigned long rules;
-+      bool fiber;
-+      bool blink_activity;
-+      u16 selector;
-+};
-+
-+/* The following is a lookup table to check what rules we can support on a
-+ * certain LED given restrictions such as that some rules only work with fiber
-+ * (SFP) connections and some blink on activity by default.
-+ */
-+#define MV88E6XXX_PORTS_0_3 (BIT(0) | BIT(1) | BIT(2) | BIT(3))
-+#define MV88E6XXX_PORTS_4_5 (BIT(4) | BIT(5))
-+#define MV88E6XXX_PORT_4 BIT(4)
-+#define MV88E6XXX_PORT_5 BIT(5)
-+
-+/* Entries are listed in selector order.
-+ *
-+ * These configurations vary across different switch families, list
-+ * different tables per-family here.
-+ */
-+static const struct mv88e6xxx_led_hwconfig mv88e6352_led_hwconfigs[] = {
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORT_4,
-+              .rules = BIT(TRIGGER_NETDEV_LINK),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL0,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORT_5,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_1000),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL0,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK_1000),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL1,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_100),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL1,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_4_5,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_100),
-+              .blink_activity = true,
-+              .fiber = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL1,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_4_5,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_1000),
-+              .blink_activity = true,
-+              .fiber = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL1,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_1000),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL2,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_100),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL2,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_4_5,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_1000),
-+              .blink_activity = true,
-+              .fiber = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL2,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_4_5,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_100),
-+              .blink_activity = true,
-+              .fiber = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL2,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL3,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_1000),
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL3,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_4_5,
-+              .rules = BIT(TRIGGER_NETDEV_LINK),
-+              .fiber = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL3,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORT_4,
-+              .rules = BIT(TRIGGER_NETDEV_LINK),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL4,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORT_5,
-+              .rules = BIT(TRIGGER_NETDEV_LINK),
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL5,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL6,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_1000),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL6,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORT_4,
-+              .rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL6,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORT_5,
-+              .rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL6,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_1000),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL7,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_1000),
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL7,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK),
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL8,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL8,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORT_5,
-+              .rules = BIT(TRIGGER_NETDEV_LINK),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL8,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_10),
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL9,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_100),
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL9,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_10),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SELA,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_100),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SELA,
-+      },
-+      {
-+              .led = 0,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK_1000),
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SELB,
-+      },
-+      {
-+              .led = 1,
-+              .portmask = MV88E6XXX_PORTS_0_3,
-+              .rules = BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK_1000),
-+              .blink_activity = true,
-+              .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SELB,
-+      },
-+};
-+
-+/* mv88e6xxx_led_match_selector() - look up the appropriate LED mode selector
-+ * @p: port state container
-+ * @led: LED number, 0 or 1
-+ * @blink_activity: blink the LED (usually blink on indicated activity)
-+ * @fiber: the link is connected to fiber such as SFP
-+ * @rules: LED status flags from the LED classdev core
-+ * @selector: fill in the selector in this parameter with an OR operation
-+ */
-+static int mv88e6xxx_led_match_selector(struct mv88e6xxx_port *p, int led, bool blink_activity,
-+                                      bool fiber, unsigned long rules, u16 *selector)
-+{
-+      const struct mv88e6xxx_led_hwconfig *conf;
-+      int i;
-+
-+      /* No rules means we turn the LED off */
-+      if (!rules) {
-+              if (led == 1)
-+                      *selector |= MV88E6XXX_PORT_LED_CONTROL_LED1_SELE;
-+              else
-+                      *selector |= MV88E6XXX_PORT_LED_CONTROL_LED0_SELE;
-+              return 0;
-+      }
-+
-+      /* TODO: these rules are for MV88E6352, when adding other families,
-+       * think about making sure you select the table that match the
-+       * specific switch family.
-+       */
-+      for (i = 0; i < ARRAY_SIZE(mv88e6352_led_hwconfigs); i++) {
-+              conf = &mv88e6352_led_hwconfigs[i];
-+
-+              if (conf->led != led)
-+                      continue;
-+
-+              if (!(conf->portmask & BIT(p->port)))
-+                      continue;
-+
-+              if (conf->blink_activity != blink_activity)
-+                      continue;
-+
-+              if (conf->fiber != fiber)
-+                      continue;
-+
-+              if (conf->rules == rules) {
-+                      dev_dbg(p->chip->dev, "port%d LED %d set selector %04x for rules %08lx\n",
-+                              p->port, led, conf->selector, rules);
-+                      *selector |= conf->selector;
-+                      return 0;
-+              }
-+      }
-+
-+      return -EOPNOTSUPP;
-+}
-+
-+/* mv88e6xxx_led_match_selector() - find Linux netdev rules from a selector value
-+ * @p: port state container
-+ * @selector: the selector value from the LED actity register
-+ * @led: LED number, 0 or 1
-+ * @rules: Linux netdev activity rules found from selector
-+ */
-+static int
-+mv88e6xxx_led_match_rule(struct mv88e6xxx_port *p, u16 selector, int led, unsigned long *rules)
-+{
-+      const struct mv88e6xxx_led_hwconfig *conf;
-+      int i;
-+
-+      /* Find the selector in the table, we just look for the right selector
-+       * and ignore if the activity has special properties such as blinking
-+       * or is fiber-only.
-+       */
-+      for (i = 0; i < ARRAY_SIZE(mv88e6352_led_hwconfigs); i++) {
-+              conf = &mv88e6352_led_hwconfigs[i];
-+
-+              if (conf->led != led)
-+                      continue;
-+
-+              if (!(conf->portmask & BIT(p->port)))
-+                      continue;
-+
-+              if (conf->selector == selector) {
-+                      dev_dbg(p->chip->dev, "port%d LED %d has selector %04x, rules %08lx\n",
-+                              p->port, led, selector, conf->rules);
-+                      *rules = conf->rules;
-+                      return 0;
-+              }
-+      }
-+
-+      return -EINVAL;
-+}
-+
-+/* mv88e6xxx_led_get_selector() - get the appropriate LED mode selector
-+ * @p: port state container
-+ * @led: LED number, 0 or 1
-+ * @fiber: the link is connected to fiber such as SFP
-+ * @rules: LED status flags from the LED classdev core
-+ * @selector: fill in the selector in this parameter with an OR operation
-+ */
-+static int mv88e6xxx_led_get_selector(struct mv88e6xxx_port *p, int led,
-+                                    bool fiber, unsigned long rules, u16 *selector)
-+{
-+      int err;
-+
-+      /* What happens here is that we first try to locate a trigger with solid
-+       * indicator (such as LED is on for a 1000 link) else we try a second
-+       * sweep to find something suitable with a trigger that will blink on
-+       * activity.
-+       */
-+      err = mv88e6xxx_led_match_selector(p, led, false, fiber, rules, selector);
-+      if (err)
-+              return mv88e6xxx_led_match_selector(p, led, true, fiber, rules, selector);
-+
-+      return 0;
-+}
-+
-+/* Sets up the hardware blinking period */
-+static int mv88e6xxx_led_set_blinking_period(struct mv88e6xxx_port *p, int led,
-+                                           unsigned long delay_on, unsigned long delay_off)
-+{
-+      unsigned long period;
-+      u16 reg;
-+
-+      period = delay_on + delay_off;
-+
-+      reg = 0;
-+
-+      switch (period) {
-+      case 21:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_21MS;
-+              break;
-+      case 42:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_42MS;
-+              break;
-+      case 84:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_84MS;
-+              break;
-+      case 168:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_168MS;
-+              break;
-+      case 336:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_336MS;
-+              break;
-+      case 672:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_672MS;
-+              break;
-+      default:
-+              /* Fall back to software blinking */
-+              return -EINVAL;
-+      }
-+
-+      /* This is essentially PWM duty cycle: how long time of the period
-+       * will the LED be on. Zero isn't great in most cases.
-+       */
-+      switch (delay_on) {
-+      case 0:
-+              /* This is usually pretty useless and will make the LED look OFF */
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_NONE;
-+              break;
-+      case 21:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_21MS;
-+              break;
-+      case 42:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_42MS;
-+              break;
-+      case 84:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_84MS;
-+              break;
-+      case 168:
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_168MS;
-+              break;
-+      default:
-+              /* Just use something non-zero */
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_21MS;
-+              break;
-+      }
-+
-+      /* Set up blink rate */
-+      reg |= MV88E6XXX_PORT_LED_CONTROL_POINTER_STRETCH_BLINK;
-+
-+      return mv88e6xxx_port_led_write(p->chip, p->port, reg);
-+}
-+
-+static int mv88e6xxx_led_blink_set(struct mv88e6xxx_port *p, int led,
-+                                 unsigned long *delay_on, unsigned long *delay_off)
-+{
-+      u16 reg;
-+      int err;
-+
-+      /* Choose a sensible default 336 ms (~3 Hz) */
-+      if ((*delay_on == 0) && (*delay_off == 0)) {
-+              *delay_on = 168;
-+              *delay_off = 168;
-+      }
-+
-+      /* No off delay is just on */
-+      if (*delay_off == 0)
-+              return mv88e6xxx_led_brightness_set(p, led, 1);
-+
-+      err = mv88e6xxx_led_set_blinking_period(p, led, *delay_on, *delay_off);
-+      if (err)
-+              return err;
-+
-+      err = mv88e6xxx_port_led_read(p->chip, p->port,
-+                                    MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL,
-+                                    &reg);
-+      if (err)
-+              return err;
-+
-+      if (led == 1)
-+              reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK;
-+      else
-+              reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK;
-+
-+      /* This will select the forced blinking status */
-+      if (led == 1)
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_LED1_SELD;
-+      else
-+              reg |= MV88E6XXX_PORT_LED_CONTROL_LED0_SELD;
-+
-+      reg |= MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL;
-+
-+      return mv88e6xxx_port_led_write(p->chip, p->port, reg);
-+}
-+
-+static int mv88e6xxx_led0_blink_set(struct led_classdev *ldev,
-+                                  unsigned long *delay_on,
-+                                  unsigned long *delay_off)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
-+      int err;
-+
-+      mv88e6xxx_reg_lock(p->chip);
-+      err = mv88e6xxx_led_blink_set(p, 0, delay_on, delay_off);
-+      mv88e6xxx_reg_unlock(p->chip);
-+
-+      return err;
-+}
-+
-+static int mv88e6xxx_led1_blink_set(struct led_classdev *ldev,
-+                                  unsigned long *delay_on,
-+                                  unsigned long *delay_off)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
-+      int err;
-+
-+      mv88e6xxx_reg_lock(p->chip);
-+      err = mv88e6xxx_led_blink_set(p, 1, delay_on, delay_off);
-+      mv88e6xxx_reg_unlock(p->chip);
-+
-+      return err;
-+}
-+
-+static int
-+mv88e6xxx_led0_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
-+      u16 selector = 0;
-+
-+      return mv88e6xxx_led_get_selector(p, 0, p->fiber, rules, &selector);
-+}
-+
-+static int
-+mv88e6xxx_led1_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
-+      u16 selector = 0;
-+
-+      return mv88e6xxx_led_get_selector(p, 1, p->fiber, rules, &selector);
-+}
-+
-+static int mv88e6xxx_led_hw_control_set(struct mv88e6xxx_port *p,
-+                                      int led, unsigned long rules)
-+{
-+      u16 reg;
-+      int err;
-+
-+      err = mv88e6xxx_port_led_read(p->chip, p->port,
-+                                    MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL,
-+                                    &reg);
-+      if (err)
-+              return err;
-+
-+      if (led == 1)
-+              reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK;
-+      else
-+              reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK;
-+
-+      err = mv88e6xxx_led_get_selector(p, led, p->fiber, rules, &reg);
-+      if (err)
-+              return err;
-+
-+      reg |= MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL;
-+
-+      if (led == 0)
-+              dev_dbg(p->chip->dev, "LED 0 hw control on port %d trigger selector 0x%02x\n",
-+                      p->port,
-+                      (unsigned int)(reg & MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK));
-+      else
-+              dev_dbg(p->chip->dev, "LED 1 hw control on port %d trigger selector 0x%02x\n",
-+                      p->port,
-+                      (unsigned int)(reg & MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK) >> 4);
-+
-+      return mv88e6xxx_port_led_write(p->chip, p->port, reg);
-+}
-+
-+static int
-+mv88e6xxx_led_hw_control_get(struct mv88e6xxx_port *p, int led, unsigned long *rules)
-+{
-+      u16 val;
-+      int err;
-+
-+      mv88e6xxx_reg_lock(p->chip);
-+      err = mv88e6xxx_port_led_read(p->chip, p->port,
-+                                    MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL, &val);
-+      mv88e6xxx_reg_unlock(p->chip);
-+      if (err)
-+              return err;
-+
-+      /* Mask out the selector bits for this port */
-+      if (led == 1) {
-+              val &= MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK;
-+              /* It's forced blinking/OFF/ON */
-+              if (val == MV88E6XXX_PORT_LED_CONTROL_LED1_SELD ||
-+                  val == MV88E6XXX_PORT_LED_CONTROL_LED1_SELE ||
-+                  val == MV88E6XXX_PORT_LED_CONTROL_LED1_SELF) {
-+                      *rules = 0;
-+                      return 0;
-+              }
-+      } else {
-+              val &= MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK;
-+              /* It's forced blinking/OFF/ON */
-+              if (val == MV88E6XXX_PORT_LED_CONTROL_LED0_SELD ||
-+                  val == MV88E6XXX_PORT_LED_CONTROL_LED0_SELE ||
-+                  val == MV88E6XXX_PORT_LED_CONTROL_LED0_SELF) {
-+                      *rules = 0;
-+                      return 0;
-+              }
-+      }
-+
-+      err = mv88e6xxx_led_match_rule(p, val, led, rules);
-+      if (!err)
-+              return 0;
-+
-+      dev_dbg(p->chip->dev, "couldn't find matching selector for %04x\n", val);
-+      *rules = 0;
-+      return 0;
-+}
-+
-+static int
-+mv88e6xxx_led0_hw_control_set(struct led_classdev *ldev, unsigned long rules)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
-+      int err;
-+
-+      mv88e6xxx_reg_lock(p->chip);
-+      err = mv88e6xxx_led_hw_control_set(p, 0, rules);
-+      mv88e6xxx_reg_unlock(p->chip);
-+
-+      return err;
-+}
-+
-+static int
-+mv88e6xxx_led1_hw_control_set(struct led_classdev *ldev, unsigned long rules)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
-+      int err;
-+
-+      mv88e6xxx_reg_lock(p->chip);
-+      err = mv88e6xxx_led_hw_control_set(p, 1, rules);
-+      mv88e6xxx_reg_unlock(p->chip);
-+
-+      return err;
-+}
-+
-+static int
-+mv88e6xxx_led0_hw_control_get(struct led_classdev *ldev, unsigned long *rules)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
-+
-+      return mv88e6xxx_led_hw_control_get(p, 0, rules);
-+}
-+
-+static int
-+mv88e6xxx_led1_hw_control_get(struct led_classdev *ldev, unsigned long *rules)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
-+
-+      return mv88e6xxx_led_hw_control_get(p, 1, rules);
-+}
-+
-+static struct device *mv88e6xxx_led_hw_control_get_device(struct mv88e6xxx_port *p)
-+{
-+      struct dsa_port *dp;
-+
-+      dp = dsa_to_port(p->chip->ds, p->port);
-+      if (!dp)
-+              return NULL;
-+      if (dp->user)
-+              return &dp->user->dev;
-+      return NULL;
-+}
-+
-+static struct device *
-+mv88e6xxx_led0_hw_control_get_device(struct led_classdev *ldev)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0);
-+
-+      return mv88e6xxx_led_hw_control_get_device(p);
-+}
-+
-+static struct device *
-+mv88e6xxx_led1_hw_control_get_device(struct led_classdev *ldev)
-+{
-+      struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1);
-+
-+      return mv88e6xxx_led_hw_control_get_device(p);
-+}
-+
-+int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, int port)
-+{
-+      struct fwnode_handle *led = NULL, *leds = NULL;
-+      struct led_init_data init_data = { };
-+      enum led_default_state state;
-+      struct mv88e6xxx_port *p;
-+      struct led_classdev *l;
-+      struct device *dev;
-+      u32 led_num;
-+      int ret;
-+
-+      /* LEDs are on ports 1,2,3,4, 5 and 6 (index 0..5), no more */
-+      if (port > 5)
-+              return -EOPNOTSUPP;
-+
-+      p = &chip->ports[port];
-+      if (!p->fwnode)
-+              return 0;
-+
-+      dev = chip->dev;
-+
-+      leds = fwnode_get_named_child_node(p->fwnode, "leds");
-+      if (!leds) {
-+              dev_dbg(dev, "No Leds node specified in device tree for port %d!\n",
-+                      port);
-+              return 0;
-+      }
-+
-+      fwnode_for_each_child_node(leds, led) {
-+              /* Reg represent the led number of the port, max 2
-+               * LEDs can be connected to each port, in some designs
-+               * only one LED is connected.
-+               */
-+              if (fwnode_property_read_u32(led, "reg", &led_num))
-+                      continue;
-+              if (led_num > 1) {
-+                      dev_err(dev, "invalid LED specified port %d\n", port);
-+                      return -EINVAL;
-+              }
-+
-+              if (led_num == 0)
-+                      l = &p->led0;
-+              else
-+                      l = &p->led1;
-+
-+              state = led_init_default_state_get(led);
-+              switch (state) {
-+              case LEDS_DEFSTATE_ON:
-+                      l->brightness = 1;
-+                      mv88e6xxx_led_brightness_set(p, led_num, 1);
-+                      break;
-+              case LEDS_DEFSTATE_KEEP:
-+                      break;
-+              default:
-+                      l->brightness = 0;
-+                      mv88e6xxx_led_brightness_set(p, led_num, 0);
-+              }
-+
-+              l->max_brightness = 1;
-+              if (led_num == 0) {
-+                      l->brightness_set_blocking = mv88e6xxx_led0_brightness_set_blocking;
-+                      l->blink_set = mv88e6xxx_led0_blink_set;
-+                      l->hw_control_is_supported = mv88e6xxx_led0_hw_control_is_supported;
-+                      l->hw_control_set = mv88e6xxx_led0_hw_control_set;
-+                      l->hw_control_get = mv88e6xxx_led0_hw_control_get;
-+                      l->hw_control_get_device = mv88e6xxx_led0_hw_control_get_device;
-+              } else {
-+                      l->brightness_set_blocking = mv88e6xxx_led1_brightness_set_blocking;
-+                      l->blink_set = mv88e6xxx_led1_blink_set;
-+                      l->hw_control_is_supported = mv88e6xxx_led1_hw_control_is_supported;
-+                      l->hw_control_set = mv88e6xxx_led1_hw_control_set;
-+                      l->hw_control_get = mv88e6xxx_led1_hw_control_get;
-+                      l->hw_control_get_device = mv88e6xxx_led1_hw_control_get_device;
-+              }
-+              l->hw_control_trigger = "netdev";
-+
-+              init_data.default_label = ":port";
-+              init_data.fwnode = led;
-+              init_data.devname_mandatory = true;
-+              init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d:0%d", chip->info->name,
-+                                               port, led_num);
-+              if (!init_data.devicename)
-+                      return -ENOMEM;
-+
-+              ret = devm_led_classdev_register_ext(dev, l, &init_data);
-+              kfree(init_data.devicename);
-+
-+              if (ret) {
-+                      dev_err(dev, "Failed to init LED %d for port %d", led_num, port);
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
---- a/drivers/net/dsa/mv88e6xxx/port.c
-+++ b/drivers/net/dsa/mv88e6xxx/port.c
-@@ -12,6 +12,7 @@
- #include <linux/if_bridge.h>
- #include <linux/phy.h>
- #include <linux/phylink.h>
-+#include <linux/property.h>
- #include "chip.h"
- #include "global2.h"
---- a/drivers/net/dsa/mv88e6xxx/port.h
-+++ b/drivers/net/dsa/mv88e6xxx/port.h
-@@ -309,6 +309,130 @@
- /* Offset 0x13: OutFiltered Counter */
- #define MV88E6XXX_PORT_OUT_FILTERED   0x13
-+/* Offset 0x16: LED Control */
-+#define MV88E6XXX_PORT_LED_CONTROL                            0x16
-+#define MV88E6XXX_PORT_LED_CONTROL_UPDATE                     BIT(15)
-+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_MASK                       GENMASK(14, 12)
-+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL         (0x00 << 12) /* Control for LED 0 and 1 */
-+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_STRETCH_BLINK      (0x06 << 12) /* Stetch and Blink Rate */
-+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_CNTL_SPECIAL               (0x07 << 12) /* Control for the Port's Special LED */
-+#define MV88E6XXX_PORT_LED_CONTROL_DATA_MASK                  GENMASK(10, 0)
-+/* Selection masks valid for either port 1,2,3,4 or 5 */
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK              GENMASK(3, 0)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK              GENMASK(7, 4)
-+/* Selection control for LED 0 and 1, ports 5 and 6 only has LED 0
-+ * Bits  Function
-+ * 0..3  LED 0 control selector on ports 1-5
-+ * 4..7  LED 1 control selector on ports 1-4 on port 5 this controls LED 0 of port 6
-+ *
-+ * Sel Port LED Function for the 6352 family:
-+ * 0   1-4  0   Link/Act/Speed by Blink Rate (off=no link, on=link, blink=activity, blink speed=link speed)
-+ *     1-4  1   Port 2's Special LED
-+ *     5-6  0   Port 5 Link/Act (off=no link, on=link, blink=activity)
-+ *     5-6  1   Port 6 Link/Act (off=no link, on=link 1000, blink=activity)
-+ * 1   1-4  0   100/1000 Link/Act (off=no link, on=100 or 1000 link, blink=activity)
-+ *     1-4  1   10/100 Link Act (off=no link, on=10 or 100 link, blink=activity)
-+ *     5-6  0   Fiber 100 Link/Act (off=no link, on=link 100, blink=activity)
-+ *     5-6  1   Fiber 1000 Link/Act (off=no link, on=link 1000, blink=activity)
-+ * 2   1-4  0   1000 Link/Act (off=no link, on=link 1000, blink=activity)
-+ *     1-4  1   10/100 Link/Act (off=no link, on=10 or 100 link, blink=activity)
-+ *     5-6  0   Fiber 1000 Link/Act (off=no link, on=link 1000, blink=activity)
-+ *     5-6  1   Fiber 100 Link/Act (off=no link, on=link 100, blink=activity)
-+ * 3   1-4  0   Link/Act (off=no link, on=link, blink=activity)
-+ *     1-4  1   1000 Link (off=no link, on=1000 link)
-+ *     5-6  0   Port 0's Special LED
-+ *     5-6  1   Fiber Link (off=no link, on=link)
-+ * 4   1-4  0   Port 0's Special LED
-+ *     1-4  1   Port 1's Special LED
-+ *     5-6  0   Port 1's Special LED
-+ *     5-6  1   Port 5 Link/Act (off=no link, on=link, blink=activity)
-+ * 5   1-4  0   Reserved
-+ *     1-4  1   Reserved
-+ *     5-6  0   Port 2's Special LED
-+ *     5-6  1   Port 6 Link (off=no link, on=link)
-+ * 6   1-4  0   Duplex/Collision (off=half-duplex,on=full-duplex,blink=collision)
-+ *     1-4  1   10/1000 Link/Act (off=no link, on=10 or 1000 link, blink=activity)
-+ *     5-6  0   Port 5 Duplex/Collision (off=half-duplex, on=full-duplex, blink=col)
-+ *     5-6  1   Port 6 Duplex/Collision (off=half-duplex, on=full-duplex, blink=col)
-+ * 7   1-4  0   10/1000 Link/Act (off=no link, on=10 or 1000 link, blink=activity)
-+ *     1-4  1   10/1000 Link (off=no link, on=10 or 1000 link)
-+ *     5-6  0   Port 5 Link/Act/Speed by Blink rate (off=no link, on=link, blink=activity, blink speed=link speed)
-+ *     5-6  1   Port 6 Link/Act/Speed by Blink rate (off=no link, on=link, blink=activity,  blink speed=link speed)
-+ * 8   1-4  0   Link (off=no link, on=link)
-+ *     1-4  1   Activity (off=no link, blink on=activity)
-+ *     5-6  0   Port 6 Link/Act (off=no link, on=link, blink=activity)
-+ *     5-6  1   Port 0's Special LED
-+ * 9   1-4  0   10 Link (off=no link, on=10 link)
-+ *     1-4  1   100 Link (off=no link, on=100 link)
-+ *     5-6  0   Reserved
-+ *     5-6  1   Port 1's Special LED
-+ * a   1-4  0   10 Link/Act (off=no link, on=10 link, blink=activity)
-+ *     1-4  1   100 Link/Act (off=no link, on=100 link, blink=activity)
-+ *     5-6  0   Reserved
-+ *     5-6  1   Port 2's Special LED
-+ * b   1-4  0   100/1000 Link (off=no link, on=100 or 1000 link)
-+ *     1-4  1   10/100 Link (off=no link, on=100 link, blink=activity)
-+ *     5-6  0   Reserved
-+ *     5-6  1   Reserved
-+ * c     *  *   PTP Act (blink on=PTP activity)
-+ * d     *  *   Force Blink
-+ * e     *  *   Force Off
-+ * f     *  *   Force On
-+ */
-+/* Select LED0 output */
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL0                  0x0
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL1                  0x1
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL2                  0x2
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL3                  0x3
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL4                  0x4
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL5                  0x5
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL6                  0x6
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL7                  0x7
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL8                  0x8
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL9                  0x9
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELA                  0xa
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELB                  0xb
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELC                  0xc
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELD                  0xd
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELE                  0xe
-+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELF                  0xf
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL0                  (0x0 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL1                  (0x1 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL2                  (0x2 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL3                  (0x3 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL4                  (0x4 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL5                  (0x5 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL6                  (0x6 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL7                  (0x7 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL8                  (0x8 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL9                  (0x9 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELA                  (0xa << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELB                  (0xb << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELC                  (0xc << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELD                  (0xd << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELE                  (0xe << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELF                  (0xf << 4)
-+/* Stretch and Blink Rate Control (Index 0x06 of LED Control) */
-+/* Pulse Stretch Selection for all LED's on this port */
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_NONE    (0 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_21MS    (1 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_42MS    (2 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_84MS    (3 << 4)
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_168MS   (4 << 4)
-+/* Blink Rate Selection for all LEDs on this port */
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_21MS               0
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_42MS               1
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_84MS               2
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_168MS      3
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_336MS      4
-+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_672MS      5
-+ /* Control for Special LED (Index 0x7 of LED Control on Port0) */
-+#define MV88E6XXX_PORT_LED_CONTROL_0x07_P0_LAN_LINKACT_SHIFT  0 /* bits 6:0 LAN Link Activity LED */
-+/* Control for Special LED (Index 0x7 of LED Control on Port 1) */
-+#define MV88E6XXX_PORT_LED_CONTROL_0x07_P1_WAN_LINKACT_SHIFT  0 /* bits 6:0 WAN Link Activity LED */
-+/* Control for Special LED (Index 0x7 of LED Control on Port 2) */
-+#define MV88E6XXX_PORT_LED_CONTROL_0x07_P2_PTP_ACT            0 /* bits 6:0 PTP Activity */
-+
- /* Offset 0x18: IEEE Priority Mapping Table */
- #define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE                    0x18
- #define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE             0x8000
-@@ -457,6 +581,15 @@ int mv88e6393x_port_set_cmode(struct mv8
-                             phy_interface_t mode);
- int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
- int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
-+#ifdef CONFIG_NET_DSA_MV88E6XXX_LEDS
-+int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, int port);
-+#else
-+static inline int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip,
-+                                          int port)
-+{
-+      return 0;
-+}
-+#endif
- int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port,
-                                bool drop_untagged);
- int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port, bool map);
diff --git a/target/linux/generic/backport-6.18/741-v6.13-net-dsa-mv88e6xxx-fix-unreleased-fwnode_handle-in-se.patch b/target/linux/generic/backport-6.18/741-v6.13-net-dsa-mv88e6xxx-fix-unreleased-fwnode_handle-in-se.patch
deleted file mode 100644 (file)
index 2c81983..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From b8ee7a11c75436b85fa1641aa5f970de0f8a575c Mon Sep 17 00:00:00 2001
-From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
-Date: Sat, 19 Oct 2024 22:16:49 +0200
-Subject: net: dsa: mv88e6xxx: fix unreleased fwnode_handle in setup_port()
-
-'ports_fwnode' is initialized via device_get_named_child_node(), which
-requires a call to fwnode_handle_put() when the variable is no longer
-required to avoid leaking memory.
-
-Add the missing fwnode_handle_put() after 'ports_fwnode' has been used
-and is no longer required.
-
-Fixes: 94a2a84f5e9e ("net: dsa: mv88e6xxx: Support LED control")
-Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mv88e6xxx/chip.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/dsa/mv88e6xxx/chip.c
-+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3441,6 +3441,7 @@ static int mv88e6xxx_setup_port(struct m
-                               break;
-                       }
-               }
-+              fwnode_handle_put(ports_fwnode);
-       } else {
-               dev_dbg(chip->dev, "no ethernet ports node defined for the device\n");
-       }
diff --git a/target/linux/generic/backport-6.18/742-v6.17-net-dsa-mv88e6xxx-Fix-fwnode-reference-leaks-in-mv88.patch b/target/linux/generic/backport-6.18/742-v6.17-net-dsa-mv88e6xxx-Fix-fwnode-reference-leaks-in-mv88.patch
deleted file mode 100644 (file)
index 6e0fbb8..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From f63e7c8a83892781f6ceb55566f9497639c44555 Mon Sep 17 00:00:00 2001
-From: Miaoqian Lin <linmq006@gmail.com>
-Date: Mon, 1 Sep 2025 15:32:23 +0800
-Subject: net: dsa: mv88e6xxx: Fix fwnode reference leaks in
- mv88e6xxx_port_setup_leds
-
-Fix multiple fwnode reference leaks:
-
-1. The function calls fwnode_get_named_child_node() to get the "leds" node,
-   but never calls fwnode_handle_put(leds) to release this reference.
-
-2. Within the fwnode_for_each_child_node() loop, the early return
-   paths that don't properly release the "led" fwnode reference.
-
-This fix follows the same pattern as commit d029edefed39
-("net dsa: qca8k: fix usages of device_get_named_child_node()")
-
-Fixes: 94a2a84f5e9e ("net: dsa: mv88e6xxx: Support LED control")
-Cc: stable@vger.kernel.org
-Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://patch.msgid.link/20250901073224.2273103-1-linmq006@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mv88e6xxx/leds.c | 17 +++++++++++++----
- 1 file changed, 13 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/mv88e6xxx/leds.c
-+++ b/drivers/net/dsa/mv88e6xxx/leds.c
-@@ -779,7 +779,8 @@ int mv88e6xxx_port_setup_leds(struct mv8
-                       continue;
-               if (led_num > 1) {
-                       dev_err(dev, "invalid LED specified port %d\n", port);
--                      return -EINVAL;
-+                      ret = -EINVAL;
-+                      goto err_put_led;
-               }
-               if (led_num == 0)
-@@ -823,17 +824,25 @@ int mv88e6xxx_port_setup_leds(struct mv8
-               init_data.devname_mandatory = true;
-               init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d:0%d", chip->info->name,
-                                                port, led_num);
--              if (!init_data.devicename)
--                      return -ENOMEM;
-+              if (!init_data.devicename) {
-+                      ret = -ENOMEM;
-+                      goto err_put_led;
-+              }
-               ret = devm_led_classdev_register_ext(dev, l, &init_data);
-               kfree(init_data.devicename);
-               if (ret) {
-                       dev_err(dev, "Failed to init LED %d for port %d", led_num, port);
--                      return ret;
-+                      goto err_put_led;
-               }
-       }
-+      fwnode_handle_put(leds);
-       return 0;
-+
-+err_put_led:
-+      fwnode_handle_put(led);
-+      fwnode_handle_put(leds);
-+      return ret;
- }
diff --git a/target/linux/generic/backport-6.18/760-v6.18-net-phy-introduce-phy_id_compare_model-PHY-ID-helper.patch b/target/linux/generic/backport-6.18/760-v6.18-net-phy-introduce-phy_id_compare_model-PHY-ID-helper.patch
deleted file mode 100644 (file)
index a367f66..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From ae1c658b33d4bec20c037aebba583a68375d4773 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 11 Sep 2025 15:08:31 +0200
-Subject: [PATCH] net: phy: introduce phy_id_compare_model() PHY ID helper
-
-Similar to phy_id_compare_vendor(), introduce the equivalent
-phy_id_compare_model() helper for the generic PHY ID Model mask.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://patch.msgid.link/20250911130840.23569-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/linux/phy.h | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1284,6 +1284,19 @@ static inline bool phy_id_compare(u32 id
- }
- /**
-+ * phy_id_compare_model - compare @id with @model mask
-+ * @id: PHY ID
-+ * @model_mask: PHY Model mask
-+ *
-+ * Return: true if the bits from @id match @model using the
-+ *       generic PHY Model mask.
-+ */
-+static inline bool phy_id_compare_model(u32 id, u32 model_mask)
-+{
-+      return phy_id_compare(id, model_mask, PHY_ID_MATCH_MODEL_MASK);
-+}
-+
-+/**
-  * phydev_id_compare - compare @id with the PHY's Clause 22 ID
-  * @phydev: the PHY device
-  * @id: the PHY ID to be matched
diff --git a/target/linux/generic/backport-6.18/780-01-v6.13-r8169-remove-original-workaround-for-RTL8125-broken-.patch b/target/linux/generic/backport-6.18/780-01-v6.13-r8169-remove-original-workaround-for-RTL8125-broken-.patch
deleted file mode 100644 (file)
index bd10a96..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From 854d71c555dfc3383c1fde7d9989b6046e21093d Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 9 Oct 2024 07:48:05 +0200
-Subject: [PATCH] r8169: remove original workaround for RTL8125 broken rx issue
-
-Now that we have b9c7ac4fe22c ("r8169: disable ALDPS per default for
-RTL8125"), the first attempt to fix the issue shouldn't be needed
-any longer. So let's effectively revert 621735f59064 ("r8169: fix
-rare issue with broken rx after link-down on RTL8125") and see
-whether anybody complains.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/382d8c88-cbce-400f-ad62-fda0181c7e38@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 4 ----
- 1 file changed, 4 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -4810,11 +4810,7 @@ static void r8169_phylink_handler(struct
-       if (netif_carrier_ok(ndev)) {
-               rtl_link_chg_patch(tp);
-               pm_request_resume(d);
--              netif_wake_queue(tp->dev);
-       } else {
--              /* In few cases rx is broken after link-down otherwise */
--              if (rtl_is_8125(tp))
--                      rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE);
-               pm_runtime_idle(d);
-       }
diff --git a/target/linux/generic/backport-6.18/780-02-v6.13-r8169-enable-SG-TSO-on-selected-chip-versions-per-de.patch b/target/linux/generic/backport-6.18/780-02-v6.13-r8169-enable-SG-TSO-on-selected-chip-versions-per-de.patch
deleted file mode 100644 (file)
index 7ea1a11..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From b8bf38440ba94e8ed8e2ae55c5dfb0276d30e843 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 10 Oct 2024 12:58:02 +0200
-Subject: [PATCH] r8169: enable SG/TSO on selected chip versions per default
-
-Due to problem reports in the past SG and TSO/TSO6 are disabled per
-default. It's not fully clear which chip versions are affected, so we
-may impact also users of unaffected chip versions, unless they know
-how to use ethtool for enabling SG/TSO/TSO6.
-Vendor drivers r8168/r8125 enable SG/TSO/TSO6 for selected chip
-versions per default, I'd interpret this as confirmation that these
-chip versions are unaffected. So let's do the same here.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/r8169_main.c | 16 +++++++++++-----
- 1 file changed, 11 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5524,11 +5524,6 @@ static int rtl_init_one(struct pci_dev *
-       dev->features |= dev->hw_features;
--      /* There has been a number of reports that using SG/TSO results in
--       * tx timeouts. However for a lot of people SG/TSO works fine.
--       * Therefore disable both features by default, but allow users to
--       * enable them. Use at own risk!
--       */
-       if (rtl_chip_supports_csum_v2(tp)) {
-               dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6;
-               netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V2);
-@@ -5539,6 +5534,17 @@ static int rtl_init_one(struct pci_dev *
-               netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V1);
-       }
-+      /* There has been a number of reports that using SG/TSO results in
-+       * tx timeouts. However for a lot of people SG/TSO works fine.
-+       * It's not fully clear which chip versions are affected. Vendor
-+       * drivers enable SG/TSO for certain chip versions per default,
-+       * let's mimic this here. On other chip versions users can
-+       * use ethtool to enable SG/TSO, use at own risk!
-+       */
-+      if (tp->mac_version >= RTL_GIGA_MAC_VER_46 &&
-+          tp->mac_version != RTL_GIGA_MAC_VER_61)
-+              dev->features |= dev->hw_features;
-+
-       dev->hw_features |= NETIF_F_RXALL;
-       dev->hw_features |= NETIF_F_RXFCS;
diff --git a/target/linux/generic/backport-6.18/780-03-v6.13-r8169-implement-additional-ethtool-stats-ops.patch b/target/linux/generic/backport-6.18/780-03-v6.13-r8169-implement-additional-ethtool-stats-ops.patch
deleted file mode 100644 (file)
index 594a8fa..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-From e3fc5139bd8ffaa1498adc21be4e8ecbc6aed508 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sun, 13 Oct 2024 11:17:39 +0200
-Subject: [PATCH] r8169: implement additional ethtool stats ops
-
-This adds support for ethtool standard statistics, and makes use of the
-extended hardware statistics being available from RTl8125.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/58e0da73-a7dd-4be3-82ae-d5b3f9069bde@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 82 +++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -2160,6 +2160,19 @@ static void rtl8169_get_ringparam(struct
-       data->tx_pending = NUM_TX_DESC;
- }
-+static void rtl8169_get_pause_stats(struct net_device *dev,
-+                                  struct ethtool_pause_stats *pause_stats)
-+{
-+      struct rtl8169_private *tp = netdev_priv(dev);
-+
-+      if (!rtl_is_8125(tp))
-+              return;
-+
-+      rtl8169_update_counters(tp);
-+      pause_stats->tx_pause_frames = le32_to_cpu(tp->counters->tx_pause_on);
-+      pause_stats->rx_pause_frames = le32_to_cpu(tp->counters->rx_pause_on);
-+}
-+
- static void rtl8169_get_pauseparam(struct net_device *dev,
-                                  struct ethtool_pauseparam *data)
- {
-@@ -2186,6 +2199,69 @@ static int rtl8169_set_pauseparam(struct
-       return 0;
- }
-+static void rtl8169_get_eth_mac_stats(struct net_device *dev,
-+                                    struct ethtool_eth_mac_stats *mac_stats)
-+{
-+      struct rtl8169_private *tp = netdev_priv(dev);
-+
-+      rtl8169_update_counters(tp);
-+
-+      mac_stats->FramesTransmittedOK =
-+              le64_to_cpu(tp->counters->tx_packets);
-+      mac_stats->SingleCollisionFrames =
-+              le32_to_cpu(tp->counters->tx_one_collision);
-+      mac_stats->MultipleCollisionFrames =
-+              le32_to_cpu(tp->counters->tx_multi_collision);
-+      mac_stats->FramesReceivedOK =
-+              le64_to_cpu(tp->counters->rx_packets);
-+      mac_stats->AlignmentErrors =
-+              le16_to_cpu(tp->counters->align_errors);
-+      mac_stats->FramesLostDueToIntMACXmitError =
-+              le64_to_cpu(tp->counters->tx_errors);
-+      mac_stats->BroadcastFramesReceivedOK =
-+              le64_to_cpu(tp->counters->rx_broadcast);
-+      mac_stats->MulticastFramesReceivedOK =
-+              le32_to_cpu(tp->counters->rx_multicast);
-+
-+      if (!rtl_is_8125(tp))
-+              return;
-+
-+      mac_stats->AlignmentErrors =
-+              le32_to_cpu(tp->counters->align_errors32);
-+      mac_stats->OctetsTransmittedOK =
-+              le64_to_cpu(tp->counters->tx_octets);
-+      mac_stats->LateCollisions =
-+              le32_to_cpu(tp->counters->tx_late_collision);
-+      mac_stats->FramesAbortedDueToXSColls =
-+              le32_to_cpu(tp->counters->tx_aborted32);
-+      mac_stats->OctetsReceivedOK =
-+              le64_to_cpu(tp->counters->rx_octets);
-+      mac_stats->FramesLostDueToIntMACRcvError =
-+              le32_to_cpu(tp->counters->rx_mac_error);
-+      mac_stats->MulticastFramesXmittedOK =
-+              le64_to_cpu(tp->counters->tx_multicast64);
-+      mac_stats->BroadcastFramesXmittedOK =
-+              le64_to_cpu(tp->counters->tx_broadcast64);
-+      mac_stats->MulticastFramesReceivedOK =
-+              le64_to_cpu(tp->counters->rx_multicast64);
-+       mac_stats->FrameTooLongErrors =
-+              le32_to_cpu(tp->counters->rx_frame_too_long);
-+}
-+
-+static void rtl8169_get_eth_ctrl_stats(struct net_device *dev,
-+                                     struct ethtool_eth_ctrl_stats *ctrl_stats)
-+{
-+      struct rtl8169_private *tp = netdev_priv(dev);
-+
-+      if (!rtl_is_8125(tp))
-+              return;
-+
-+      rtl8169_update_counters(tp);
-+
-+      ctrl_stats->UnsupportedOpcodesReceived =
-+              le32_to_cpu(tp->counters->rx_unknown_opcode);
-+}
-+
- static const struct ethtool_ops rtl8169_ethtool_ops = {
-       .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
-                                    ETHTOOL_COALESCE_MAX_FRAMES,
-@@ -2207,8 +2283,11 @@ static const struct ethtool_ops rtl8169_
-       .get_link_ksettings     = phy_ethtool_get_link_ksettings,
-       .set_link_ksettings     = phy_ethtool_set_link_ksettings,
-       .get_ringparam          = rtl8169_get_ringparam,
-+      .get_pause_stats        = rtl8169_get_pause_stats,
-       .get_pauseparam         = rtl8169_get_pauseparam,
-       .set_pauseparam         = rtl8169_set_pauseparam,
-+      .get_eth_mac_stats      = rtl8169_get_eth_mac_stats,
-+      .get_eth_ctrl_stats     = rtl8169_get_eth_ctrl_stats,
- };
- static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
-@@ -3926,6 +4005,9 @@ static void rtl_hw_start_8125(struct rtl
-               break;
-       }
-+      /* enable extended tally counter */
-+      r8168_mac_ocp_modify(tp, 0xea84, 0, BIT(1) | BIT(0));
-+
-       rtl_hw_config(tp);
- }
diff --git a/target/linux/generic/backport-6.18/780-04-v6.13-r8169-don-t-take-RTNL-lock-in-rtl_task.patch b/target/linux/generic/backport-6.18/780-04-v6.13-r8169-don-t-take-RTNL-lock-in-rtl_task.patch
deleted file mode 100644 (file)
index a125ebb..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-From ac48430368c1a4f4e6c2fa92243b4b93fd25bee4 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 16 Oct 2024 22:05:57 +0200
-Subject: [PATCH] r8169: don't take RTNL lock in rtl_task()
-
-There's not really a benefit here in taking the RTNL lock. The task
-handler does exception handling only, so we're in trouble anyway when
-we come here, and there's no need to protect against e.g. a parallel
-ethtool call.
-A benefit of removing the RTNL lock here is that we now can
-synchronously cancel the workqueue from a context holding the RTNL mutex.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
----
- drivers/net/ethernet/realtek/r8169_main.c | 8 ++------
- 1 file changed, 2 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -4833,10 +4833,8 @@ static void rtl_task(struct work_struct
-               container_of(work, struct rtl8169_private, wk.work);
-       int ret;
--      rtnl_lock();
--
-       if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
--              goto out_unlock;
-+              return;
-       if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
-               /* if chip isn't accessible, reset bus to revive it */
-@@ -4845,7 +4843,7 @@ static void rtl_task(struct work_struct
-                       if (ret < 0) {
-                               netdev_err(tp->dev, "Can't reset secondary PCI bus, detach NIC\n");
-                               netif_device_detach(tp->dev);
--                              goto out_unlock;
-+                              return;
-                       }
-               }
-@@ -4864,8 +4862,6 @@ reset:
-       } else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) {
-               rtl_reset_work(tp);
-       }
--out_unlock:
--      rtnl_unlock();
- }
- static int rtl8169_poll(struct napi_struct *napi, int budget)
diff --git a/target/linux/generic/backport-6.18/780-05-v6.13-replace-custom-flag-with-disable_work-et-al.patch b/target/linux/generic/backport-6.18/780-05-v6.13-replace-custom-flag-with-disable_work-et-al.patch
deleted file mode 100644 (file)
index 49e274a..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-From e2015942e90a021151a5751776f35830ba063be7 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 16 Oct 2024 22:06:53 +0200
-Subject: [PATCH] r8169: replace custom flag with disable_work() et al
-
-So far we use a custom flag to define when a task can be scheduled and
-when not. Let's use the standard mechanism with disable_work() et al
-instead.
-Note that in rtl8169_close() we can remove the call to cancel_work()
-because we now call disable_work_sync() in rtl8169_down() already.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
----
- drivers/net/ethernet/realtek/r8169_main.c | 18 ++++++------------
- 1 file changed, 6 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -619,7 +619,6 @@ struct rtl8169_tc_offsets {
- };
- enum rtl_flag {
--      RTL_FLAG_TASK_ENABLED = 0,
-       RTL_FLAG_TASK_RESET_PENDING,
-       RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE,
-       RTL_FLAG_TASK_TX_TIMEOUT,
-@@ -2505,11 +2504,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(stru
- static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
- {
--      if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
--              return;
--
-       set_bit(flag, tp->wk.flags);
--      schedule_work(&tp->wk.work);
-+      if (!schedule_work(&tp->wk.work))
-+              clear_bit(flag, tp->wk.flags);
- }
- static void rtl8169_init_phy(struct rtl8169_private *tp)
-@@ -4833,9 +4830,6 @@ static void rtl_task(struct work_struct
-               container_of(work, struct rtl8169_private, wk.work);
-       int ret;
--      if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
--              return;
--
-       if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
-               /* if chip isn't accessible, reset bus to revive it */
-               if (RTL_R32(tp, TxConfig) == ~0) {
-@@ -4919,6 +4913,7 @@ static int r8169_phy_connect(struct rtl8
- static void rtl8169_down(struct rtl8169_private *tp)
- {
-+      disable_work_sync(&tp->wk.work);
-       /* Clear all task flags */
-       bitmap_zero(tp->wk.flags, RTL_FLAG_MAX);
-@@ -4947,7 +4942,7 @@ static void rtl8169_up(struct rtl8169_pr
-       phy_resume(tp->phydev);
-       rtl8169_init_phy(tp);
-       napi_enable(&tp->napi);
--      set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
-+      enable_work(&tp->wk.work);
-       rtl_reset_work(tp);
-       phy_start(tp->phydev);
-@@ -4964,8 +4959,6 @@ static int rtl8169_close(struct net_devi
-       rtl8169_down(tp);
-       rtl8169_rx_clear(tp);
--      cancel_work(&tp->wk.work);
--
-       free_irq(tp->irq, tp);
-       phy_disconnect(tp->phydev);
-@@ -5199,7 +5192,7 @@ static void rtl_remove_one(struct pci_de
-       if (pci_dev_run_wake(pdev))
-               pm_runtime_get_noresume(&pdev->dev);
--      cancel_work_sync(&tp->wk.work);
-+      disable_work_sync(&tp->wk.work);
-       if (IS_ENABLED(CONFIG_R8169_LEDS))
-               r8169_remove_leds(tp->leds);
-@@ -5577,6 +5570,7 @@ static int rtl_init_one(struct pci_dev *
-       tp->irq = pci_irq_vector(pdev, 0);
-       INIT_WORK(&tp->wk.work, rtl_task);
-+      disable_work(&tp->wk.work);
-       rtl_init_mac_address(tp);
diff --git a/target/linux/generic/backport-6.18/780-06-v6.13-r8169-avoid-duplicated-messages-if-loading-firmware-.patch b/target/linux/generic/backport-6.18/780-06-v6.13-r8169-avoid-duplicated-messages-if-loading-firmware-.patch
deleted file mode 100644 (file)
index 6430d32..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From 1c105bacb160b5918e917ab811552b7be69fc69c Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 16 Oct 2024 22:29:39 +0200
-Subject: [PATCH] r8169: avoid duplicated messages if loading firmware fails
- and switch to warn level
-
-In case of a problem with firmware loading we inform at the driver level,
-in addition the firmware load code itself issues warnings. Therefore
-switch to firmware_request_nowarn() to avoid duplicated error messages.
-In addition switch to warn level because the firmware is optional and
-typically just fixes compatibility issues.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Message-ID: <d9c5094c-89a6-40e2-b5fe-8df7df4624ef@gmail.com>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
----
- drivers/net/ethernet/realtek/r8169_firmware.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_firmware.c
-+++ b/drivers/net/ethernet/realtek/r8169_firmware.c
-@@ -215,7 +215,7 @@ int rtl_fw_request_firmware(struct rtl_f
- {
-       int rc;
--      rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
-+      rc = firmware_request_nowarn(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
-       if (rc < 0)
-               goto out;
-@@ -227,7 +227,7 @@ int rtl_fw_request_firmware(struct rtl_f
-       return 0;
- out:
--      dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
--              rtl_fw->fw_name, rc);
-+      dev_warn(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
-+               rtl_fw->fw_name, rc);
-       return rc;
- }
diff --git a/target/linux/generic/backport-6.18/780-07-v6.13-r8169-remove-rtl_dash_loop_wait_high-low.patch b/target/linux/generic/backport-6.18/780-07-v6.13-r8169-remove-rtl_dash_loop_wait_high-low.patch
deleted file mode 100644 (file)
index bc8f979..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-From d64113c6bb5ea5a70b7c9c3a6bcadef307638187 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 16 Oct 2024 22:31:10 +0200
-Subject: [PATCH] r8169: remove rtl_dash_loop_wait_high/low
-
-Remove rtl_dash_loop_wait_high/low to simplify the code.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Message-ID: <fb8c490c-2d92-48f5-8bbf-1fc1f2ee1649@gmail.com>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
----
- drivers/net/ethernet/realtek/r8169_main.c | 35 ++++++-----------------
- 1 file changed, 8 insertions(+), 27 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -1348,40 +1348,19 @@ static void rtl8168ep_stop_cmac(struct r
-       RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01);
- }
--static void rtl_dash_loop_wait(struct rtl8169_private *tp,
--                             const struct rtl_cond *c,
--                             unsigned long usecs, int n, bool high)
--{
--      if (!tp->dash_enabled)
--              return;
--      rtl_loop_wait(tp, c, usecs, n, high);
--}
--
--static void rtl_dash_loop_wait_high(struct rtl8169_private *tp,
--                                  const struct rtl_cond *c,
--                                  unsigned long d, int n)
--{
--      rtl_dash_loop_wait(tp, c, d, n, true);
--}
--
--static void rtl_dash_loop_wait_low(struct rtl8169_private *tp,
--                                 const struct rtl_cond *c,
--                                 unsigned long d, int n)
--{
--      rtl_dash_loop_wait(tp, c, d, n, false);
--}
--
- static void rtl8168dp_driver_start(struct rtl8169_private *tp)
- {
-       r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START);
--      rtl_dash_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
-+      if (tp->dash_enabled)
-+              rtl_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
- }
- static void rtl8168ep_driver_start(struct rtl8169_private *tp)
- {
-       r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START);
-       r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
--      rtl_dash_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
-+      if (tp->dash_enabled)
-+              rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
- }
- static void rtl8168_driver_start(struct rtl8169_private *tp)
-@@ -1395,7 +1374,8 @@ static void rtl8168_driver_start(struct
- static void rtl8168dp_driver_stop(struct rtl8169_private *tp)
- {
-       r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP);
--      rtl_dash_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
-+      if (tp->dash_enabled)
-+              rtl_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
- }
- static void rtl8168ep_driver_stop(struct rtl8169_private *tp)
-@@ -1403,7 +1383,8 @@ static void rtl8168ep_driver_stop(struct
-       rtl8168ep_stop_cmac(tp);
-       r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP);
-       r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
--      rtl_dash_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
-+      if (tp->dash_enabled)
-+              rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
- }
- static void rtl8168_driver_stop(struct rtl8169_private *tp)
diff --git a/target/linux/generic/backport-6.18/780-08-v6.13-r8169-enable-EEE-at-2.5G-per-default-on-RTL8125B.patch b/target/linux/generic/backport-6.18/780-08-v6.13-r8169-enable-EEE-at-2.5G-per-default-on-RTL8125B.patch
deleted file mode 100644 (file)
index 4ec06cc..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From c4e64095c00cb2de413cd6b90be047c273bcd491 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 17 Oct 2024 22:27:44 +0200
-Subject: [PATCH] r8169: enable EEE at 2.5G per default on RTL8125B
-
-Register a6d/12 is shadowing register MDIO_AN_EEE_ADV2. So this line
-disables advertisement of EEE at 2.5G. Latest vendor driver r8125
-doesn't do this (any longer?), so this mode seems to be safe.
-EEE saves quite some energy, therefore enable this mode per default.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Message-ID: <95dd5a0c-09ea-4847-94d9-b7aa3063e8ff@gmail.com>
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
----
- drivers/net/ethernet/realtek/r8169_phy_config.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -99,7 +99,6 @@ static void rtl8125a_config_eee_phy(stru
- static void rtl8125b_config_eee_phy(struct phy_device *phydev)
- {
--      phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000);
-       phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
-       phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000);
-       phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
diff --git a/target/linux/generic/backport-6.18/780-10-v6.13-r8169-fix-inconsistent-indenting-in-rtl8169_get_eth_.patch b/target/linux/generic/backport-6.18/780-10-v6.13-r8169-fix-inconsistent-indenting-in-rtl8169_get_eth_.patch
deleted file mode 100644 (file)
index 41bab55..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From b8bd8c44a266c9a7dcb907eab10fbb119e3f6494 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 24 Oct 2024 22:48:59 +0200
-Subject: [PATCH] r8169: fix inconsistent indenting in
- rtl8169_get_eth_mac_stats
-
-This fixes an inconsistent indenting introduced with e3fc5139bd8f
-("r8169: implement additional ethtool stats ops").
-
-Reported-by: kernel test robot <lkp@intel.com>
-Closes: https://lore.kernel.org/oe-kbuild-all/202410220413.1gAxIJ4t-lkp@intel.com/
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/20fd6f39-3c1b-4af0-9adc-7d1f49728fad@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -2224,7 +2224,7 @@ static void rtl8169_get_eth_mac_stats(st
-               le64_to_cpu(tp->counters->tx_broadcast64);
-       mac_stats->MulticastFramesReceivedOK =
-               le64_to_cpu(tp->counters->rx_multicast64);
--       mac_stats->FrameTooLongErrors =
-+      mac_stats->FrameTooLongErrors =
-               le32_to_cpu(tp->counters->rx_frame_too_long);
- }
diff --git a/target/linux/generic/backport-6.18/780-11-v6.13-r8169-align-RTL8125-EEE-config-with-vendor-driver.patch b/target/linux/generic/backport-6.18/780-11-v6.13-r8169-align-RTL8125-EEE-config-with-vendor-driver.patch
deleted file mode 100644 (file)
index de2be01..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-From eb90f876b7961d702d7fc549e14614860f531e60 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 31 Oct 2024 22:42:52 +0100
-Subject: [PATCH] r8169: align RTL8125 EEE config with vendor driver
-
-Align the EEE config for RTL8125A/RTL8125B with vendor driver r8125.
-This should help to avoid compatibility issues.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/044c925e-8669-4b98-87df-95b4056f4f5f@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../net/ethernet/realtek/r8169_phy_config.c    | 18 ++++++++++++------
- 1 file changed, 12 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -89,19 +89,25 @@ static void rtl8168h_config_eee_phy(stru
-       phy_modify_paged(phydev, 0xa42, 0x14, 0x0000, 0x0080);
- }
--static void rtl8125a_config_eee_phy(struct phy_device *phydev)
-+static void rtl8125_common_config_eee_phy(struct phy_device *phydev)
- {
--      rtl8168h_config_eee_phy(phydev);
-+      phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
-+      phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000);
-+      phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
-+}
-+static void rtl8125a_config_eee_phy(struct phy_device *phydev)
-+{
-+      rtl8168g_config_eee_phy(phydev);
-+      /* disable EEE at 2.5Gbps */
-       phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000);
--      phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
-+      rtl8125_common_config_eee_phy(phydev);
- }
- static void rtl8125b_config_eee_phy(struct phy_device *phydev)
- {
--      phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
--      phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000);
--      phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
-+      rtl8168g_config_eee_phy(phydev);
-+      rtl8125_common_config_eee_phy(phydev);
- }
- static void rtl8169s_hw_phy_config(struct rtl8169_private *tp,
diff --git a/target/linux/generic/backport-6.18/780-12-v6.13-r8169-align-RTL8125-RTL8126-PHY-config-with-vendor-d.patch b/target/linux/generic/backport-6.18/780-12-v6.13-r8169-align-RTL8125-RTL8126-PHY-config-with-vendor-d.patch
deleted file mode 100644 (file)
index a546c42..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From 4af2f60bf7378bd5c92b15a528d8c6c7d02bed6c Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 31 Oct 2024 22:43:45 +0100
-Subject: [PATCH] r8169: align RTL8125/RTL8126 PHY config with vendor driver
-
-This aligns some parameters with vendor driver r8125/r8126 to avoid
-compatibility issues. Note that for RTL8125B there's no functional
-change, just the open-coded version of the function is replaced.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/a8a9d896-fbe6-41f2-bf87-666567d3cdb3@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_phy_config.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1073,8 +1073,8 @@ static void rtl8125b_hw_phy_config(struc
-                                  struct phy_device *phydev)
- {
-       r8169_apply_firmware(tp);
-+      rtl8168g_enable_gphy_10m(phydev);
--      phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800);
-       phy_modify_paged(phydev, 0xac4, 0x13, 0x00f0, 0x0090);
-       phy_modify_paged(phydev, 0xad3, 0x10, 0x0003, 0x0001);
-@@ -1113,6 +1113,7 @@ static void rtl8125d_hw_phy_config(struc
-                                  struct phy_device *phydev)
- {
-       r8169_apply_firmware(tp);
-+      rtl8168g_enable_gphy_10m(phydev);
-       rtl8125_legacy_force_mode(phydev);
-       rtl8168g_disable_aldps(phydev);
-       rtl8125b_config_eee_phy(phydev);
-@@ -1122,6 +1123,9 @@ static void rtl8126a_hw_phy_config(struc
-                                  struct phy_device *phydev)
- {
-       r8169_apply_firmware(tp);
-+      rtl8168g_enable_gphy_10m(phydev);
-+      rtl8125_legacy_force_mode(phydev);
-+      rtl8168g_disable_aldps(phydev);
- }
- void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
diff --git a/target/linux/generic/backport-6.18/780-13-v6.13-r8169-align-RTL8126-EEE-config-with-vendor-driver.patch b/target/linux/generic/backport-6.18/780-13-v6.13-r8169-align-RTL8126-EEE-config-with-vendor-driver.patch
deleted file mode 100644 (file)
index 36c8041..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From a3d8520e6a19ab018da6c7fc22512c913697a829 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 31 Oct 2024 22:44:36 +0100
-Subject: [PATCH] r8169: align RTL8126 EEE config with vendor driver
-
-Align the EEE config for RTL8126A with vendor driver r8126 to avoid
-compatibility issues.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/71e4859e-4cd0-4b6b-b7fa-621d7721992f@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_phy_config.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1126,6 +1126,7 @@ static void rtl8126a_hw_phy_config(struc
-       rtl8168g_enable_gphy_10m(phydev);
-       rtl8125_legacy_force_mode(phydev);
-       rtl8168g_disable_aldps(phydev);
-+      rtl8125_common_config_eee_phy(phydev);
- }
- void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
diff --git a/target/linux/generic/backport-6.18/780-14-v6.13-r8169-improve-initialization-of-RSS-registers-on-RTL.patch b/target/linux/generic/backport-6.18/780-14-v6.13-r8169-improve-initialization-of-RSS-registers-on-RTL.patch
deleted file mode 100644 (file)
index d00b08e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-From 2cd02f2fdd8a92e5b6b85ff64eab0fc549b30c07 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 2 Nov 2024 14:49:01 +0100
-Subject: [PATCH] r8169: improve initialization of RSS registers on
- RTL8125/RTL8126
-
-Replace the register addresses with the names used in r8125/r8126
-vendor driver, and consider that RSS_CTRL_8125 is a 32 bit register.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/3bf2f340-b369-4174-97bf-fd38d4217492@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -346,6 +346,8 @@ enum rtl8125_registers {
-       TxPoll_8125             = 0x90,
-       LEDSEL3                 = 0x96,
-       MAC0_BKP                = 0x19e0,
-+      RSS_CTRL_8125           = 0x4500,
-+      Q_NUM_CTRL_8125         = 0x4800,
-       EEE_TXIDLE_TIMER_8125   = 0x6048,
- };
-@@ -3788,8 +3790,8 @@ static void rtl_hw_start_8125_common(str
-       rtl_pcie_state_l2l3_disable(tp);
-       RTL_W16(tp, 0x382, 0x221b);
--      RTL_W8(tp, 0x4500, 0);
--      RTL_W16(tp, 0x4800, 0);
-+      RTL_W32(tp, RSS_CTRL_8125, 0);
-+      RTL_W16(tp, Q_NUM_CTRL_8125, 0);
-       /* disable UPS */
-       r8168_mac_ocp_modify(tp, 0xd40a, 0x0010, 0x0000);
diff --git a/target/linux/generic/backport-6.18/780-15-v6.13-r8169-remove-leftover-locks-after-reverted-change.patch b/target/linux/generic/backport-6.18/780-15-v6.13-r8169-remove-leftover-locks-after-reverted-change.patch
deleted file mode 100644 (file)
index 19bcf08..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-From 83cb4b470c66b37b19a347a35cea01e0cbdd258d Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 4 Nov 2024 23:16:20 +0100
-Subject: [PATCH] r8169: remove leftover locks after reverted change
-
-After e31a9fedc7d8 ("Revert "r8169: disable ASPM during NAPI poll"")
-these locks aren't needed any longer.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/680f2606-ac7d-4ced-8694-e5033855da9b@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 29 ++---------------------
- 1 file changed, 2 insertions(+), 27 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -661,13 +661,9 @@ struct rtl8169_private {
-               struct work_struct work;
-       } wk;
--      raw_spinlock_t config25_lock;
-       raw_spinlock_t mac_ocp_lock;
-       struct mutex led_lock;  /* serialize LED ctrl RMW access */
--      raw_spinlock_t cfg9346_usage_lock;
--      int cfg9346_usage_count;
--
-       unsigned supports_gmii:1;
-       unsigned aspm_manageable:1;
-       unsigned dash_enabled:1;
-@@ -721,22 +717,12 @@ static inline struct device *tp_to_dev(s
- static void rtl_lock_config_regs(struct rtl8169_private *tp)
- {
--      unsigned long flags;
--
--      raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags);
--      if (!--tp->cfg9346_usage_count)
--              RTL_W8(tp, Cfg9346, Cfg9346_Lock);
--      raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags);
-+      RTL_W8(tp, Cfg9346, Cfg9346_Lock);
- }
- static void rtl_unlock_config_regs(struct rtl8169_private *tp)
- {
--      unsigned long flags;
--
--      raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags);
--      if (!tp->cfg9346_usage_count++)
--              RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
--      raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags);
-+      RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
- }
- static void rtl_pci_commit(struct rtl8169_private *tp)
-@@ -747,24 +733,18 @@ static void rtl_pci_commit(struct rtl816
- static void rtl_mod_config2(struct rtl8169_private *tp, u8 clear, u8 set)
- {
--      unsigned long flags;
-       u8 val;
--      raw_spin_lock_irqsave(&tp->config25_lock, flags);
-       val = RTL_R8(tp, Config2);
-       RTL_W8(tp, Config2, (val & ~clear) | set);
--      raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
- }
- static void rtl_mod_config5(struct rtl8169_private *tp, u8 clear, u8 set)
- {
--      unsigned long flags;
-       u8 val;
--      raw_spin_lock_irqsave(&tp->config25_lock, flags);
-       val = RTL_R8(tp, Config5);
-       RTL_W8(tp, Config5, (val & ~clear) | set);
--      raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
- }
- static bool rtl_is_8125(struct rtl8169_private *tp)
-@@ -1570,7 +1550,6 @@ static void __rtl8169_set_wol(struct rtl
-               { WAKE_MAGIC, Config3, MagicPacket }
-       };
-       unsigned int i, tmp = ARRAY_SIZE(cfg);
--      unsigned long flags;
-       u8 options;
-       rtl_unlock_config_regs(tp);
-@@ -1589,14 +1568,12 @@ static void __rtl8169_set_wol(struct rtl
-                       r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0);
-       }
--      raw_spin_lock_irqsave(&tp->config25_lock, flags);
-       for (i = 0; i < tmp; i++) {
-               options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask;
-               if (wolopts & cfg[i].opt)
-                       options |= cfg[i].mask;
-               RTL_W8(tp, cfg[i].reg, options);
-       }
--      raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
-       switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
-@@ -5477,8 +5454,6 @@ static int rtl_init_one(struct pci_dev *
-       tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
-       tp->ocp_base = OCP_STD_PHY_BASE;
--      raw_spin_lock_init(&tp->cfg9346_usage_lock);
--      raw_spin_lock_init(&tp->config25_lock);
-       raw_spin_lock_init(&tp->mac_ocp_lock);
-       mutex_init(&tp->led_lock);
diff --git a/target/linux/generic/backport-6.18/780-16-v6.13-r8169-improve-__rtl8169_set_wol.patch b/target/linux/generic/backport-6.18/780-16-v6.13-r8169-improve-__rtl8169_set_wol.patch
deleted file mode 100644 (file)
index 3158ac5..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-From c507e96b5763b36b63ad50ad804341f72ea000e4 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 6 Nov 2024 17:55:45 +0100
-Subject: [PATCH] r8169: improve __rtl8169_set_wol
-
-Add helper r8169_mod_reg8_cond() what allows to significantly simplify
-__rtl8169_set_wol().
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/697b197a-8eac-40c6-8847-27093cacec36@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 55 ++++++++++-------------
- 1 file changed, 24 insertions(+), 31 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -747,6 +747,20 @@ static void rtl_mod_config5(struct rtl81
-       RTL_W8(tp, Config5, (val & ~clear) | set);
- }
-+static void r8169_mod_reg8_cond(struct rtl8169_private *tp, int reg,
-+                              u8 bits, bool cond)
-+{
-+      u8 val, old_val;
-+
-+      old_val = RTL_R8(tp, reg);
-+      if (cond)
-+              val = old_val | bits;
-+      else
-+              val = old_val & ~bits;
-+      if (val != old_val)
-+              RTL_W8(tp, reg, val);
-+}
-+
- static bool rtl_is_8125(struct rtl8169_private *tp)
- {
-       return tp->mac_version >= RTL_GIGA_MAC_VER_61;
-@@ -1537,58 +1551,37 @@ static void rtl8169_get_wol(struct net_d
- static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
- {
--      static const struct {
--              u32 opt;
--              u16 reg;
--              u8  mask;
--      } cfg[] = {
--              { WAKE_PHY,   Config3, LinkUp },
--              { WAKE_UCAST, Config5, UWF },
--              { WAKE_BCAST, Config5, BWF },
--              { WAKE_MCAST, Config5, MWF },
--              { WAKE_ANY,   Config5, LanWake },
--              { WAKE_MAGIC, Config3, MagicPacket }
--      };
--      unsigned int i, tmp = ARRAY_SIZE(cfg);
--      u8 options;
--
-       rtl_unlock_config_regs(tp);
-       if (rtl_is_8168evl_up(tp)) {
--              tmp--;
-               if (wolopts & WAKE_MAGIC)
-                       rtl_eri_set_bits(tp, 0x0dc, MagicPacket_v2);
-               else
-                       rtl_eri_clear_bits(tp, 0x0dc, MagicPacket_v2);
-       } else if (rtl_is_8125(tp)) {
--              tmp--;
-               if (wolopts & WAKE_MAGIC)
-                       r8168_mac_ocp_modify(tp, 0xc0b6, 0, BIT(0));
-               else
-                       r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0);
-+      } else {
-+              r8169_mod_reg8_cond(tp, Config3, MagicPacket,
-+                                  wolopts & WAKE_MAGIC);
-       }
--      for (i = 0; i < tmp; i++) {
--              options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask;
--              if (wolopts & cfg[i].opt)
--                      options |= cfg[i].mask;
--              RTL_W8(tp, cfg[i].reg, options);
--      }
-+      r8169_mod_reg8_cond(tp, Config3, LinkUp, wolopts & WAKE_PHY);
-+      r8169_mod_reg8_cond(tp, Config5, UWF, wolopts & WAKE_UCAST);
-+      r8169_mod_reg8_cond(tp, Config5, BWF, wolopts & WAKE_BCAST);
-+      r8169_mod_reg8_cond(tp, Config5, MWF, wolopts & WAKE_MCAST);
-+      r8169_mod_reg8_cond(tp, Config5, LanWake, wolopts);
-       switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
--              options = RTL_R8(tp, Config1) & ~PMEnable;
--              if (wolopts)
--                      options |= PMEnable;
--              RTL_W8(tp, Config1, options);
-+              r8169_mod_reg8_cond(tp, Config1, PMEnable, wolopts);
-               break;
-       case RTL_GIGA_MAC_VER_34:
-       case RTL_GIGA_MAC_VER_37:
-       case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66:
--              if (wolopts)
--                      rtl_mod_config2(tp, 0, PME_SIGNAL);
--              else
--                      rtl_mod_config2(tp, PME_SIGNAL, 0);
-+              r8169_mod_reg8_cond(tp, Config2, PME_SIGNAL, wolopts);
-               break;
-       default:
-               break;
diff --git a/target/linux/generic/backport-6.18/780-17-v6.13-r8169-improve-rtl_set_d3_pll_down.patch b/target/linux/generic/backport-6.18/780-17-v6.13-r8169-improve-rtl_set_d3_pll_down.patch
deleted file mode 100644 (file)
index ede589e..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-From 330dc2297c82953dff402e0b4176a5383a618538 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 6 Nov 2024 17:56:28 +0100
-Subject: [PATCH] r8169: improve rtl_set_d3_pll_down
-
-Make use of new helper r8169_mod_reg8_cond() and move from a switch()
-to an if() clause. Benefit is that we don't have to touch this piece of
-code each time support for a new chip version is added.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/e1ccdb85-a4ed-4800-89c2-89770ff06452@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 18 +++++-------------
- 1 file changed, 5 insertions(+), 13 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -1430,19 +1430,11 @@ static enum rtl_dash_type rtl_get_dash_t
- static void rtl_set_d3_pll_down(struct rtl8169_private *tp, bool enable)
- {
--      switch (tp->mac_version) {
--      case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
--      case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
--      case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
--      case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66:
--              if (enable)
--                      RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
--              else
--                      RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | D3_NO_PLL_DOWN);
--              break;
--      default:
--              break;
--      }
-+      if (tp->mac_version >= RTL_GIGA_MAC_VER_25 &&
-+          tp->mac_version != RTL_GIGA_MAC_VER_28 &&
-+          tp->mac_version != RTL_GIGA_MAC_VER_31 &&
-+          tp->mac_version != RTL_GIGA_MAC_VER_38)
-+              r8169_mod_reg8_cond(tp, PMCH, D3_NO_PLL_DOWN, !enable);
- }
- static void rtl_reset_packet_filter(struct rtl8169_private *tp)
diff --git a/target/linux/generic/backport-6.18/780-18-v6.13-r8169-align-WAKE_PHY-handling-with-r8125-r8126-vendo.patch b/target/linux/generic/backport-6.18/780-18-v6.13-r8169-align-WAKE_PHY-handling-with-r8125-r8126-vendo.patch
deleted file mode 100644 (file)
index ceb8c12..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From e3e9e9039fa6ae885c7d5c954d7b9f105fa23e8f Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 6 Nov 2024 17:57:08 +0100
-Subject: [PATCH] r8169: align WAKE_PHY handling with r8125/r8126 vendor
- drivers
-
-Vendor drivers r8125/r8126 apply this additional magic setting when
-enabling WAKE_PHY, so do the same here.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/51130715-45be-4db5-abb7-05d87e1f5df9@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -1561,6 +1561,9 @@ static void __rtl8169_set_wol(struct rtl
-       }
-       r8169_mod_reg8_cond(tp, Config3, LinkUp, wolopts & WAKE_PHY);
-+      if (rtl_is_8125(tp))
-+              r8168_mac_ocp_modify(tp, 0xe0c6, 0x3f,
-+                                   wolopts & WAKE_PHY ? 0x13 : 0);
-       r8169_mod_reg8_cond(tp, Config5, UWF, wolopts & WAKE_UCAST);
-       r8169_mod_reg8_cond(tp, Config5, BWF, wolopts & WAKE_BCAST);
-       r8169_mod_reg8_cond(tp, Config5, MWF, wolopts & WAKE_MCAST);
diff --git a/target/linux/generic/backport-6.18/780-19-v6.13-r8169-use-helper-r8169_mod_reg8_cond-to-simplify-rtl.patch b/target/linux/generic/backport-6.18/780-19-v6.13-r8169-use-helper-r8169_mod_reg8_cond-to-simplify-rtl.patch
deleted file mode 100644 (file)
index d6332df..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-From 7a3bcd39ae1f0e3ab896d9df62339ab4297a0bfd Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 9 Nov 2024 23:12:12 +0100
-Subject: [PATCH] r8169: use helper r8169_mod_reg8_cond to simplify
- rtl_jumbo_config
-
-Use recently added helper r8169_mod_reg8_cond() to simplify jumbo
-mode configuration.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/3df1d484-a02e-46e7-8f75-db5b428e422e@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 77 ++++-------------------
- 1 file changed, 11 insertions(+), 66 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -2542,86 +2542,31 @@ static void rtl8169_init_ring_indexes(st
-       tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0;
- }
--static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp)
--{
--      RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
--      RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1);
--}
--
--static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp)
--{
--      RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
--      RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1);
--}
--
--static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp)
--{
--      RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
--}
--
--static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp)
--{
--      RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
--}
--
--static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp)
--{
--      RTL_W8(tp, MaxTxPacketSize, 0x24);
--      RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
--      RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01);
--}
--
--static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
--{
--      RTL_W8(tp, MaxTxPacketSize, 0x3f);
--      RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
--      RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01);
--}
--
--static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp)
--{
--      RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0));
--}
--
--static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp)
--{
--      RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0));
--}
--
- static void rtl_jumbo_config(struct rtl8169_private *tp)
- {
-       bool jumbo = tp->dev->mtu > ETH_DATA_LEN;
-       int readrq = 4096;
-+      if (jumbo && tp->mac_version >= RTL_GIGA_MAC_VER_17 &&
-+          tp->mac_version <= RTL_GIGA_MAC_VER_26)
-+              readrq = 512;
-+
-       rtl_unlock_config_regs(tp);
-       switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_17:
--              if (jumbo) {
--                      readrq = 512;
--                      r8168b_1_hw_jumbo_enable(tp);
--              } else {
--                      r8168b_1_hw_jumbo_disable(tp);
--              }
-+              r8169_mod_reg8_cond(tp, Config4, BIT(0), jumbo);
-               break;
-       case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26:
--              if (jumbo) {
--                      readrq = 512;
--                      r8168c_hw_jumbo_enable(tp);
--              } else {
--                      r8168c_hw_jumbo_disable(tp);
--              }
-+              r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo);
-+              r8169_mod_reg8_cond(tp, Config4, Jumbo_En1, jumbo);
-               break;
-       case RTL_GIGA_MAC_VER_28:
--              if (jumbo)
--                      r8168dp_hw_jumbo_enable(tp);
--              else
--                      r8168dp_hw_jumbo_disable(tp);
-+              r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo);
-               break;
-       case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33:
--              if (jumbo)
--                      r8168e_hw_jumbo_enable(tp);
--              else
--                      r8168e_hw_jumbo_disable(tp);
-+              RTL_W8(tp, MaxTxPacketSize, jumbo ? 0x24 : 0x3f);
-+              r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo);
-+              r8169_mod_reg8_cond(tp, Config4, BIT(0), jumbo);
-               break;
-       default:
-               break;
diff --git a/target/linux/generic/backport-6.18/780-20-v6.13-r8169-copy-vendor-driver-2.5G-5G-EEE-advertisement-c.patch b/target/linux/generic/backport-6.18/780-20-v6.13-r8169-copy-vendor-driver-2.5G-5G-EEE-advertisement-c.patch
deleted file mode 100644 (file)
index fee9d95..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-From e340bff27e63ed61a1e9895bed546107859e48a7 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Fri, 8 Nov 2024 08:08:24 +0100
-Subject: [PATCH] r8169: copy vendor driver 2.5G/5G EEE advertisement
- constraints
-
-Vendor driver r8125 doesn't advertise 2.5G EEE on RTL8125A, and r8126
-doesn't advertise 5G EEE. Likely there are compatibility issues,
-therefore do the same in r8169.
-With this change we don't have to disable 2.5G EEE advertisement in
-rtl8125a_config_eee_phy() any longer.
-We use new phylib accessor phy_set_eee_broken() to mark the respective
-EEE modes as broken.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/ce185e10-8a2f-4cf8-a49b-fd8fb3c3c8a1@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c       |  6 ++++++
- drivers/net/ethernet/realtek/r8169_phy_config.c | 16 ++++------------
- 2 files changed, 10 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5253,6 +5253,11 @@ static int r8169_mdio_register(struct rt
-               phy_support_eee(tp->phydev);
-       phy_support_asym_pause(tp->phydev);
-+      /* mimic behavior of r8125/r8126 vendor drivers */
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_61)
-+              tp->phydev->eee_broken_modes |= MDIO_EEE_2_5GT;
-+      tp->phydev->eee_broken_modes |= MDIO_EEE_5GT;
-+
-       /* PHY will be woken up in rtl_open() */
-       phy_suspend(tp->phydev);
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -96,15 +96,7 @@ static void rtl8125_common_config_eee_ph
-       phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
- }
--static void rtl8125a_config_eee_phy(struct phy_device *phydev)
--{
--      rtl8168g_config_eee_phy(phydev);
--      /* disable EEE at 2.5Gbps */
--      phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000);
--      rtl8125_common_config_eee_phy(phydev);
--}
--
--static void rtl8125b_config_eee_phy(struct phy_device *phydev)
-+static void rtl8125_config_eee_phy(struct phy_device *phydev)
- {
-       rtl8168g_config_eee_phy(phydev);
-       rtl8125_common_config_eee_phy(phydev);
-@@ -1066,7 +1058,7 @@ static void rtl8125a_2_hw_phy_config(str
-       rtl8168g_enable_gphy_10m(phydev);
-       rtl8168g_disable_aldps(phydev);
--      rtl8125a_config_eee_phy(phydev);
-+      rtl8125_config_eee_phy(phydev);
- }
- static void rtl8125b_hw_phy_config(struct rtl8169_private *tp,
-@@ -1106,7 +1098,7 @@ static void rtl8125b_hw_phy_config(struc
-       rtl8125_legacy_force_mode(phydev);
-       rtl8168g_disable_aldps(phydev);
--      rtl8125b_config_eee_phy(phydev);
-+      rtl8125_config_eee_phy(phydev);
- }
- static void rtl8125d_hw_phy_config(struct rtl8169_private *tp,
-@@ -1116,7 +1108,7 @@ static void rtl8125d_hw_phy_config(struc
-       rtl8168g_enable_gphy_10m(phydev);
-       rtl8125_legacy_force_mode(phydev);
-       rtl8168g_disable_aldps(phydev);
--      rtl8125b_config_eee_phy(phydev);
-+      rtl8125_config_eee_phy(phydev);
- }
- static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
diff --git a/target/linux/generic/backport-6.18/780-21-v6.14-r8169-remove-unused-flag-RTL_FLAG_TASK_RESET_NO_QUEU.patch b/target/linux/generic/backport-6.18/780-21-v6.14-r8169-remove-unused-flag-RTL_FLAG_TASK_RESET_NO_QUEU.patch
deleted file mode 100644 (file)
index 182858a..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 2e20bf8cc05766dcd0357cdfcada49e1bc45512b Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 2 Dec 2024 21:14:35 +0100
-Subject: [PATCH] r8169: remove unused flag RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE
-
-After 854d71c555dfc3 ("r8169: remove original workaround for RTL8125
-broken rx issue") this flag isn't used any longer. So remove it.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
-Link: https://patch.msgid.link/d9dd214b-3027-4f60-b0e8-6f34a0c76582@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 3 ---
- 1 file changed, 3 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -622,7 +622,6 @@ struct rtl8169_tc_offsets {
- enum rtl_flag {
-       RTL_FLAG_TASK_RESET_PENDING,
--      RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE,
-       RTL_FLAG_TASK_TX_TIMEOUT,
-       RTL_FLAG_MAX
- };
-@@ -4746,8 +4745,6 @@ static void rtl_task(struct work_struct
- reset:
-               rtl_reset_work(tp);
-               netif_wake_queue(tp->dev);
--      } else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) {
--              rtl_reset_work(tp);
-       }
- }
diff --git a/target/linux/generic/backport-6.18/780-22-v6.14-r8169-remove-support-for-chip-version-11.patch b/target/linux/generic/backport-6.18/780-22-v6.14-r8169-remove-support-for-chip-version-11.patch
deleted file mode 100644 (file)
index 055e0f0..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-From bb18265c3aba92b91a1355609769f3e967b65dee Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 2 Dec 2024 21:20:02 +0100
-Subject: [PATCH] r8169: remove support for chip version 11
-
-This is a follow-up to 982300c115d2 ("r8169: remove detection of chip
-version 11 (early RTL8168b)"). Nobody complained yet, so remove
-support for this chip version.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/b689ab6d-20b5-4b64-bd7e-531a0a972ba3@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h            |  2 +-
- drivers/net/ethernet/realtek/r8169_main.c       | 14 +-------------
- drivers/net/ethernet/realtek/r8169_phy_config.c | 10 ----------
- 3 files changed, 2 insertions(+), 24 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -23,7 +23,7 @@ enum mac_version {
-       RTL_GIGA_MAC_VER_08,
-       RTL_GIGA_MAC_VER_09,
-       RTL_GIGA_MAC_VER_10,
--      RTL_GIGA_MAC_VER_11,
-+      /* support for RTL_GIGA_MAC_VER_11 has been removed */
-       /* RTL_GIGA_MAC_VER_12 was handled the same as VER_17 */
-       /* RTL_GIGA_MAC_VER_13 was merged with VER_10 */
-       RTL_GIGA_MAC_VER_14,
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -103,7 +103,6 @@ static const struct {
-       [RTL_GIGA_MAC_VER_08] = {"RTL8102e"                             },
-       [RTL_GIGA_MAC_VER_09] = {"RTL8102e/RTL8103e"                    },
-       [RTL_GIGA_MAC_VER_10] = {"RTL8101e/RTL8100e"                    },
--      [RTL_GIGA_MAC_VER_11] = {"RTL8168b/8111b"                       },
-       [RTL_GIGA_MAC_VER_14] = {"RTL8401"                              },
-       [RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b"                       },
-       [RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp"                     },
-@@ -2334,7 +2333,7 @@ static enum mac_version rtl8169_get_mac_
-               /* 8168B family. */
-               { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 },
--              /* This one is very old and rare, let's see if anybody complains.
-+              /* This one is very old and rare, support has been removed.
-                * { 0x7c8, 0x300,      RTL_GIGA_MAC_VER_11 },
-                */
-@@ -3826,7 +3825,6 @@ static void rtl_hw_config(struct rtl8169
-               [RTL_GIGA_MAC_VER_08] = rtl_hw_start_8102e_3,
-               [RTL_GIGA_MAC_VER_09] = rtl_hw_start_8102e_2,
-               [RTL_GIGA_MAC_VER_10] = NULL,
--              [RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b,
-               [RTL_GIGA_MAC_VER_14] = rtl_hw_start_8401,
-               [RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b,
-               [RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1,
-@@ -4702,12 +4700,6 @@ static irqreturn_t rtl8169_interrupt(int
-       if (status & LinkChg)
-               phy_mac_interrupt(tp->phydev);
--      if (unlikely(status & RxFIFOOver &&
--          tp->mac_version == RTL_GIGA_MAC_VER_11)) {
--              netif_stop_queue(tp->dev);
--              rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
--      }
--
-       rtl_irq_disable(tp);
-       napi_schedule(&tp->napi);
- out:
-@@ -5124,9 +5116,6 @@ static void rtl_set_irq_mask(struct rtl8
-       if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
-               tp->irq_mask |= SYSErr | RxFIFOOver;
--      else if (tp->mac_version == RTL_GIGA_MAC_VER_11)
--              /* special workaround needed */
--              tp->irq_mask |= RxFIFOOver;
- }
- static int rtl_alloc_irq(struct rtl8169_private *tp)
-@@ -5321,7 +5310,6 @@ static int rtl_jumbo_max(struct rtl8169_
-       case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
-               return JUMBO_7K;
-       /* RTL8168b */
--      case RTL_GIGA_MAC_VER_11:
-       case RTL_GIGA_MAC_VER_17:
-               return JUMBO_4K;
-       /* RTL8168c */
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -276,15 +276,6 @@ static void rtl8169sce_hw_phy_config(str
-       rtl_writephy_batch(phydev, phy_reg_init);
- }
--static void rtl8168bb_hw_phy_config(struct rtl8169_private *tp,
--                                  struct phy_device *phydev)
--{
--      phy_write(phydev, 0x1f, 0x0001);
--      phy_set_bits(phydev, 0x16, BIT(0));
--      phy_write(phydev, 0x10, 0xf41b);
--      phy_write(phydev, 0x1f, 0x0000);
--}
--
- static void rtl8168bef_hw_phy_config(struct rtl8169_private *tp,
-                                    struct phy_device *phydev)
- {
-@@ -1136,7 +1127,6 @@ void r8169_hw_phy_config(struct rtl8169_
-               [RTL_GIGA_MAC_VER_08] = rtl8102e_hw_phy_config,
-               [RTL_GIGA_MAC_VER_09] = rtl8102e_hw_phy_config,
-               [RTL_GIGA_MAC_VER_10] = NULL,
--              [RTL_GIGA_MAC_VER_11] = rtl8168bb_hw_phy_config,
-               [RTL_GIGA_MAC_VER_14] = rtl8401_hw_phy_config,
-               [RTL_GIGA_MAC_VER_17] = rtl8168bef_hw_phy_config,
-               [RTL_GIGA_MAC_VER_18] = rtl8168cp_1_hw_phy_config,
diff --git a/target/linux/generic/backport-6.18/780-23-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch b/target/linux/generic/backport-6.18/780-23-v6.14-r8169-adjust-version-numbering-for-RTL8126.patch
deleted file mode 100644 (file)
index 7ea47bd..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-From b299ea0069284186b0d3d54aebe87f0d195d457a Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Fri, 13 Dec 2024 20:01:41 +0100
-Subject: [PATCH] r8169: adjust version numbering for RTL8126
-
-Adjust version numbering for RTL8126, so that it doesn't overlap with
-new RTL8125 versions.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/6a354364-20e9-48ad-a198-468264288757@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h          |  4 +-
- drivers/net/ethernet/realtek/r8169_main.c     | 62 +++++++++----------
- .../net/ethernet/realtek/r8169_phy_config.c   |  4 +-
- 3 files changed, 35 insertions(+), 35 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -69,8 +69,8 @@ enum mac_version {
-       RTL_GIGA_MAC_VER_61,
-       RTL_GIGA_MAC_VER_63,
-       RTL_GIGA_MAC_VER_64,
--      RTL_GIGA_MAC_VER_65,
--      RTL_GIGA_MAC_VER_66,
-+      RTL_GIGA_MAC_VER_70,
-+      RTL_GIGA_MAC_VER_71,
-       RTL_GIGA_MAC_NONE
- };
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -139,8 +139,8 @@ static const struct {
-       /* reserve 62 for CFG_METHOD_4 in the vendor driver */
-       [RTL_GIGA_MAC_VER_63] = {"RTL8125B",            FIRMWARE_8125B_2},
-       [RTL_GIGA_MAC_VER_64] = {"RTL8125D",            FIRMWARE_8125D_1},
--      [RTL_GIGA_MAC_VER_65] = {"RTL8126A",            FIRMWARE_8126A_2},
--      [RTL_GIGA_MAC_VER_66] = {"RTL8126A",            FIRMWARE_8126A_3},
-+      [RTL_GIGA_MAC_VER_70] = {"RTL8126A",            FIRMWARE_8126A_2},
-+      [RTL_GIGA_MAC_VER_71] = {"RTL8126A",            FIRMWARE_8126A_3},
- };
- static const struct pci_device_id rtl8169_pci_tbl[] = {
-@@ -1227,7 +1227,7 @@ static void rtl_writephy(struct rtl8169_
-       case RTL_GIGA_MAC_VER_31:
-               r8168dp_2_mdio_write(tp, location, val);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-               r8168g_mdio_write(tp, location, val);
-               break;
-       default:
-@@ -1242,7 +1242,7 @@ static int rtl_readphy(struct rtl8169_pr
-       case RTL_GIGA_MAC_VER_28:
-       case RTL_GIGA_MAC_VER_31:
-               return r8168dp_2_mdio_read(tp, location);
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-               return r8168g_mdio_read(tp, location);
-       default:
-               return r8169_mdio_read(tp, location);
-@@ -1573,7 +1573,7 @@ static void __rtl8169_set_wol(struct rtl
-               break;
-       case RTL_GIGA_MAC_VER_34:
-       case RTL_GIGA_MAC_VER_37:
--      case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_71:
-               r8169_mod_reg8_cond(tp, Config2, PME_SIGNAL, wolopts);
-               break;
-       default:
-@@ -2046,7 +2046,7 @@ static void rtl_set_eee_txidle_timer(str
-               tp->tx_lpi_timer = timer_val;
-               r8168_mac_ocp_write(tp, 0xe048, timer_val);
-               break;
--      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-               tp->tx_lpi_timer = timer_val;
-               RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
-               break;
-@@ -2254,8 +2254,8 @@ static enum mac_version rtl8169_get_mac_
-               enum mac_version ver;
-       } mac_info[] = {
-               /* 8126A family. */
--              { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_66 },
--              { 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
-+              { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71 },
-+              { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70 },
-               /* 8125D family. */
-               { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 },
-@@ -2525,7 +2525,7 @@ static void rtl_init_rxcfg(struct rtl816
-       case RTL_GIGA_MAC_VER_61:
-               RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
-               break;
--      case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71:
-               RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
-                       RX_PAUSE_SLOT_ON);
-               break;
-@@ -2657,7 +2657,7 @@ static void rtl_wait_txrx_fifo_empty(str
-       case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
-               rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
-               break;
--      case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71:
-               RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
-               rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
-               rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
-@@ -2923,7 +2923,7 @@ static void rtl_enable_exit_l1(struct rt
-       case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
-               rtl_eri_set_bits(tp, 0xd4, 0x0c00);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-               r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
-               break;
-       default:
-@@ -2937,7 +2937,7 @@ static void rtl_disable_exit_l1(struct r
-       case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
-               rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-               r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
-               break;
-       default:
-@@ -2963,8 +2963,8 @@ static void rtl_hw_aspm_clkreq_enable(st
-               rtl_mod_config5(tp, 0, ASPM_en);
-               switch (tp->mac_version) {
--              case RTL_GIGA_MAC_VER_65:
--              case RTL_GIGA_MAC_VER_66:
-+              case RTL_GIGA_MAC_VER_70:
-+              case RTL_GIGA_MAC_VER_71:
-                       val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
-                       RTL_W8(tp, INT_CFG0_8125, val8);
-                       break;
-@@ -2975,7 +2975,7 @@ static void rtl_hw_aspm_clkreq_enable(st
-               switch (tp->mac_version) {
-               case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
--              case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
-+              case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-                       /* reset ephy tx/rx disable timer */
-                       r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
-                       /* chip can trigger L1.2 */
-@@ -2987,7 +2987,7 @@ static void rtl_hw_aspm_clkreq_enable(st
-       } else {
-               switch (tp->mac_version) {
-               case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
--              case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
-+              case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-                       r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
-                       break;
-               default:
-@@ -2995,8 +2995,8 @@ static void rtl_hw_aspm_clkreq_enable(st
-               }
-               switch (tp->mac_version) {
--              case RTL_GIGA_MAC_VER_65:
--              case RTL_GIGA_MAC_VER_66:
-+              case RTL_GIGA_MAC_VER_70:
-+              case RTL_GIGA_MAC_VER_71:
-                       val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
-                       RTL_W8(tp, INT_CFG0_8125, val8);
-                       break;
-@@ -3716,12 +3716,12 @@ static void rtl_hw_start_8125_common(str
-       /* disable new tx descriptor format */
-       r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
--          tp->mac_version == RTL_GIGA_MAC_VER_66)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
-+          tp->mac_version == RTL_GIGA_MAC_VER_71)
-               RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
--          tp->mac_version == RTL_GIGA_MAC_VER_66)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
-+          tp->mac_version == RTL_GIGA_MAC_VER_71)
-               r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
-       else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
-               r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
-@@ -3739,8 +3739,8 @@ static void rtl_hw_start_8125_common(str
-       r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0000);
-       r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
-       r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
--          tp->mac_version == RTL_GIGA_MAC_VER_66)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
-+          tp->mac_version == RTL_GIGA_MAC_VER_71)
-               r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
-       else
-               r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
-@@ -3860,8 +3860,8 @@ static void rtl_hw_config(struct rtl8169
-               [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
-               [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
-               [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
--              [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
--              [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8126a,
-+              [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
-+              [RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a,
-       };
-       if (hw_configs[tp->mac_version])
-@@ -3882,8 +3882,8 @@ static void rtl_hw_start_8125(struct rtl
-                       RTL_W32(tp, i, 0);
-               break;
-       case RTL_GIGA_MAC_VER_63:
--      case RTL_GIGA_MAC_VER_65:
--      case RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_70:
-+      case RTL_GIGA_MAC_VER_71:
-               for (i = 0xa00; i < 0xa80; i += 4)
-                       RTL_W32(tp, i, 0);
-               RTL_W16(tp, INT_CFG1_8125, 0x0000);
-@@ -4115,7 +4115,7 @@ static void rtl8169_cleanup(struct rtl81
-               RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
-               rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-               rtl_enable_rxdvgate(tp);
-               fsleep(2000);
-               break;
-@@ -4272,7 +4272,7 @@ static unsigned int rtl_quirk_packet_pad
-       switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_34:
--      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-               padto = max_t(unsigned int, padto, ETH_ZLEN);
-               break;
-       default:
-@@ -5291,7 +5291,7 @@ static void rtl_hw_initialize(struct rtl
-       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
-               rtl_hw_init_8168g(tp);
-               break;
--      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-               rtl_hw_init_8125(tp);
-               break;
-       default:
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1162,8 +1162,8 @@ void r8169_hw_phy_config(struct rtl8169_
-               [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
-               [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
-               [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
--              [RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
--              [RTL_GIGA_MAC_VER_66] = rtl8126a_hw_phy_config,
-+              [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
-+              [RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config,
-       };
-       if (phy_configs[ver])
diff --git a/target/linux/generic/backport-6.18/780-24-v6.14-r8169-add-support-for-RTL8125D-rev.b.patch b/target/linux/generic/backport-6.18/780-24-v6.14-r8169-add-support-for-RTL8125D-rev.b.patch
deleted file mode 100644 (file)
index bbc447f..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-From b3593df26ab19f114d613693fa8a92ab202803d0 Mon Sep 17 00:00:00 2001
-From: ChunHao Lin <hau@realtek.com>
-Date: Fri, 13 Dec 2024 20:02:58 +0100
-Subject: [PATCH] r8169: add support for RTL8125D rev.b
-
-Add support for RTL8125D rev.b. Its XID is 0x689. It is basically
-based on the one with XID 0x688, but with different firmware file.
-
-Signed-off-by: ChunHao Lin <hau@realtek.com>
-[hkallweit1@gmail.com: rebased after adjusted version numbering]
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/75e5e9ec-d01f-43ac-b0f4-e7456baf18d1@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h            | 1 +
- drivers/net/ethernet/realtek/r8169_main.c       | 6 ++++++
- drivers/net/ethernet/realtek/r8169_phy_config.c | 1 +
- 3 files changed, 8 insertions(+)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -69,6 +69,7 @@ enum mac_version {
-       RTL_GIGA_MAC_VER_61,
-       RTL_GIGA_MAC_VER_63,
-       RTL_GIGA_MAC_VER_64,
-+      RTL_GIGA_MAC_VER_65,
-       RTL_GIGA_MAC_VER_70,
-       RTL_GIGA_MAC_VER_71,
-       RTL_GIGA_MAC_NONE
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -56,6 +56,7 @@
- #define FIRMWARE_8125A_3      "rtl_nic/rtl8125a-3.fw"
- #define FIRMWARE_8125B_2      "rtl_nic/rtl8125b-2.fw"
- #define FIRMWARE_8125D_1      "rtl_nic/rtl8125d-1.fw"
-+#define FIRMWARE_8125D_2      "rtl_nic/rtl8125d-2.fw"
- #define FIRMWARE_8126A_2      "rtl_nic/rtl8126a-2.fw"
- #define FIRMWARE_8126A_3      "rtl_nic/rtl8126a-3.fw"
-@@ -139,6 +140,7 @@ static const struct {
-       /* reserve 62 for CFG_METHOD_4 in the vendor driver */
-       [RTL_GIGA_MAC_VER_63] = {"RTL8125B",            FIRMWARE_8125B_2},
-       [RTL_GIGA_MAC_VER_64] = {"RTL8125D",            FIRMWARE_8125D_1},
-+      [RTL_GIGA_MAC_VER_65] = {"RTL8125D",            FIRMWARE_8125D_2},
-       [RTL_GIGA_MAC_VER_70] = {"RTL8126A",            FIRMWARE_8126A_2},
-       [RTL_GIGA_MAC_VER_71] = {"RTL8126A",            FIRMWARE_8126A_3},
- };
-@@ -705,6 +707,7 @@ MODULE_FIRMWARE(FIRMWARE_8107E_2);
- MODULE_FIRMWARE(FIRMWARE_8125A_3);
- MODULE_FIRMWARE(FIRMWARE_8125B_2);
- MODULE_FIRMWARE(FIRMWARE_8125D_1);
-+MODULE_FIRMWARE(FIRMWARE_8125D_2);
- MODULE_FIRMWARE(FIRMWARE_8126A_2);
- MODULE_FIRMWARE(FIRMWARE_8126A_3);
-@@ -2258,6 +2261,7 @@ static enum mac_version rtl8169_get_mac_
-               { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70 },
-               /* 8125D family. */
-+              { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65 },
-               { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 },
-               /* 8125B family. */
-@@ -3860,6 +3864,7 @@ static void rtl_hw_config(struct rtl8169
-               [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
-               [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
-               [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
-+              [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
-               [RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a,
-       };
-@@ -3878,6 +3883,7 @@ static void rtl_hw_start_8125(struct rtl
-       switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_61:
-       case RTL_GIGA_MAC_VER_64:
-+      case RTL_GIGA_MAC_VER_65:
-               for (i = 0xa00; i < 0xb00; i += 4)
-                       RTL_W32(tp, i, 0);
-               break;
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1162,6 +1162,7 @@ void r8169_hw_phy_config(struct rtl8169_
-               [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
-               [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
-               [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
-+              [RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config,
-               [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
-               [RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config,
-       };
diff --git a/target/linux/generic/backport-6.18/780-25-v6.14-r8169-add-support-for-RTL8125BP-rev.b.patch b/target/linux/generic/backport-6.18/780-25-v6.14-r8169-add-support-for-RTL8125BP-rev.b.patch
deleted file mode 100644 (file)
index 7b4f474..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-From b11bff90f2ad52c5c55c822ecd20326619a73898 Mon Sep 17 00:00:00 2001
-From: ChunHao Lin <hau@realtek.com>
-Date: Tue, 7 Jan 2025 14:43:55 +0800
-Subject: [PATCH] r8169: add support for RTL8125BP rev.b
-
-Add support for RTL8125BP rev.b. Its XID is 0x689. This chip supports
-DASH and its dash type is "RTL_DASH_25_BP".
-
-Signed-off-by: ChunHao Lin <hau@realtek.com>
-Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/20250107064355.104711-1-hau@realtek.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/realtek/r8169.h          |  1 +
- drivers/net/ethernet/realtek/r8169_main.c     | 30 +++++++++++++++++++
- .../net/ethernet/realtek/r8169_phy_config.c   | 23 ++++++++++++++
- 3 files changed, 54 insertions(+)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -70,6 +70,7 @@ enum mac_version {
-       RTL_GIGA_MAC_VER_63,
-       RTL_GIGA_MAC_VER_64,
-       RTL_GIGA_MAC_VER_65,
-+      RTL_GIGA_MAC_VER_66,
-       RTL_GIGA_MAC_VER_70,
-       RTL_GIGA_MAC_VER_71,
-       RTL_GIGA_MAC_NONE
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -57,6 +57,7 @@
- #define FIRMWARE_8125B_2      "rtl_nic/rtl8125b-2.fw"
- #define FIRMWARE_8125D_1      "rtl_nic/rtl8125d-1.fw"
- #define FIRMWARE_8125D_2      "rtl_nic/rtl8125d-2.fw"
-+#define FIRMWARE_8125BP_2     "rtl_nic/rtl8125bp-2.fw"
- #define FIRMWARE_8126A_2      "rtl_nic/rtl8126a-2.fw"
- #define FIRMWARE_8126A_3      "rtl_nic/rtl8126a-3.fw"
-@@ -141,6 +142,7 @@ static const struct {
-       [RTL_GIGA_MAC_VER_63] = {"RTL8125B",            FIRMWARE_8125B_2},
-       [RTL_GIGA_MAC_VER_64] = {"RTL8125D",            FIRMWARE_8125D_1},
-       [RTL_GIGA_MAC_VER_65] = {"RTL8125D",            FIRMWARE_8125D_2},
-+      [RTL_GIGA_MAC_VER_66] = {"RTL8125BP",           FIRMWARE_8125BP_2},
-       [RTL_GIGA_MAC_VER_70] = {"RTL8126A",            FIRMWARE_8126A_2},
-       [RTL_GIGA_MAC_VER_71] = {"RTL8126A",            FIRMWARE_8126A_3},
- };
-@@ -631,6 +633,7 @@ enum rtl_dash_type {
-       RTL_DASH_NONE,
-       RTL_DASH_DP,
-       RTL_DASH_EP,
-+      RTL_DASH_25_BP,
- };
- struct rtl8169_private {
-@@ -708,6 +711,7 @@ MODULE_FIRMWARE(FIRMWARE_8125A_3);
- MODULE_FIRMWARE(FIRMWARE_8125B_2);
- MODULE_FIRMWARE(FIRMWARE_8125D_1);
- MODULE_FIRMWARE(FIRMWARE_8125D_2);
-+MODULE_FIRMWARE(FIRMWARE_8125BP_2);
- MODULE_FIRMWARE(FIRMWARE_8126A_2);
- MODULE_FIRMWARE(FIRMWARE_8126A_3);
-@@ -1360,10 +1364,19 @@ static void rtl8168ep_driver_start(struc
-               rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
- }
-+static void rtl8125bp_driver_start(struct rtl8169_private *tp)
-+{
-+      r8168ep_ocp_write(tp, 0x01, 0x14, OOB_CMD_DRIVER_START);
-+      r8168ep_ocp_write(tp, 0x01, 0x18, 0x00);
-+      r8168ep_ocp_write(tp, 0x01, 0x10, 0x01);
-+}
-+
- static void rtl8168_driver_start(struct rtl8169_private *tp)
- {
-       if (tp->dash_type == RTL_DASH_DP)
-               rtl8168dp_driver_start(tp);
-+      else if (tp->dash_type == RTL_DASH_25_BP)
-+              rtl8125bp_driver_start(tp);
-       else
-               rtl8168ep_driver_start(tp);
- }
-@@ -1384,10 +1397,19 @@ static void rtl8168ep_driver_stop(struct
-               rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
- }
-+static void rtl8125bp_driver_stop(struct rtl8169_private *tp)
-+{
-+      r8168ep_ocp_write(tp, 0x01, 0x14, OOB_CMD_DRIVER_STOP);
-+      r8168ep_ocp_write(tp, 0x01, 0x18, 0x00);
-+      r8168ep_ocp_write(tp, 0x01, 0x10, 0x01);
-+}
-+
- static void rtl8168_driver_stop(struct rtl8169_private *tp)
- {
-       if (tp->dash_type == RTL_DASH_DP)
-               rtl8168dp_driver_stop(tp);
-+      else if (tp->dash_type == RTL_DASH_25_BP)
-+              rtl8125bp_driver_stop(tp);
-       else
-               rtl8168ep_driver_stop(tp);
- }
-@@ -1410,6 +1432,7 @@ static bool rtl_dash_is_enabled(struct r
-       case RTL_DASH_DP:
-               return r8168dp_check_dash(tp);
-       case RTL_DASH_EP:
-+      case RTL_DASH_25_BP:
-               return r8168ep_check_dash(tp);
-       default:
-               return false;
-@@ -1424,6 +1447,8 @@ static enum rtl_dash_type rtl_get_dash_t
-               return RTL_DASH_DP;
-       case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
-               return RTL_DASH_EP;
-+      case RTL_GIGA_MAC_VER_66:
-+              return RTL_DASH_25_BP;
-       default:
-               return RTL_DASH_NONE;
-       }
-@@ -2260,6 +2285,9 @@ static enum mac_version rtl8169_get_mac_
-               { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71 },
-               { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70 },
-+              /* 8125BP family. */
-+              { 0x7cf, 0x681, RTL_GIGA_MAC_VER_66 },
-+
-               /* 8125D family. */
-               { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65 },
-               { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 },
-@@ -3865,6 +3893,7 @@ static void rtl_hw_config(struct rtl8169
-               [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
-               [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d,
-+              [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
-               [RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a,
-       };
-@@ -3884,6 +3913,7 @@ static void rtl_hw_start_8125(struct rtl
-       case RTL_GIGA_MAC_VER_61:
-       case RTL_GIGA_MAC_VER_64:
-       case RTL_GIGA_MAC_VER_65:
-+      case RTL_GIGA_MAC_VER_66:
-               for (i = 0xa00; i < 0xb00; i += 4)
-                       RTL_W32(tp, i, 0);
-               break;
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1102,6 +1102,28 @@ static void rtl8125d_hw_phy_config(struc
-       rtl8125_config_eee_phy(phydev);
- }
-+static void rtl8125bp_hw_phy_config(struct rtl8169_private *tp,
-+                                  struct phy_device *phydev)
-+{
-+      r8169_apply_firmware(tp);
-+      rtl8168g_enable_gphy_10m(phydev);
-+
-+      r8168g_phy_param(phydev, 0x8010, 0x0800, 0x0000);
-+
-+      phy_write(phydev, 0x1f, 0x0b87);
-+      phy_write(phydev, 0x16, 0x8088);
-+      phy_modify(phydev, 0x17, 0xff00, 0x9000);
-+      phy_write(phydev, 0x16, 0x808f);
-+      phy_modify(phydev, 0x17, 0xff00, 0x9000);
-+      phy_write(phydev, 0x1f, 0x0000);
-+
-+      r8168g_phy_param(phydev, 0x8174, 0x2000, 0x1800);
-+
-+      rtl8125_legacy_force_mode(phydev);
-+      rtl8168g_disable_aldps(phydev);
-+      rtl8125_config_eee_phy(phydev);
-+}
-+
- static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
-                                  struct phy_device *phydev)
- {
-@@ -1163,6 +1185,7 @@ void r8169_hw_phy_config(struct rtl8169_
-               [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
-               [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
-               [RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config,
-+              [RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config,
-               [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
-               [RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config,
-       };
diff --git a/target/linux/generic/backport-6.18/780-26-v6.15-r8169-make-Kconfig-option-for-LED-support-user-visib.patch b/target/linux/generic/backport-6.18/780-26-v6.15-r8169-make-Kconfig-option-for-LED-support-user-visib.patch
deleted file mode 100644 (file)
index 62acd26..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From 135c3c86a7cef4ba3d368da15b16c275b74582d3 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 3 Feb 2025 21:35:24 +0100
-Subject: [PATCH] r8169: make Kconfig option for LED support user-visible
-
-Make config option R8169_LEDS user-visible, so that users can remove
-support if not needed.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/d29f0cdb-32bf-435f-b59d-dc96bca1e3ab@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/Kconfig | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/realtek/Kconfig
-+++ b/drivers/net/ethernet/realtek/Kconfig
-@@ -114,7 +114,8 @@ config R8169
-         will be called r8169.  This is recommended.
- config R8169_LEDS
--      def_bool R8169 && LEDS_TRIGGER_NETDEV
-+      bool "Support for controlling the NIC LEDs"
-+      depends on R8169 && LEDS_TRIGGER_NETDEV
-       depends on !(R8169=y && LEDS_CLASS=m)
-       help
-         Optional support for controlling the NIC LED's with the netdev
diff --git a/target/linux/generic/backport-6.18/780-28-v6.15-r8169-add-support-for-Intel-Killer-E5000.patch b/target/linux/generic/backport-6.18/780-28-v6.15-r8169-add-support-for-Intel-Killer-E5000.patch
deleted file mode 100644 (file)
index d741d19..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From d30460f42675fef5cd4b44ffbc49b545524555e3 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 12 Feb 2025 08:03:56 +0100
-Subject: [PATCH] r8169: add support for Intel Killer E5000
-
-This adds support for the Intel Killer E5000 which seems to be a
-rebranded RTL8126. Copied from r8126 vendor driver.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/9db73e9b-e2e8-45de-97a5-041c5f71d774@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -169,6 +169,7 @@ static const struct pci_device_id rtl816
-       { PCI_VDEVICE(REALTEK,  0x8125) },
-       { PCI_VDEVICE(REALTEK,  0x8126) },
-       { PCI_VDEVICE(REALTEK,  0x3000) },
-+      { PCI_VDEVICE(REALTEK,  0x5000) },
-       {}
- };
diff --git a/target/linux/generic/backport-6.18/780-29-v6.15-r8169-add-PHY-c45-ops-for-MDIO_MMD_VENDOR2-registers.patch b/target/linux/generic/backport-6.18/780-29-v6.15-r8169-add-PHY-c45-ops-for-MDIO_MMD_VENDOR2-registers.patch
deleted file mode 100644 (file)
index 1336ec6..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-From 853e80369cfceb2331bf34f251ba11c6602cc67f Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 13 Feb 2025 20:15:42 +0100
-Subject: [PATCH] r8169: add PHY c45 ops for MDIO_MMD_VENDOR2 registers
-
-The integrated PHYs on chip versions from RTL8168g allow to address
-MDIO_MMD_VEND2 registers. All c22 standard registers are mapped to
-MDIO_MMD_VEND2 registers. So far the paging mechanism is used to
-address PHY registers. Add support for c45 ops to address MDIO_MMD_VEND2
-registers directly, w/o the paging.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/d6f97eaa-0f13-468f-89cb-75a41087bc4a@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 32 +++++++++++++++++++++++
- 1 file changed, 32 insertions(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5225,6 +5225,33 @@ static int r8169_mdio_write_reg(struct m
-       return 0;
- }
-+static int r8169_mdio_read_reg_c45(struct mii_bus *mii_bus, int addr,
-+                                 int devnum, int regnum)
-+{
-+      struct rtl8169_private *tp = mii_bus->priv;
-+
-+      if (addr > 0)
-+              return -ENODEV;
-+
-+      if (devnum == MDIO_MMD_VEND2 && regnum > MDIO_STAT2)
-+              return r8168_phy_ocp_read(tp, regnum);
-+
-+      return 0;
-+}
-+
-+static int r8169_mdio_write_reg_c45(struct mii_bus *mii_bus, int addr,
-+                                  int devnum, int regnum, u16 val)
-+{
-+      struct rtl8169_private *tp = mii_bus->priv;
-+
-+      if (addr > 0 || devnum != MDIO_MMD_VEND2 || regnum <= MDIO_STAT2)
-+              return -ENODEV;
-+
-+      r8168_phy_ocp_write(tp, regnum, val);
-+
-+      return 0;
-+}
-+
- static int r8169_mdio_register(struct rtl8169_private *tp)
- {
-       struct pci_dev *pdev = tp->pci_dev;
-@@ -5255,6 +5282,11 @@ static int r8169_mdio_register(struct rt
-       new_bus->read = r8169_mdio_read_reg;
-       new_bus->write = r8169_mdio_write_reg;
-+      if (tp->mac_version >= RTL_GIGA_MAC_VER_40) {
-+              new_bus->read_c45 = r8169_mdio_read_reg_c45;
-+              new_bus->write_c45 = r8169_mdio_write_reg_c45;
-+      }
-+
-       ret = devm_mdiobus_register(&pdev->dev, new_bus);
-       if (ret)
-               return ret;
diff --git a/target/linux/generic/backport-6.18/780-30-v6.15-r8169-increase-max-jumbo-packet-size-on-RTL8125-RTL8.patch b/target/linux/generic/backport-6.18/780-30-v6.15-r8169-increase-max-jumbo-packet-size-on-RTL8125-RTL8.patch
deleted file mode 100644 (file)
index 852c9a3..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From 473367a5ffe1607a61be481e2feda684eb5faea9 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Fri, 7 Mar 2025 08:29:47 +0100
-Subject: [PATCH] r8169: increase max jumbo packet size on RTL8125/RTL8126
-
-Realtek confirmed that all RTL8125/RTL8126 chip versions support up to
-16K jumbo packets. Reflect this in the driver.
-
-Tested by Rui on RTL8125B with 12K jumbo packets.
-
-Suggested-by: Rui Salvaterra <rsalvaterra@gmail.com>
-Tested-by: Rui Salvaterra <rsalvaterra@gmail.com>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/396762ad-cc65-4e60-b01e-8847db89e98b@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -89,6 +89,7 @@
- #define JUMBO_6K      (6 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
- #define JUMBO_7K      (7 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
- #define JUMBO_9K      (9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
-+#define JUMBO_16K     (SZ_16K - VLAN_ETH_HLEN - ETH_FCS_LEN)
- static const struct {
-       const char *name;
-@@ -5384,6 +5385,9 @@ static int rtl_jumbo_max(struct rtl8169_
-       /* RTL8168c */
-       case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24:
-               return JUMBO_6K;
-+      /* RTL8125/8126 */
-+      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-+              return JUMBO_16K;
-       default:
-               return JUMBO_9K;
-       }
diff --git a/target/linux/generic/backport-6.18/780-31-v6.15-r8169-switch-away-from-deprecated-pcim_iomap_table.patch b/target/linux/generic/backport-6.18/780-31-v6.15-r8169-switch-away-from-deprecated-pcim_iomap_table.patch
deleted file mode 100644 (file)
index 0721247..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 34e5ededf4b8ad4c9e58f0cab8596e26c8fa59a2 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 12 Mar 2025 20:21:42 +0100
-Subject: [PATCH] r8169: switch away from deprecated pcim_iomap_table
-
-Avoid using deprecated pcim_iomap_table by switching to
-pcim_iomap_region.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/a36b4cf3-c792-40fa-8164-5dc9d5f14dd0@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/realtek/r8169_main.c | 9 ++++-----
- 1 file changed, 4 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5471,11 +5471,10 @@ static int rtl_init_one(struct pci_dev *
-       if (region < 0)
-               return dev_err_probe(&pdev->dev, -ENODEV, "no MMIO resource found\n");
--      rc = pcim_iomap_regions(pdev, BIT(region), KBUILD_MODNAME);
--      if (rc < 0)
--              return dev_err_probe(&pdev->dev, rc, "cannot remap MMIO, aborting\n");
--
--      tp->mmio_addr = pcim_iomap_table(pdev)[region];
-+      tp->mmio_addr = pcim_iomap_region(pdev, region, KBUILD_MODNAME);
-+      if (IS_ERR(tp->mmio_addr))
-+              return dev_err_probe(&pdev->dev, PTR_ERR(tp->mmio_addr),
-+                                   "cannot remap MMIO, aborting\n");
-       txconfig = RTL_R32(tp, TxConfig);
-       if (txconfig == ~0U)
diff --git a/target/linux/generic/backport-6.18/780-32-v6.15-r8169-enable-RTL8168H-RTL8168EP-RTL8168FP-ASPM-suppo.patch b/target/linux/generic/backport-6.18/780-32-v6.15-r8169-enable-RTL8168H-RTL8168EP-RTL8168FP-ASPM-suppo.patch
deleted file mode 100644 (file)
index 331d296..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From 3d9b8ac5341269d31e59fd5d58d47266ac78bc32 Mon Sep 17 00:00:00 2001
-From: ChunHao Lin <hau@realtek.com>
-Date: Tue, 18 Mar 2025 16:37:20 +0800
-Subject: [PATCH] r8169: enable RTL8168H/RTL8168EP/RTL8168FP ASPM support
-
-This patch will enable RTL8168H/RTL8168EP/RTL8168FP ASPM support on
-the platforms that have tested with ASPM enabled.
-
-Signed-off-by: ChunHao Lin <hau@realtek.com>
-Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/20250318083721.4127-2-hau@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5422,7 +5422,7 @@ done:
- /* register is set if system vendor successfully tested ASPM 1.2 */
- static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
- {
--      if (tp->mac_version >= RTL_GIGA_MAC_VER_61 &&
-+      if (tp->mac_version >= RTL_GIGA_MAC_VER_46 &&
-           r8168_mac_ocp_read(tp, 0xc0b2) & 0xf)
-               return true;
diff --git a/target/linux/generic/backport-6.18/780-34-v6.16-r8169-add-helper-rtl_csi_mod-for-accessing-extended.patch b/target/linux/generic/backport-6.18/780-34-v6.16-r8169-add-helper-rtl_csi_mod-for-accessing-extended.patch
deleted file mode 100644 (file)
index 383f9eb..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-From 8c40d99e5f43e0545a3f4fea9156313847e2eb79 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 9 Apr 2025 21:05:37 +0200
-Subject: [PATCH] r8169: add helper rtl_csi_mod for accessing extended config
- space
-
-Add a helper for the Realtek-specific mechanism for accessing extended
-config space if native access isn't possible.
-This avoids code duplication.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/b368fd91-57d7-4cb5-9342-98b4d8fe9aea@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 26 ++++++++++++++---------
- 1 file changed, 16 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -2849,10 +2849,23 @@ static u32 rtl_csi_read(struct rtl8169_p
-               RTL_R32(tp, CSIDR) : ~0;
- }
-+static void rtl_csi_mod(struct rtl8169_private *tp, int addr,
-+                      u32 mask, u32 set)
-+{
-+      u32 val;
-+
-+      WARN(addr % 4, "Invalid CSI address %#x\n", addr);
-+
-+      netdev_notice_once(tp->dev,
-+              "No native access to PCI extended config space, falling back to CSI\n");
-+
-+      val = rtl_csi_read(tp, addr);
-+      rtl_csi_write(tp, addr, (val & ~mask) | set);
-+}
-+
- static void rtl_disable_zrxdc_timeout(struct rtl8169_private *tp)
- {
-       struct pci_dev *pdev = tp->pci_dev;
--      u32 csi;
-       int rc;
-       u8 val;
-@@ -2869,16 +2882,12 @@ static void rtl_disable_zrxdc_timeout(st
-               }
-       }
--      netdev_notice_once(tp->dev,
--              "No native access to PCI extended config space, falling back to CSI\n");
--      csi = rtl_csi_read(tp, RTL_GEN3_RELATED_OFF);
--      rtl_csi_write(tp, RTL_GEN3_RELATED_OFF, csi & ~RTL_GEN3_ZRXDC_NONCOMPL);
-+      rtl_csi_mod(tp, RTL_GEN3_RELATED_OFF, RTL_GEN3_ZRXDC_NONCOMPL, 0);
- }
- static void rtl_set_aspm_entry_latency(struct rtl8169_private *tp, u8 val)
- {
-       struct pci_dev *pdev = tp->pci_dev;
--      u32 csi;
-       /* According to Realtek the value at config space address 0x070f
-        * controls the L0s/L1 entrance latency. We try standard ECAM access
-@@ -2890,10 +2899,7 @@ static void rtl_set_aspm_entry_latency(s
-           pci_write_config_byte(pdev, 0x070f, val) == PCIBIOS_SUCCESSFUL)
-               return;
--      netdev_notice_once(tp->dev,
--              "No native access to PCI extended config space, falling back to CSI\n");
--      csi = rtl_csi_read(tp, 0x070c) & 0x00ffffff;
--      rtl_csi_write(tp, 0x070c, csi | val << 24);
-+      rtl_csi_mod(tp, 0x070c, 0xff000000, val << 24);
- }
- static void rtl_set_def_aspm_entry_latency(struct rtl8169_private *tp)
diff --git a/target/linux/generic/backport-6.18/780-35-v6.16-r8169-add-helper-rtl8125_phy_param.patch b/target/linux/generic/backport-6.18/780-35-v6.16-r8169-add-helper-rtl8125_phy_param.patch
deleted file mode 100644 (file)
index 30ebb4b..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-From 0c49baf099ba2147a6ff3bbdc3197c6ddbee5469 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 9 Apr 2025 21:14:47 +0200
-Subject: [PATCH] r8169: add helper rtl8125_phy_param
-
-The integrated PHY's of RTL8125/8126 have an own mechanism to access
-PHY parameters, similar to what r8168g_phy_param does on earlier PHY
-versions. Add helper rtl8125_phy_param to simplify the code.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/847b7356-12d6-441b-ade9-4b6e1539b84a@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../net/ethernet/realtek/r8169_phy_config.c   | 36 +++++++++----------
- 1 file changed, 16 insertions(+), 20 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -50,6 +50,15 @@ static void r8168g_phy_param(struct phy_
-       phy_restore_page(phydev, oldpage, 0);
- }
-+static void rtl8125_phy_param(struct phy_device *phydev, u16 parm,
-+                            u16 mask, u16 val)
-+{
-+      phy_lock_mdio_bus(phydev);
-+      __phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xb87c, parm);
-+      __phy_modify_mmd(phydev, MDIO_MMD_VEND2, 0xb87e, mask, val);
-+      phy_unlock_mdio_bus(phydev);
-+}
-+
- struct phy_reg {
-       u16 reg;
-       u16 val;
-@@ -1004,12 +1013,8 @@ static void rtl8125a_2_hw_phy_config(str
-       phy_write_paged(phydev, 0xac5, 0x16, 0x01ff);
-       phy_modify_paged(phydev, 0xac8, 0x15, 0x00f0, 0x0030);
--      phy_write(phydev, 0x1f, 0x0b87);
--      phy_write(phydev, 0x16, 0x80a2);
--      phy_write(phydev, 0x17, 0x0153);
--      phy_write(phydev, 0x16, 0x809c);
--      phy_write(phydev, 0x17, 0x0153);
--      phy_write(phydev, 0x1f, 0x0000);
-+      rtl8125_phy_param(phydev, 0x80a2, 0xffff, 0x0153);
-+      rtl8125_phy_param(phydev, 0x809c, 0xffff, 0x0153);
-       phy_write(phydev, 0x1f, 0x0a43);
-       phy_write(phydev, 0x13, 0x81B3);
-@@ -1061,14 +1066,9 @@ static void rtl8125b_hw_phy_config(struc
-       phy_modify_paged(phydev, 0xac4, 0x13, 0x00f0, 0x0090);
-       phy_modify_paged(phydev, 0xad3, 0x10, 0x0003, 0x0001);
--      phy_write(phydev, 0x1f, 0x0b87);
--      phy_write(phydev, 0x16, 0x80f5);
--      phy_write(phydev, 0x17, 0x760e);
--      phy_write(phydev, 0x16, 0x8107);
--      phy_write(phydev, 0x17, 0x360e);
--      phy_write(phydev, 0x16, 0x8551);
--      phy_modify(phydev, 0x17, 0xff00, 0x0800);
--      phy_write(phydev, 0x1f, 0x0000);
-+      rtl8125_phy_param(phydev, 0x80f5, 0xffff, 0x760e);
-+      rtl8125_phy_param(phydev, 0x8107, 0xffff, 0x360e);
-+      rtl8125_phy_param(phydev, 0x8551, 0xff00, 0x0800);
-       phy_modify_paged(phydev, 0xbf0, 0x10, 0xe000, 0xa000);
-       phy_modify_paged(phydev, 0xbf4, 0x13, 0x0f00, 0x0300);
-@@ -1110,12 +1110,8 @@ static void rtl8125bp_hw_phy_config(stru
-       r8168g_phy_param(phydev, 0x8010, 0x0800, 0x0000);
--      phy_write(phydev, 0x1f, 0x0b87);
--      phy_write(phydev, 0x16, 0x8088);
--      phy_modify(phydev, 0x17, 0xff00, 0x9000);
--      phy_write(phydev, 0x16, 0x808f);
--      phy_modify(phydev, 0x17, 0xff00, 0x9000);
--      phy_write(phydev, 0x1f, 0x0000);
-+      rtl8125_phy_param(phydev, 0x8088, 0xff00, 0x9000);
-+      rtl8125_phy_param(phydev, 0x808f, 0xff00, 0x9000);
-       r8168g_phy_param(phydev, 0x8174, 0x2000, 0x1800);
diff --git a/target/linux/generic/backport-6.18/780-36-v6.16-r8169-refactor-chip-version-detection.patch b/target/linux/generic/backport-6.18/780-36-v6.16-r8169-refactor-chip-version-detection.patch
deleted file mode 100644 (file)
index ae9cfb8..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-From 2b065c098c37a3ed28df7c3be59dca61b9da8402 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Tue, 15 Apr 2025 21:29:34 +0200
-Subject: [PATCH] r8169: refactor chip version detection
-
-Refactor chip version detection and merge both configuration tables.
-Apart from reducing the code by a third, this paves the way for
-merging chip version handling if only difference is the firmware.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
-Link: https://patch.msgid.link/1fea533a-dd5a-4198-a9e2-895e11083947@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 325 +++++++++-------------
- 1 file changed, 128 insertions(+), 197 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -91,61 +91,114 @@
- #define JUMBO_9K      (9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN)
- #define JUMBO_16K     (SZ_16K - VLAN_ETH_HLEN - ETH_FCS_LEN)
--static const struct {
-+static const struct rtl_chip_info {
-+      u16 mask;
-+      u16 val;
-+      enum mac_version mac_version;
-       const char *name;
-       const char *fw_name;
- } rtl_chip_infos[] = {
--      /* PCI devices. */
--      [RTL_GIGA_MAC_VER_02] = {"RTL8169s"                             },
--      [RTL_GIGA_MAC_VER_03] = {"RTL8110s"                             },
--      [RTL_GIGA_MAC_VER_04] = {"RTL8169sb/8110sb"                     },
--      [RTL_GIGA_MAC_VER_05] = {"RTL8169sc/8110sc"                     },
--      [RTL_GIGA_MAC_VER_06] = {"RTL8169sc/8110sc"                     },
--      /* PCI-E devices. */
--      [RTL_GIGA_MAC_VER_07] = {"RTL8102e"                             },
--      [RTL_GIGA_MAC_VER_08] = {"RTL8102e"                             },
--      [RTL_GIGA_MAC_VER_09] = {"RTL8102e/RTL8103e"                    },
--      [RTL_GIGA_MAC_VER_10] = {"RTL8101e/RTL8100e"                    },
--      [RTL_GIGA_MAC_VER_14] = {"RTL8401"                              },
--      [RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b"                       },
--      [RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp"                     },
--      [RTL_GIGA_MAC_VER_19] = {"RTL8168c/8111c"                       },
--      [RTL_GIGA_MAC_VER_20] = {"RTL8168c/8111c"                       },
--      [RTL_GIGA_MAC_VER_21] = {"RTL8168c/8111c"                       },
--      [RTL_GIGA_MAC_VER_22] = {"RTL8168c/8111c"                       },
--      [RTL_GIGA_MAC_VER_23] = {"RTL8168cp/8111cp"                     },
--      [RTL_GIGA_MAC_VER_24] = {"RTL8168cp/8111cp"                     },
--      [RTL_GIGA_MAC_VER_25] = {"RTL8168d/8111d",      FIRMWARE_8168D_1},
--      [RTL_GIGA_MAC_VER_26] = {"RTL8168d/8111d",      FIRMWARE_8168D_2},
--      [RTL_GIGA_MAC_VER_28] = {"RTL8168dp/8111dp"                     },
--      [RTL_GIGA_MAC_VER_29] = {"RTL8105e",            FIRMWARE_8105E_1},
--      [RTL_GIGA_MAC_VER_30] = {"RTL8105e",            FIRMWARE_8105E_1},
--      [RTL_GIGA_MAC_VER_31] = {"RTL8168dp/8111dp"                     },
--      [RTL_GIGA_MAC_VER_32] = {"RTL8168e/8111e",      FIRMWARE_8168E_1},
--      [RTL_GIGA_MAC_VER_33] = {"RTL8168e/8111e",      FIRMWARE_8168E_2},
--      [RTL_GIGA_MAC_VER_34] = {"RTL8168evl/8111evl",  FIRMWARE_8168E_3},
--      [RTL_GIGA_MAC_VER_35] = {"RTL8168f/8111f",      FIRMWARE_8168F_1},
--      [RTL_GIGA_MAC_VER_36] = {"RTL8168f/8111f",      FIRMWARE_8168F_2},
--      [RTL_GIGA_MAC_VER_37] = {"RTL8402",             FIRMWARE_8402_1 },
--      [RTL_GIGA_MAC_VER_38] = {"RTL8411",             FIRMWARE_8411_1 },
--      [RTL_GIGA_MAC_VER_39] = {"RTL8106e",            FIRMWARE_8106E_1},
--      [RTL_GIGA_MAC_VER_40] = {"RTL8168g/8111g",      FIRMWARE_8168G_2},
--      [RTL_GIGA_MAC_VER_42] = {"RTL8168gu/8111gu",    FIRMWARE_8168G_3},
--      [RTL_GIGA_MAC_VER_43] = {"RTL8106eus",          FIRMWARE_8106E_2},
--      [RTL_GIGA_MAC_VER_44] = {"RTL8411b",            FIRMWARE_8411_2 },
--      [RTL_GIGA_MAC_VER_46] = {"RTL8168h/8111h",      FIRMWARE_8168H_2},
--      [RTL_GIGA_MAC_VER_48] = {"RTL8107e",            FIRMWARE_8107E_2},
--      [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep"                     },
--      [RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117",  FIRMWARE_8168FP_3},
--      [RTL_GIGA_MAC_VER_53] = {"RTL8168fp/RTL8117",                   },
--      [RTL_GIGA_MAC_VER_61] = {"RTL8125A",            FIRMWARE_8125A_3},
--      /* reserve 62 for CFG_METHOD_4 in the vendor driver */
--      [RTL_GIGA_MAC_VER_63] = {"RTL8125B",            FIRMWARE_8125B_2},
--      [RTL_GIGA_MAC_VER_64] = {"RTL8125D",            FIRMWARE_8125D_1},
--      [RTL_GIGA_MAC_VER_65] = {"RTL8125D",            FIRMWARE_8125D_2},
--      [RTL_GIGA_MAC_VER_66] = {"RTL8125BP",           FIRMWARE_8125BP_2},
--      [RTL_GIGA_MAC_VER_70] = {"RTL8126A",            FIRMWARE_8126A_2},
--      [RTL_GIGA_MAC_VER_71] = {"RTL8126A",            FIRMWARE_8126A_3},
-+      /* 8126A family. */
-+      { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71, "RTL8126A", FIRMWARE_8126A_3 },
-+      { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_2 },
-+
-+      /* 8125BP family. */
-+      { 0x7cf, 0x681, RTL_GIGA_MAC_VER_66, "RTL8125BP", FIRMWARE_8125BP_2 },
-+
-+      /* 8125D family. */
-+      { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65, "RTL8125D", FIRMWARE_8125D_2 },
-+      { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64, "RTL8125D", FIRMWARE_8125D_1 },
-+
-+      /* 8125B family. */
-+      { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63, "RTL8125B", FIRMWARE_8125B_2 },
-+
-+      /* 8125A family. */
-+      { 0x7cf, 0x609, RTL_GIGA_MAC_VER_61, "RTL8125A", FIRMWARE_8125A_3 },
-+
-+      /* RTL8117 */
-+      { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_53, "RTL8168fp/RTL8117" },
-+      { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52, "RTL8168fp/RTL8117",
-+        FIRMWARE_8168FP_3 },
-+
-+      /* 8168EP family. */
-+      { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51, "RTL8168ep/8111ep" },
-+
-+      /* 8168H family. */
-+      { 0x7cf, 0x541, RTL_GIGA_MAC_VER_46, "RTL8168h/8111h",
-+        FIRMWARE_8168H_2 },
-+      /* Realtek calls it RTL8168M, but it's handled like RTL8168H */
-+      { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46, "RTL8168M", FIRMWARE_8168H_2 },
-+
-+      /* 8168G family. */
-+      { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44, "RTL8411b", FIRMWARE_8411_2 },
-+      { 0x7cf, 0x509, RTL_GIGA_MAC_VER_42, "RTL8168gu/8111gu",
-+        FIRMWARE_8168G_3 },
-+      { 0x7cf, 0x4c0, RTL_GIGA_MAC_VER_40, "RTL8168g/8111g",
-+        FIRMWARE_8168G_2 },
-+
-+      /* 8168F family. */
-+      { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38, "RTL8411", FIRMWARE_8411_1 },
-+      { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36, "RTL8168f/8111f",
-+        FIRMWARE_8168F_2 },
-+      { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35, "RTL8168f/8111f",
-+        FIRMWARE_8168F_1 },
-+
-+      /* 8168E family. */
-+      { 0x7c8, 0x2c8, RTL_GIGA_MAC_VER_34, "RTL8168evl/8111evl",
-+        FIRMWARE_8168E_3 },
-+      { 0x7cf, 0x2c1, RTL_GIGA_MAC_VER_32, "RTL8168e/8111e",
-+        FIRMWARE_8168E_1 },
-+      { 0x7c8, 0x2c0, RTL_GIGA_MAC_VER_33, "RTL8168e/8111e",
-+        FIRMWARE_8168E_2 },
-+
-+      /* 8168D family. */
-+      { 0x7cf, 0x281, RTL_GIGA_MAC_VER_25, "RTL8168d/8111d",
-+        FIRMWARE_8168D_1 },
-+      { 0x7c8, 0x280, RTL_GIGA_MAC_VER_26, "RTL8168d/8111d",
-+        FIRMWARE_8168D_2 },
-+
-+      /* 8168DP family. */
-+      { 0x7cf, 0x28a, RTL_GIGA_MAC_VER_28, "RTL8168dp/8111dp" },
-+      { 0x7cf, 0x28b, RTL_GIGA_MAC_VER_31, "RTL8168dp/8111dp" },
-+
-+      /* 8168C family. */
-+      { 0x7cf, 0x3c9, RTL_GIGA_MAC_VER_23, "RTL8168cp/8111cp" },
-+      { 0x7cf, 0x3c8, RTL_GIGA_MAC_VER_18, "RTL8168cp/8111cp" },
-+      { 0x7c8, 0x3c8, RTL_GIGA_MAC_VER_24, "RTL8168cp/8111cp" },
-+      { 0x7cf, 0x3c0, RTL_GIGA_MAC_VER_19, "RTL8168c/8111c" },
-+      { 0x7cf, 0x3c2, RTL_GIGA_MAC_VER_20, "RTL8168c/8111c" },
-+      { 0x7cf, 0x3c3, RTL_GIGA_MAC_VER_21, "RTL8168c/8111c" },
-+      { 0x7c8, 0x3c0, RTL_GIGA_MAC_VER_22, "RTL8168c/8111c" },
-+
-+      /* 8168B family. */
-+      { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17, "RTL8168b/8111b" },
-+      /* This one is very old and rare, support has been removed.
-+       * { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11, "RTL8168b/8111b" },
-+       */
-+
-+      /* 8101 family. */
-+      { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39, "RTL8106e", FIRMWARE_8106E_1 },
-+      { 0x7c8, 0x440, RTL_GIGA_MAC_VER_37, "RTL8402", FIRMWARE_8402_1 },
-+      { 0x7cf, 0x409, RTL_GIGA_MAC_VER_29, "RTL8105e", FIRMWARE_8105E_1 },
-+      { 0x7c8, 0x408, RTL_GIGA_MAC_VER_30, "RTL8105e", FIRMWARE_8105E_1 },
-+      { 0x7cf, 0x349, RTL_GIGA_MAC_VER_08, "RTL8102e" },
-+      { 0x7cf, 0x249, RTL_GIGA_MAC_VER_08, "RTL8102e" },
-+      { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07, "RTL8102e" },
-+      { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07, "RTL8102e" },
-+      { 0x7cf, 0x240, RTL_GIGA_MAC_VER_14, "RTL8401" },
-+      { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09, "RTL8102e/RTL8103e" },
-+      { 0x7c8, 0x248, RTL_GIGA_MAC_VER_09, "RTL8102e/RTL8103e" },
-+      { 0x7c8, 0x340, RTL_GIGA_MAC_VER_10, "RTL8101e/RTL8100e" },
-+
-+      /* 8110 family. */
-+      { 0xfc8, 0x980, RTL_GIGA_MAC_VER_06, "RTL8169sc/8110sc" },
-+      { 0xfc8, 0x180, RTL_GIGA_MAC_VER_05, "RTL8169sc/8110sc" },
-+      { 0xfc8, 0x100, RTL_GIGA_MAC_VER_04, "RTL8169sb/8110sb" },
-+      { 0xfc8, 0x040, RTL_GIGA_MAC_VER_03, "RTL8110s" },
-+      { 0xfc8, 0x008, RTL_GIGA_MAC_VER_02, "RTL8169s" },
-+
-+      /* Catch-all */
-+      { 0x000, 0x000, RTL_GIGA_MAC_NONE }
- };
- static const struct pci_device_id rtl8169_pci_tbl[] = {
-@@ -2265,151 +2318,30 @@ static const struct ethtool_ops rtl8169_
-       .get_eth_ctrl_stats     = rtl8169_get_eth_ctrl_stats,
- };
--static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
-+static const struct rtl_chip_info *rtl8169_get_chip_version(u16 xid, bool gmii)
- {
--      /*
--       * The driver currently handles the 8168Bf and the 8168Be identically
--       * but they can be identified more specifically through the test below
--       * if needed:
--       *
--       * (RTL_R32(tp, TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
--       *
--       * Same thing for the 8101Eb and the 8101Ec:
--       *
--       * (RTL_R32(tp, TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
--       */
--      static const struct rtl_mac_info {
--              u16 mask;
--              u16 val;
--              enum mac_version ver;
--      } mac_info[] = {
--              /* 8126A family. */
--              { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71 },
--              { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70 },
--
--              /* 8125BP family. */
--              { 0x7cf, 0x681, RTL_GIGA_MAC_VER_66 },
--
--              /* 8125D family. */
--              { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65 },
--              { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 },
--
--              /* 8125B family. */
--              { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
--
--              /* 8125A family. */
--              { 0x7cf, 0x609, RTL_GIGA_MAC_VER_61 },
--              /* It seems only XID 609 made it to the mass market.
--               * { 0x7cf, 0x608,      RTL_GIGA_MAC_VER_60 },
--               * { 0x7c8, 0x608,      RTL_GIGA_MAC_VER_61 },
--               */
--
--              /* RTL8117 */
--              { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_53 },
--              { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52 },
--
--              /* 8168EP family. */
--              { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51 },
--              /* It seems this chip version never made it to
--               * the wild. Let's disable detection.
--               * { 0x7cf, 0x501,      RTL_GIGA_MAC_VER_50 },
--               * { 0x7cf, 0x500,      RTL_GIGA_MAC_VER_49 },
--               */
--
--              /* 8168H family. */
--              { 0x7cf, 0x541, RTL_GIGA_MAC_VER_46 },
--              /* It seems this chip version never made it to
--               * the wild. Let's disable detection.
--               * { 0x7cf, 0x540,      RTL_GIGA_MAC_VER_45 },
--               */
--              /* Realtek calls it RTL8168M, but it's handled like RTL8168H */
--              { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46 },
--
--              /* 8168G family. */
--              { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 },
--              { 0x7cf, 0x509, RTL_GIGA_MAC_VER_42 },
--              /* It seems this chip version never made it to
--               * the wild. Let's disable detection.
--               * { 0x7cf, 0x4c1,      RTL_GIGA_MAC_VER_41 },
--               */
--              { 0x7cf, 0x4c0, RTL_GIGA_MAC_VER_40 },
--
--              /* 8168F family. */
--              { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38 },
--              { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36 },
--              { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35 },
--
--              /* 8168E family. */
--              { 0x7c8, 0x2c8, RTL_GIGA_MAC_VER_34 },
--              { 0x7cf, 0x2c1, RTL_GIGA_MAC_VER_32 },
--              { 0x7c8, 0x2c0, RTL_GIGA_MAC_VER_33 },
--
--              /* 8168D family. */
--              { 0x7cf, 0x281, RTL_GIGA_MAC_VER_25 },
--              { 0x7c8, 0x280, RTL_GIGA_MAC_VER_26 },
--
--              /* 8168DP family. */
--              /* It seems this early RTL8168dp version never made it to
--               * the wild. Support has been removed.
--               * { 0x7cf, 0x288,      RTL_GIGA_MAC_VER_27 },
--               */
--              { 0x7cf, 0x28a, RTL_GIGA_MAC_VER_28 },
--              { 0x7cf, 0x28b, RTL_GIGA_MAC_VER_31 },
--
--              /* 8168C family. */
--              { 0x7cf, 0x3c9, RTL_GIGA_MAC_VER_23 },
--              { 0x7cf, 0x3c8, RTL_GIGA_MAC_VER_18 },
--              { 0x7c8, 0x3c8, RTL_GIGA_MAC_VER_24 },
--              { 0x7cf, 0x3c0, RTL_GIGA_MAC_VER_19 },
--              { 0x7cf, 0x3c2, RTL_GIGA_MAC_VER_20 },
--              { 0x7cf, 0x3c3, RTL_GIGA_MAC_VER_21 },
--              { 0x7c8, 0x3c0, RTL_GIGA_MAC_VER_22 },
--
--              /* 8168B family. */
--              { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 },
--              /* This one is very old and rare, support has been removed.
--               * { 0x7c8, 0x300,      RTL_GIGA_MAC_VER_11 },
--               */
--
--              /* 8101 family. */
--              { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 },
--              { 0x7c8, 0x440, RTL_GIGA_MAC_VER_37 },
--              { 0x7cf, 0x409, RTL_GIGA_MAC_VER_29 },
--              { 0x7c8, 0x408, RTL_GIGA_MAC_VER_30 },
--              { 0x7cf, 0x349, RTL_GIGA_MAC_VER_08 },
--              { 0x7cf, 0x249, RTL_GIGA_MAC_VER_08 },
--              { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 },
--              { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 },
--              { 0x7cf, 0x240, RTL_GIGA_MAC_VER_14 },
--              { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 },
--              { 0x7c8, 0x248, RTL_GIGA_MAC_VER_09 },
--              { 0x7c8, 0x340, RTL_GIGA_MAC_VER_10 },
--
--              /* 8110 family. */
--              { 0xfc8, 0x980, RTL_GIGA_MAC_VER_06 },
--              { 0xfc8, 0x180, RTL_GIGA_MAC_VER_05 },
--              { 0xfc8, 0x100, RTL_GIGA_MAC_VER_04 },
--              { 0xfc8, 0x040, RTL_GIGA_MAC_VER_03 },
--              { 0xfc8, 0x008, RTL_GIGA_MAC_VER_02 },
--
--              /* Catch-all */
--              { 0x000, 0x000, RTL_GIGA_MAC_NONE   }
-+      /* Chips combining a 1Gbps MAC with a 100Mbps PHY */
-+      static const struct rtl_chip_info rtl8106eus_info = {
-+              .mac_version = RTL_GIGA_MAC_VER_43,
-+              .name = "RTL8106eus",
-+              .fw_name = FIRMWARE_8106E_2,
-       };
--      const struct rtl_mac_info *p = mac_info;
--      enum mac_version ver;
-+      static const struct rtl_chip_info rtl8107e_info = {
-+              .mac_version = RTL_GIGA_MAC_VER_48,
-+              .name = "RTL8107e",
-+              .fw_name = FIRMWARE_8107E_2,
-+      };
-+      const struct rtl_chip_info *p = rtl_chip_infos;
-       while ((xid & p->mask) != p->val)
-               p++;
--      ver = p->ver;
--      if (ver != RTL_GIGA_MAC_NONE && !gmii) {
--              if (ver == RTL_GIGA_MAC_VER_42)
--                      ver = RTL_GIGA_MAC_VER_43;
--              else if (ver == RTL_GIGA_MAC_VER_46)
--                      ver = RTL_GIGA_MAC_VER_48;
--      }
-+      if (p->mac_version == RTL_GIGA_MAC_VER_42 && !gmii)
-+              return &rtl8106eus_info;
-+      if (p->mac_version == RTL_GIGA_MAC_VER_46 && !gmii)
-+              return &rtl8107e_info;
--      return ver;
-+      return p;
- }
- static void rtl_release_firmware(struct rtl8169_private *tp)
-@@ -5437,9 +5369,9 @@ static bool rtl_aspm_is_safe(struct rtl8
- static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
- {
-+      const struct rtl_chip_info *chip;
-       struct rtl8169_private *tp;
-       int jumbo_max, region, rc;
--      enum mac_version chipset;
-       struct net_device *dev;
-       u32 txconfig;
-       u16 xid;
-@@ -5489,12 +5421,13 @@ static int rtl_init_one(struct pci_dev *
-       xid = (txconfig >> 20) & 0xfcf;
-       /* Identify chip attached to board */
--      chipset = rtl8169_get_mac_version(xid, tp->supports_gmii);
--      if (chipset == RTL_GIGA_MAC_NONE)
-+      chip = rtl8169_get_chip_version(xid, tp->supports_gmii);
-+      if (chip->mac_version == RTL_GIGA_MAC_NONE)
-               return dev_err_probe(&pdev->dev, -ENODEV,
-                                    "unknown chip XID %03x, contact r8169 maintainers (see MAINTAINERS file)\n",
-                                    xid);
--      tp->mac_version = chipset;
-+      tp->mac_version = chip->mac_version;
-+      tp->fw_name = chip->fw_name;
-       /* Disable ASPM L1 as that cause random device stop working
-        * problems as well as full system hangs for some PCIe devices users.
-@@ -5599,8 +5532,6 @@ static int rtl_init_one(struct pci_dev *
-       rtl_set_irq_mask(tp);
--      tp->fw_name = rtl_chip_infos[chipset].fw_name;
--
-       tp->counters = dmam_alloc_coherent (&pdev->dev, sizeof(*tp->counters),
-                                           &tp->counters_phys_addr,
-                                           GFP_KERNEL);
-@@ -5625,7 +5556,7 @@ static int rtl_init_one(struct pci_dev *
-       }
-       netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
--                  rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
-+                  chip->name, dev->dev_addr, xid, tp->irq);
-       if (jumbo_max)
-               netdev_info(dev, "jumbo features [frames: %d bytes, tx checksumming: %s]\n",
diff --git a/target/linux/generic/backport-6.18/780-37-v6.16-r8169-add-RTL_GIGA_MAC_VER_LAST-to-facilitate-adding.patch b/target/linux/generic/backport-6.18/780-37-v6.16-r8169-add-RTL_GIGA_MAC_VER_LAST-to-facilitate-adding.patch
deleted file mode 100644 (file)
index 6dad3f3..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-From fe733618b27a8c033f0d246c2efff56fca322656 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Tue, 15 Apr 2025 21:39:23 +0200
-Subject: [PATCH] r8169: add RTL_GIGA_MAC_VER_LAST to facilitate adding support
- for new chip versions
-
-Add a new mac_version enum value RTL_GIGA_MAC_VER_LAST. Benefit is that
-when adding support for a new chip version we have to touch less code,
-except something changes fundamentally.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/06991f47-2aec-4aa2-8918-2c6e79332303@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h      |  3 ++-
- drivers/net/ethernet/realtek/r8169_main.c | 28 +++++++++++------------
- 2 files changed, 16 insertions(+), 15 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -73,7 +73,8 @@ enum mac_version {
-       RTL_GIGA_MAC_VER_66,
-       RTL_GIGA_MAC_VER_70,
-       RTL_GIGA_MAC_VER_71,
--      RTL_GIGA_MAC_NONE
-+      RTL_GIGA_MAC_NONE,
-+      RTL_GIGA_MAC_VER_LAST = RTL_GIGA_MAC_NONE - 1
- };
- struct rtl8169_private;
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -1289,7 +1289,7 @@ static void rtl_writephy(struct rtl8169_
-       case RTL_GIGA_MAC_VER_31:
-               r8168dp_2_mdio_write(tp, location, val);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST:
-               r8168g_mdio_write(tp, location, val);
-               break;
-       default:
-@@ -1304,7 +1304,7 @@ static int rtl_readphy(struct rtl8169_pr
-       case RTL_GIGA_MAC_VER_28:
-       case RTL_GIGA_MAC_VER_31:
-               return r8168dp_2_mdio_read(tp, location);
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST:
-               return r8168g_mdio_read(tp, location);
-       default:
-               return r8169_mdio_read(tp, location);
-@@ -1656,7 +1656,7 @@ static void __rtl8169_set_wol(struct rtl
-               break;
-       case RTL_GIGA_MAC_VER_34:
-       case RTL_GIGA_MAC_VER_37:
--      case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_LAST:
-               r8169_mod_reg8_cond(tp, Config2, PME_SIGNAL, wolopts);
-               break;
-       default:
-@@ -2129,7 +2129,7 @@ static void rtl_set_eee_txidle_timer(str
-               tp->tx_lpi_timer = timer_val;
-               r8168_mac_ocp_write(tp, 0xe048, timer_val);
-               break;
--      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST:
-               tp->tx_lpi_timer = timer_val;
-               RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
-               break;
-@@ -2491,7 +2491,7 @@ static void rtl_init_rxcfg(struct rtl816
-       case RTL_GIGA_MAC_VER_61:
-               RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
-               break;
--      case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_LAST:
-               RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
-                       RX_PAUSE_SLOT_ON);
-               break;
-@@ -2623,7 +2623,7 @@ static void rtl_wait_txrx_fifo_empty(str
-       case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
-               rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
-               break;
--      case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_LAST:
-               RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
-               rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
-               rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
-@@ -2895,7 +2895,7 @@ static void rtl_enable_exit_l1(struct rt
-       case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
-               rtl_eri_set_bits(tp, 0xd4, 0x0c00);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST:
-               r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
-               break;
-       default:
-@@ -2909,7 +2909,7 @@ static void rtl_disable_exit_l1(struct r
-       case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
-               rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST:
-               r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
-               break;
-       default:
-@@ -2947,7 +2947,7 @@ static void rtl_hw_aspm_clkreq_enable(st
-               switch (tp->mac_version) {
-               case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
--              case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-+              case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST:
-                       /* reset ephy tx/rx disable timer */
-                       r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
-                       /* chip can trigger L1.2 */
-@@ -2959,7 +2959,7 @@ static void rtl_hw_aspm_clkreq_enable(st
-       } else {
-               switch (tp->mac_version) {
-               case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
--              case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-+              case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST:
-                       r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
-                       break;
-               default:
-@@ -4091,7 +4091,7 @@ static void rtl8169_cleanup(struct rtl81
-               RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
-               rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST:
-               rtl_enable_rxdvgate(tp);
-               fsleep(2000);
-               break;
-@@ -4248,7 +4248,7 @@ static unsigned int rtl_quirk_packet_pad
-       switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_34:
--      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST:
-               padto = max_t(unsigned int, padto, ETH_ZLEN);
-               break;
-       default:
-@@ -5299,7 +5299,7 @@ static void rtl_hw_initialize(struct rtl
-       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
-               rtl_hw_init_8168g(tp);
-               break;
--      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST:
-               rtl_hw_init_8125(tp);
-               break;
-       default:
-@@ -5324,7 +5324,7 @@ static int rtl_jumbo_max(struct rtl8169_
-       case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24:
-               return JUMBO_6K;
-       /* RTL8125/8126 */
--      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
-+      case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST:
-               return JUMBO_16K;
-       default:
-               return JUMBO_9K;
diff --git a/target/linux/generic/backport-6.18/780-38-v6.16-r8169-use-pci_prepare_to_sleep-in-rtl_shutdown.patch b/target/linux/generic/backport-6.18/780-38-v6.16-r8169-use-pci_prepare_to_sleep-in-rtl_shutdown.patch
deleted file mode 100644 (file)
index 0f085f0..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From b7ed5d5a78fccee96cf8919ac2c7a064c2f4c45b Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 21 Apr 2025 11:25:18 +0200
-Subject: [PATCH] r8169: use pci_prepare_to_sleep in rtl_shutdown
-
-Use pci_prepare_to_sleep() like PCI core does in pci_pm_suspend_noirq.
-This aligns setting a low-power mode during shutdown with the handling
-of the transition to system suspend. Also the transition to runtime
-suspend uses pci_target_state() instead of setting D3hot unconditionally.
-
-Note: pci_prepare_to_sleep() uses device_may_wakeup() to check whether
-      device may generate wakeup events. So we don't lose anything by
-      not passing tp->saved_wolopts any longer.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
-Link: https://patch.msgid.link/f573fdbd-ba6d-41c1-b68f-311d3c88db2c@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5037,10 +5037,8 @@ static void rtl_shutdown(struct pci_dev
-       /* Restore original MAC address */
-       rtl_rar_set(tp, tp->dev->perm_addr);
--      if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) {
--              pci_wake_from_d3(pdev, tp->saved_wolopts);
--              pci_set_power_state(pdev, PCI_D3hot);
--      }
-+      if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled)
-+              pci_prepare_to_sleep(pdev);
- }
- static void rtl_remove_one(struct pci_dev *pdev)
diff --git a/target/linux/generic/backport-6.18/780-39-v6.16-r8169-merge-chip-versions-70-and-71-RTL8126A.patch b/target/linux/generic/backport-6.18/780-39-v6.16-r8169-merge-chip-versions-70-and-71-RTL8126A.patch
deleted file mode 100644 (file)
index caab6c6..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-From 4dec0702b8627c364a0e1f2c5b249e06709a1c24 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Fri, 18 Apr 2025 11:23:45 +0200
-Subject: [PATCH] r8169: merge chip versions 70 and 71 (RTL8126A)
-
-Handling of both chip versions is the same, only difference is
-the firmware. So we can merge handling of both chip versions.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/97d7ae79-d021-4b6b-b424-89e5e305b029@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h            |  1 -
- drivers/net/ethernet/realtek/r8169_main.c       | 15 ++++-----------
- drivers/net/ethernet/realtek/r8169_phy_config.c |  1 -
- 3 files changed, 4 insertions(+), 13 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -72,7 +72,6 @@ enum mac_version {
-       RTL_GIGA_MAC_VER_65,
-       RTL_GIGA_MAC_VER_66,
-       RTL_GIGA_MAC_VER_70,
--      RTL_GIGA_MAC_VER_71,
-       RTL_GIGA_MAC_NONE,
-       RTL_GIGA_MAC_VER_LAST = RTL_GIGA_MAC_NONE - 1
- };
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -99,7 +99,7 @@ static const struct rtl_chip_info {
-       const char *fw_name;
- } rtl_chip_infos[] = {
-       /* 8126A family. */
--      { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71, "RTL8126A", FIRMWARE_8126A_3 },
-+      { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_3 },
-       { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_2 },
-       /* 8125BP family. */
-@@ -2936,7 +2936,6 @@ static void rtl_hw_aspm_clkreq_enable(st
-               rtl_mod_config5(tp, 0, ASPM_en);
-               switch (tp->mac_version) {
-               case RTL_GIGA_MAC_VER_70:
--              case RTL_GIGA_MAC_VER_71:
-                       val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
-                       RTL_W8(tp, INT_CFG0_8125, val8);
-                       break;
-@@ -2968,7 +2967,6 @@ static void rtl_hw_aspm_clkreq_enable(st
-               switch (tp->mac_version) {
-               case RTL_GIGA_MAC_VER_70:
--              case RTL_GIGA_MAC_VER_71:
-                       val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
-                       RTL_W8(tp, INT_CFG0_8125, val8);
-                       break;
-@@ -3688,12 +3686,10 @@ static void rtl_hw_start_8125_common(str
-       /* disable new tx descriptor format */
-       r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
--          tp->mac_version == RTL_GIGA_MAC_VER_71)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_70)
-               RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
--          tp->mac_version == RTL_GIGA_MAC_VER_71)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_70)
-               r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
-       else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
-               r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
-@@ -3711,8 +3707,7 @@ static void rtl_hw_start_8125_common(str
-       r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0000);
-       r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
-       r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
--          tp->mac_version == RTL_GIGA_MAC_VER_71)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_70)
-               r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
-       else
-               r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
-@@ -3835,7 +3830,6 @@ static void rtl_hw_config(struct rtl8169
-               [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
--              [RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a,
-       };
-       if (hw_configs[tp->mac_version])
-@@ -3859,7 +3853,6 @@ static void rtl_hw_start_8125(struct rtl
-               break;
-       case RTL_GIGA_MAC_VER_63:
-       case RTL_GIGA_MAC_VER_70:
--      case RTL_GIGA_MAC_VER_71:
-               for (i = 0xa00; i < 0xa80; i += 4)
-                       RTL_W32(tp, i, 0);
-               RTL_W16(tp, INT_CFG1_8125, 0x0000);
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1183,7 +1183,6 @@ void r8169_hw_phy_config(struct rtl8169_
-               [RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config,
-               [RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config,
-               [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
--              [RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config,
-       };
-       if (phy_configs[ver])
diff --git a/target/linux/generic/backport-6.18/780-40-v6.16-r8169-merge-chip-versions-64-and-65-RTL8125D.patch b/target/linux/generic/backport-6.18/780-40-v6.16-r8169-merge-chip-versions-64-and-65-RTL8125D.patch
deleted file mode 100644 (file)
index 5110c27..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-From f372ef6ed5a6b0401c884561d4bba1843e54d46a Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Fri, 18 Apr 2025 11:24:30 +0200
-Subject: [PATCH] r8169: merge chip versions 64 and 65 (RTL8125D)
-
-Handling of both chip versions is the same, only difference is
-the firmware. So we can merge handling of both chip versions.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/0baad123-c679-4154-923f-fdc12783e900@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h            | 1 -
- drivers/net/ethernet/realtek/r8169_main.c       | 4 +---
- drivers/net/ethernet/realtek/r8169_phy_config.c | 1 -
- 3 files changed, 1 insertion(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -69,7 +69,6 @@ enum mac_version {
-       RTL_GIGA_MAC_VER_61,
-       RTL_GIGA_MAC_VER_63,
-       RTL_GIGA_MAC_VER_64,
--      RTL_GIGA_MAC_VER_65,
-       RTL_GIGA_MAC_VER_66,
-       RTL_GIGA_MAC_VER_70,
-       RTL_GIGA_MAC_NONE,
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -106,7 +106,7 @@ static const struct rtl_chip_info {
-       { 0x7cf, 0x681, RTL_GIGA_MAC_VER_66, "RTL8125BP", FIRMWARE_8125BP_2 },
-       /* 8125D family. */
--      { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65, "RTL8125D", FIRMWARE_8125D_2 },
-+      { 0x7cf, 0x689, RTL_GIGA_MAC_VER_64, "RTL8125D", FIRMWARE_8125D_2 },
-       { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64, "RTL8125D", FIRMWARE_8125D_1 },
-       /* 8125B family. */
-@@ -3827,7 +3827,6 @@ static void rtl_hw_config(struct rtl8169
-               [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
-               [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
-               [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
--              [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
-       };
-@@ -3846,7 +3845,6 @@ static void rtl_hw_start_8125(struct rtl
-       switch (tp->mac_version) {
-       case RTL_GIGA_MAC_VER_61:
-       case RTL_GIGA_MAC_VER_64:
--      case RTL_GIGA_MAC_VER_65:
-       case RTL_GIGA_MAC_VER_66:
-               for (i = 0xa00; i < 0xb00; i += 4)
-                       RTL_W32(tp, i, 0);
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1180,7 +1180,6 @@ void r8169_hw_phy_config(struct rtl8169_
-               [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
-               [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
-               [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
--              [RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config,
-               [RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config,
-               [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
-       };
diff --git a/target/linux/generic/backport-6.18/780-41-v6.16-r8169-merge-chip-versions-52-and-53-RTL8117.patch b/target/linux/generic/backport-6.18/780-41-v6.16-r8169-merge-chip-versions-52-and-53-RTL8117.patch
deleted file mode 100644 (file)
index b28c28f..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-From 4f51e7d370a04122fa78470b031d6487c52298b1 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Fri, 18 Apr 2025 11:25:17 +0200
-Subject: [PATCH] r8169: merge chip versions 52 and 53 (RTL8117)
-
-Handling of both chip versions is the same, only difference is
-the firmware. So we can merge handling of both chip versions.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/ae866b71-c904-434e-befb-848c831e33ff@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h            |  1 -
- drivers/net/ethernet/realtek/r8169_main.c       | 17 +++++++----------
- drivers/net/ethernet/realtek/r8169_phy_config.c |  1 -
- 3 files changed, 7 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -64,7 +64,6 @@ enum mac_version {
-       /* support for RTL_GIGA_MAC_VER_50 has been removed */
-       RTL_GIGA_MAC_VER_51,
-       RTL_GIGA_MAC_VER_52,
--      RTL_GIGA_MAC_VER_53,
-       /* support for RTL_GIGA_MAC_VER_60 has been removed */
-       RTL_GIGA_MAC_VER_61,
-       RTL_GIGA_MAC_VER_63,
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -116,7 +116,7 @@ static const struct rtl_chip_info {
-       { 0x7cf, 0x609, RTL_GIGA_MAC_VER_61, "RTL8125A", FIRMWARE_8125A_3 },
-       /* RTL8117 */
--      { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_53, "RTL8168fp/RTL8117" },
-+      { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_52, "RTL8168fp/RTL8117" },
-       { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52, "RTL8168fp/RTL8117",
-         FIRMWARE_8168FP_3 },
-@@ -830,7 +830,7 @@ static bool rtl_is_8168evl_up(struct rtl
- {
-       return tp->mac_version >= RTL_GIGA_MAC_VER_34 &&
-              tp->mac_version != RTL_GIGA_MAC_VER_39 &&
--             tp->mac_version <= RTL_GIGA_MAC_VER_53;
-+             tp->mac_version <= RTL_GIGA_MAC_VER_52;
- }
- static bool rtl_supports_eee(struct rtl8169_private *tp)
-@@ -998,9 +998,7 @@ void r8169_get_led_name(struct rtl8169_p
- static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
- {
-       /* based on RTL8168FP_OOBMAC_BASE in vendor driver */
--      if (type == ERIAR_OOB &&
--          (tp->mac_version == RTL_GIGA_MAC_VER_52 ||
--           tp->mac_version == RTL_GIGA_MAC_VER_53))
-+      if (type == ERIAR_OOB && tp->mac_version == RTL_GIGA_MAC_VER_52)
-               *cmd |= 0xf70 << 18;
- }
-@@ -1500,7 +1498,7 @@ static enum rtl_dash_type rtl_get_dash_t
-       case RTL_GIGA_MAC_VER_28:
-       case RTL_GIGA_MAC_VER_31:
-               return RTL_DASH_DP;
--      case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
-+      case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_52:
-               return RTL_DASH_EP;
-       case RTL_GIGA_MAC_VER_66:
-               return RTL_DASH_25_BP;
-@@ -2485,7 +2483,7 @@ static void rtl_init_rxcfg(struct rtl816
-       case RTL_GIGA_MAC_VER_38:
-               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
-               break;
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52:
-               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
-               break;
-       case RTL_GIGA_MAC_VER_61:
-@@ -2616,7 +2614,7 @@ DECLARE_RTL_COND(rtl_rxtx_empty_cond_2)
- static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp)
- {
-       switch (tp->mac_version) {
--      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53:
-+      case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52:
-               rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42);
-               rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
-               break;
-@@ -3823,7 +3821,6 @@ static void rtl_hw_config(struct rtl8169
-               [RTL_GIGA_MAC_VER_48] = rtl_hw_start_8168h_1,
-               [RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3,
-               [RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117,
--              [RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
-               [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
-               [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
-               [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
-@@ -5282,7 +5279,7 @@ static void rtl_hw_init_8125(struct rtl8
- static void rtl_hw_initialize(struct rtl8169_private *tp)
- {
-       switch (tp->mac_version) {
--      case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
-+      case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_52:
-               rtl8168ep_stop_cmac(tp);
-               fallthrough;
-       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1176,7 +1176,6 @@ void r8169_hw_phy_config(struct rtl8169_
-               [RTL_GIGA_MAC_VER_48] = rtl8168h_2_hw_phy_config,
-               [RTL_GIGA_MAC_VER_51] = rtl8168ep_2_hw_phy_config,
-               [RTL_GIGA_MAC_VER_52] = rtl8117_hw_phy_config,
--              [RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config,
-               [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
-               [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
-               [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
diff --git a/target/linux/generic/backport-6.18/780-42-v6.16-r8169-add-support-for-RTL8127A.patch b/target/linux/generic/backport-6.18/780-42-v6.16-r8169-add-support-for-RTL8127A.patch
deleted file mode 100644 (file)
index 45587a3..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-From f24f7b2f3af9e008ded20f804d7829ee2efd43f2 Mon Sep 17 00:00:00 2001
-From: ChunHao Lin <hau@realtek.com>
-Date: Thu, 15 May 2025 17:53:03 +0800
-Subject: [PATCH] r8169: add support for RTL8127A
-
-This adds support for 10Gbs chip RTL8127A.
-
-Signed-off-by: ChunHao Lin <hau@realtek.com>
-Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/20250515095303.3138-1-hau@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h          |   1 +
- drivers/net/ethernet/realtek/r8169_main.c     |  29 ++-
- .../net/ethernet/realtek/r8169_phy_config.c   | 166 ++++++++++++++++++
- 3 files changed, 193 insertions(+), 3 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -70,6 +70,7 @@ enum mac_version {
-       RTL_GIGA_MAC_VER_64,
-       RTL_GIGA_MAC_VER_66,
-       RTL_GIGA_MAC_VER_70,
-+      RTL_GIGA_MAC_VER_80,
-       RTL_GIGA_MAC_NONE,
-       RTL_GIGA_MAC_VER_LAST = RTL_GIGA_MAC_NONE - 1
- };
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -60,6 +60,7 @@
- #define FIRMWARE_8125BP_2     "rtl_nic/rtl8125bp-2.fw"
- #define FIRMWARE_8126A_2      "rtl_nic/rtl8126a-2.fw"
- #define FIRMWARE_8126A_3      "rtl_nic/rtl8126a-3.fw"
-+#define FIRMWARE_8127A_1      "rtl_nic/rtl8127a-1.fw"
- #define TX_DMA_BURST  7       /* Maximum PCI burst, '7' is unlimited */
- #define InterFrameGap 0x03    /* 3 means InterFrameGap = the shortest one */
-@@ -98,6 +99,9 @@ static const struct rtl_chip_info {
-       const char *name;
-       const char *fw_name;
- } rtl_chip_infos[] = {
-+      /* 8127A family. */
-+      { 0x7cf, 0x6c9, RTL_GIGA_MAC_VER_80, "RTL8127A", FIRMWARE_8127A_1 },
-+
-       /* 8126A family. */
-       { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_3 },
-       { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_2 },
-@@ -222,8 +226,10 @@ static const struct pci_device_id rtl816
-       { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
-       { PCI_VDEVICE(REALTEK,  0x8125) },
-       { PCI_VDEVICE(REALTEK,  0x8126) },
-+      { PCI_VDEVICE(REALTEK,  0x8127) },
-       { PCI_VDEVICE(REALTEK,  0x3000) },
-       { PCI_VDEVICE(REALTEK,  0x5000) },
-+      { PCI_VDEVICE(REALTEK,  0x0e10) },
-       {}
- };
-@@ -769,6 +775,7 @@ MODULE_FIRMWARE(FIRMWARE_8125D_2);
- MODULE_FIRMWARE(FIRMWARE_8125BP_2);
- MODULE_FIRMWARE(FIRMWARE_8126A_2);
- MODULE_FIRMWARE(FIRMWARE_8126A_3);
-+MODULE_FIRMWARE(FIRMWARE_8127A_1);
- static inline struct device *tp_to_dev(struct rtl8169_private *tp)
- {
-@@ -2934,6 +2941,7 @@ static void rtl_hw_aspm_clkreq_enable(st
-               rtl_mod_config5(tp, 0, ASPM_en);
-               switch (tp->mac_version) {
-               case RTL_GIGA_MAC_VER_70:
-+              case RTL_GIGA_MAC_VER_80:
-                       val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
-                       RTL_W8(tp, INT_CFG0_8125, val8);
-                       break;
-@@ -2965,6 +2973,7 @@ static void rtl_hw_aspm_clkreq_enable(st
-               switch (tp->mac_version) {
-               case RTL_GIGA_MAC_VER_70:
-+              case RTL_GIGA_MAC_VER_80:
-                       val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
-                       RTL_W8(tp, INT_CFG0_8125, val8);
-                       break;
-@@ -3684,10 +3693,13 @@ static void rtl_hw_start_8125_common(str
-       /* disable new tx descriptor format */
-       r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_70)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
-+          tp->mac_version == RTL_GIGA_MAC_VER_80)
-               RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_70)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_80)
-+              r8168_mac_ocp_modify(tp, 0xe614, 0x0f00, 0x0f00);
-+      else if (tp->mac_version == RTL_GIGA_MAC_VER_70)
-               r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
-       else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
-               r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
-@@ -3705,7 +3717,8 @@ static void rtl_hw_start_8125_common(str
-       r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0000);
-       r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
-       r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
--      if (tp->mac_version == RTL_GIGA_MAC_VER_70)
-+      if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
-+          tp->mac_version == RTL_GIGA_MAC_VER_80)
-               r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
-       else
-               r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
-@@ -3783,6 +3796,12 @@ static void rtl_hw_start_8126a(struct rt
-       rtl_hw_start_8125_common(tp);
- }
-+static void rtl_hw_start_8127a(struct rtl8169_private *tp)
-+{
-+      rtl_set_def_aspm_entry_latency(tp);
-+      rtl_hw_start_8125_common(tp);
-+}
-+
- static void rtl_hw_config(struct rtl8169_private *tp)
- {
-       static const rtl_generic_fct hw_configs[] = {
-@@ -3826,6 +3845,7 @@ static void rtl_hw_config(struct rtl8169
-               [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d,
-               [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
-+              [RTL_GIGA_MAC_VER_80] = rtl_hw_start_8127a,
-       };
-       if (hw_configs[tp->mac_version])
-@@ -3843,8 +3863,11 @@ static void rtl_hw_start_8125(struct rtl
-       case RTL_GIGA_MAC_VER_61:
-       case RTL_GIGA_MAC_VER_64:
-       case RTL_GIGA_MAC_VER_66:
-+      case RTL_GIGA_MAC_VER_80:
-               for (i = 0xa00; i < 0xb00; i += 4)
-                       RTL_W32(tp, i, 0);
-+              if (tp->mac_version == RTL_GIGA_MAC_VER_80)
-+                      RTL_W16(tp, INT_CFG1_8125, 0x0000);
-               break;
-       case RTL_GIGA_MAC_VER_63:
-       case RTL_GIGA_MAC_VER_70:
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1130,6 +1130,171 @@ static void rtl8126a_hw_phy_config(struc
-       rtl8125_common_config_eee_phy(phydev);
- }
-+static void rtl8127a_1_hw_phy_config(struct rtl8169_private *tp,
-+                                   struct phy_device *phydev)
-+{
-+      r8169_apply_firmware(tp);
-+      rtl8168g_enable_gphy_10m(phydev);
-+
-+      r8168g_phy_param(phydev, 0x8415, 0xff00, 0x9300);
-+      r8168g_phy_param(phydev, 0x81a3, 0xff00, 0x0f00);
-+      r8168g_phy_param(phydev, 0x81ae, 0xff00, 0x0f00);
-+      r8168g_phy_param(phydev, 0x81b9, 0xff00, 0xb900);
-+      rtl8125_phy_param(phydev, 0x83b0, 0x0e00, 0x0000);
-+      rtl8125_phy_param(phydev, 0x83C5, 0x0e00, 0x0000);
-+      rtl8125_phy_param(phydev, 0x83da, 0x0e00, 0x0000);
-+      rtl8125_phy_param(phydev, 0x83ef, 0x0e00, 0x0000);
-+      phy_modify_paged(phydev, 0x0bf3, 0x14, 0x01f0, 0x0160);
-+      phy_modify_paged(phydev, 0x0bf3, 0x15, 0x001f, 0x0014);
-+      phy_modify_paged(phydev, 0x0bf2, 0x14, 0x6000, 0x0000);
-+      phy_modify_paged(phydev, 0x0bf2, 0x16, 0xc000, 0x0000);
-+      phy_modify_paged(phydev, 0x0bf2, 0x14, 0x1fff, 0x0187);
-+      phy_modify_paged(phydev, 0x0bf2, 0x15, 0x003f, 0x0003);
-+
-+      r8168g_phy_param(phydev, 0x8173, 0xffff, 0x8620);
-+      r8168g_phy_param(phydev, 0x8175, 0xffff, 0x8671);
-+      r8168g_phy_param(phydev, 0x817c, 0x0000, 0x2000);
-+      r8168g_phy_param(phydev, 0x8187, 0x0000, 0x2000);
-+      r8168g_phy_param(phydev, 0x8192, 0x0000, 0x2000);
-+      r8168g_phy_param(phydev, 0x819d, 0x0000, 0x2000);
-+      r8168g_phy_param(phydev, 0x81a8, 0x2000, 0x0000);
-+      r8168g_phy_param(phydev, 0x81b3, 0x2000, 0x0000);
-+      r8168g_phy_param(phydev, 0x81be, 0x0000, 0x2000);
-+      r8168g_phy_param(phydev, 0x817d, 0xff00, 0xa600);
-+      r8168g_phy_param(phydev, 0x8188, 0xff00, 0xa600);
-+      r8168g_phy_param(phydev, 0x8193, 0xff00, 0xa600);
-+      r8168g_phy_param(phydev, 0x819e, 0xff00, 0xa600);
-+      r8168g_phy_param(phydev, 0x81a9, 0xff00, 0x1400);
-+      r8168g_phy_param(phydev, 0x81b4, 0xff00, 0x1400);
-+      r8168g_phy_param(phydev, 0x81bf, 0xff00, 0xa600);
-+
-+      phy_modify_paged(phydev, 0x0aea, 0x15, 0x0028, 0x0000);
-+
-+      rtl8125_phy_param(phydev, 0x84f0, 0xffff, 0x201c);
-+      rtl8125_phy_param(phydev, 0x84f2, 0xffff, 0x3117);
-+
-+      phy_write_paged(phydev, 0x0aec, 0x13, 0x0000);
-+      phy_write_paged(phydev, 0x0ae2, 0x10, 0xffff);
-+      phy_write_paged(phydev, 0x0aec, 0x17, 0xffff);
-+      phy_write_paged(phydev, 0x0aed, 0x11, 0xffff);
-+      phy_write_paged(phydev, 0x0aec, 0x14, 0x0000);
-+      phy_modify_paged(phydev, 0x0aed, 0x10, 0x0001, 0x0000);
-+      phy_write_paged(phydev, 0x0adb, 0x14, 0x0150);
-+      rtl8125_phy_param(phydev, 0x8197, 0xff00, 0x5000);
-+      rtl8125_phy_param(phydev, 0x8231, 0xff00, 0x5000);
-+      rtl8125_phy_param(phydev, 0x82cb, 0xff00, 0x5000);
-+      rtl8125_phy_param(phydev, 0x82cd, 0xff00, 0x5700);
-+      rtl8125_phy_param(phydev, 0x8233, 0xff00, 0x5700);
-+      rtl8125_phy_param(phydev, 0x8199, 0xff00, 0x5700);
-+
-+      rtl8125_phy_param(phydev, 0x815a, 0xffff, 0x0150);
-+      rtl8125_phy_param(phydev, 0x81f4, 0xffff, 0x0150);
-+      rtl8125_phy_param(phydev, 0x828e, 0xffff, 0x0150);
-+      rtl8125_phy_param(phydev, 0x81b1, 0xffff, 0x0000);
-+      rtl8125_phy_param(phydev, 0x824b, 0xffff, 0x0000);
-+      rtl8125_phy_param(phydev, 0x82e5, 0xffff, 0x0000);
-+
-+      rtl8125_phy_param(phydev, 0x84f7, 0xff00, 0x2800);
-+      phy_modify_paged(phydev, 0x0aec, 0x11, 0x0000, 0x1000);
-+      rtl8125_phy_param(phydev, 0x81b3, 0xff00, 0xad00);
-+      rtl8125_phy_param(phydev, 0x824d, 0xff00, 0xad00);
-+      rtl8125_phy_param(phydev, 0x82e7, 0xff00, 0xad00);
-+      phy_modify_paged(phydev, 0x0ae4, 0x17, 0x000f, 0x0001);
-+      rtl8125_phy_param(phydev, 0x82ce, 0xf000, 0x4000);
-+
-+      rtl8125_phy_param(phydev, 0x84ac, 0xffff, 0x0000);
-+      rtl8125_phy_param(phydev, 0x84ae, 0xffff, 0x0000);
-+      rtl8125_phy_param(phydev, 0x84b0, 0xffff, 0xf818);
-+      rtl8125_phy_param(phydev, 0x84b2, 0xff00, 0x6000);
-+
-+      rtl8125_phy_param(phydev, 0x8ffc, 0xffff, 0x6008);
-+      rtl8125_phy_param(phydev, 0x8ffe, 0xffff, 0xf450);
-+
-+      rtl8125_phy_param(phydev, 0x8015, 0x0000, 0x0200);
-+      rtl8125_phy_param(phydev, 0x8016, 0x0800, 0x0000);
-+      rtl8125_phy_param(phydev, 0x8fe6, 0xff00, 0x0800);
-+      rtl8125_phy_param(phydev, 0x8fe4, 0xffff, 0x2114);
-+
-+      rtl8125_phy_param(phydev, 0x8647, 0xffff, 0xa7b1);
-+      rtl8125_phy_param(phydev, 0x8649, 0xffff, 0xbbca);
-+      rtl8125_phy_param(phydev, 0x864b, 0xff00, 0xdc00);
-+
-+      rtl8125_phy_param(phydev, 0x8154, 0xc000, 0x4000);
-+      rtl8125_phy_param(phydev, 0x8158, 0xc000, 0x0000);
-+
-+      rtl8125_phy_param(phydev, 0x826c, 0xffff, 0xffff);
-+      rtl8125_phy_param(phydev, 0x826e, 0xffff, 0xffff);
-+
-+      rtl8125_phy_param(phydev, 0x8872, 0xff00, 0x0e00);
-+      r8168g_phy_param(phydev, 0x8012, 0x0000, 0x0800);
-+      r8168g_phy_param(phydev, 0x8012, 0x0000, 0x4000);
-+      phy_modify_paged(phydev, 0x0b57, 0x13, 0x0000, 0x0001);
-+      r8168g_phy_param(phydev, 0x834a, 0xff00, 0x0700);
-+      rtl8125_phy_param(phydev, 0x8217, 0x3f00, 0x2a00);
-+      r8168g_phy_param(phydev, 0x81b1, 0xff00, 0x0b00);
-+      rtl8125_phy_param(phydev, 0x8fed, 0xff00, 0x4e00);
-+
-+      rtl8125_phy_param(phydev, 0x88ac, 0xff00, 0x2300);
-+      phy_modify_paged(phydev, 0x0bf0, 0x16, 0x0000, 0x3800);
-+      rtl8125_phy_param(phydev, 0x88de, 0xff00, 0x0000);
-+      rtl8125_phy_param(phydev, 0x80b4, 0xffff, 0x5195);
-+
-+      r8168g_phy_param(phydev, 0x8370, 0xffff, 0x8671);
-+      r8168g_phy_param(phydev, 0x8372, 0xffff, 0x86c8);
-+
-+      r8168g_phy_param(phydev, 0x8401, 0xffff, 0x86c8);
-+      r8168g_phy_param(phydev, 0x8403, 0xffff, 0x86da);
-+      r8168g_phy_param(phydev, 0x8406, 0x1800, 0x1000);
-+      r8168g_phy_param(phydev, 0x8408, 0x1800, 0x1000);
-+      r8168g_phy_param(phydev, 0x840a, 0x1800, 0x1000);
-+      r8168g_phy_param(phydev, 0x840c, 0x1800, 0x1000);
-+      r8168g_phy_param(phydev, 0x840e, 0x1800, 0x1000);
-+      r8168g_phy_param(phydev, 0x8410, 0x1800, 0x1000);
-+      r8168g_phy_param(phydev, 0x8412, 0x1800, 0x1000);
-+      r8168g_phy_param(phydev, 0x8414, 0x1800, 0x1000);
-+      r8168g_phy_param(phydev, 0x8416, 0x1800, 0x1000);
-+
-+      r8168g_phy_param(phydev, 0x82bd, 0xffff, 0x1f40);
-+
-+      phy_modify_paged(phydev, 0x0bfb, 0x12, 0x07ff, 0x0328);
-+      phy_write_paged(phydev, 0x0bfb, 0x13, 0x3e14);
-+
-+      r8168g_phy_param(phydev, 0x81c4, 0xffff, 0x003b);
-+      r8168g_phy_param(phydev, 0x81c6, 0xffff, 0x0086);
-+      r8168g_phy_param(phydev, 0x81c8, 0xffff, 0x00b7);
-+      r8168g_phy_param(phydev, 0x81ca, 0xffff, 0x00db);
-+      r8168g_phy_param(phydev, 0x81cc, 0xffff, 0x00fe);
-+      r8168g_phy_param(phydev, 0x81ce, 0xffff, 0x00fe);
-+      r8168g_phy_param(phydev, 0x81d0, 0xffff, 0x00fe);
-+      r8168g_phy_param(phydev, 0x81d2, 0xffff, 0x00fe);
-+      r8168g_phy_param(phydev, 0x81d4, 0xffff, 0x00c3);
-+      r8168g_phy_param(phydev, 0x81d6, 0xffff, 0x0078);
-+      r8168g_phy_param(phydev, 0x81d8, 0xffff, 0x0047);
-+      r8168g_phy_param(phydev, 0x81da, 0xffff, 0x0023);
-+
-+      rtl8125_phy_param(phydev, 0x88d7, 0xffff, 0x01a0);
-+      rtl8125_phy_param(phydev, 0x88d9, 0xffff, 0x01a0);
-+      rtl8125_phy_param(phydev, 0x8ffa, 0xffff, 0x002a);
-+
-+      rtl8125_phy_param(phydev, 0x8fee, 0xffff, 0xffdf);
-+      rtl8125_phy_param(phydev, 0x8ff0, 0xffff, 0xffff);
-+      rtl8125_phy_param(phydev, 0x8ff2, 0xffff, 0x0a4a);
-+      rtl8125_phy_param(phydev, 0x8ff4, 0xffff, 0xaa5a);
-+      rtl8125_phy_param(phydev, 0x8ff6, 0xffff, 0x0a4a);
-+
-+      rtl8125_phy_param(phydev, 0x8ff8, 0xffff, 0xaa5a);
-+      rtl8125_phy_param(phydev, 0x88d5, 0xff00, 0x0200);
-+
-+      r8168g_phy_param(phydev, 0x84bb, 0xff00, 0x0a00);
-+      r8168g_phy_param(phydev, 0x84c0, 0xff00, 0x1600);
-+
-+      phy_modify_paged(phydev, 0x0a43, 0x10, 0x0000, 0x0003);
-+
-+      rtl8125_legacy_force_mode(phydev);
-+      rtl8168g_disable_aldps(phydev);
-+      rtl8125_common_config_eee_phy(phydev);
-+}
-+
- void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
-                        enum mac_version ver)
- {
-@@ -1181,6 +1346,7 @@ void r8169_hw_phy_config(struct rtl8169_
-               [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
-               [RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config,
-               [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
-+              [RTL_GIGA_MAC_VER_80] = rtl8127a_1_hw_phy_config,
-       };
-       if (phy_configs[ver])
diff --git a/target/linux/generic/backport-6.18/781-01-v6.13-net-phy-realtek-read-duplex-and-gbit-master-from-PHY.patch b/target/linux/generic/backport-6.18/781-01-v6.13-net-phy-realtek-read-duplex-and-gbit-master-from-PHY.patch
deleted file mode 100644 (file)
index 31b8aab..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-From 081c9c0265c91b8333165aa6230c20bcbc6f7cbf Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 10 Oct 2024 14:07:16 +0100
-Subject: [PATCH] net: phy: realtek: read duplex and gbit master from PHYSR
- register
-
-The PHYSR MMD register is present and defined equally for all RTL82xx
-Ethernet PHYs.
-Read duplex and Gbit master bits from rtlgen_decode_speed() and rename
-it to rtlgen_decode_physr().
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://patch.msgid.link/b9a76341da851a18c985bc4774fa295babec79bb.1728565530.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek.c | 41 +++++++++++++++++++++++++++++++--------
- 1 file changed, 33 insertions(+), 8 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -80,15 +80,18 @@
- #define RTL822X_VND2_GANLPAR                          0xa414
--#define RTL822X_VND2_PHYSR                            0xa434
--
- #define RTL8366RB_POWER_SAVE                  0x15
- #define RTL8366RB_POWER_SAVE_ON                       BIT(12)
- #define RTL9000A_GINMR                                0x14
- #define RTL9000A_GINMR_LINK_STATUS            BIT(4)
--#define RTLGEN_SPEED_MASK                     0x0630
-+#define RTL_VND2_PHYSR                                0xa434
-+#define RTL_VND2_PHYSR_DUPLEX                 BIT(3)
-+#define RTL_VND2_PHYSR_SPEEDL                 GENMASK(5, 4)
-+#define RTL_VND2_PHYSR_SPEEDH                 GENMASK(10, 9)
-+#define RTL_VND2_PHYSR_MASTER                 BIT(11)
-+#define RTL_VND2_PHYSR_SPEED_MASK             (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
- #define RTL_GENERIC_PHYID                     0x001cc800
- #define RTL_8211FVD_PHYID                     0x001cc878
-@@ -661,9 +664,18 @@ static int rtl8366rb_config_init(struct
- }
- /* get actual speed to cover the downshift case */
--static void rtlgen_decode_speed(struct phy_device *phydev, int val)
-+static void rtlgen_decode_physr(struct phy_device *phydev, int val)
- {
--      switch (val & RTLGEN_SPEED_MASK) {
-+      /* bit 3
-+       * 0: Half Duplex
-+       * 1: Full Duplex
-+       */
-+      if (val & RTL_VND2_PHYSR_DUPLEX)
-+              phydev->duplex = DUPLEX_FULL;
-+      else
-+              phydev->duplex = DUPLEX_HALF;
-+
-+      switch (val & RTL_VND2_PHYSR_SPEED_MASK) {
-       case 0x0000:
-               phydev->speed = SPEED_10;
-               break;
-@@ -685,6 +697,19 @@ static void rtlgen_decode_speed(struct p
-       default:
-               break;
-       }
-+
-+      /* bit 11
-+       * 0: Slave Mode
-+       * 1: Master Mode
-+       */
-+      if (phydev->speed >= 1000) {
-+              if (val & RTL_VND2_PHYSR_MASTER)
-+                      phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
-+              else
-+                      phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
-+      } else {
-+              phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
-+      }
- }
- static int rtlgen_read_status(struct phy_device *phydev)
-@@ -702,7 +727,7 @@ static int rtlgen_read_status(struct phy
-       if (val < 0)
-               return val;
--      rtlgen_decode_speed(phydev, val);
-+      rtlgen_decode_physr(phydev, val);
-       return 0;
- }
-@@ -1008,11 +1033,11 @@ static int rtl822x_c45_read_status(struc
-               return 0;
-       /* Read actual speed from vendor register. */
--      val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR);
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
-       if (val < 0)
-               return val;
--      rtlgen_decode_speed(phydev, val);
-+      rtlgen_decode_physr(phydev, val);
-       return 0;
- }
diff --git a/target/linux/generic/backport-6.18/781-02-v6.13-net-phy-realtek-change-order-of-calls-in-C22-read_st.patch b/target/linux/generic/backport-6.18/781-02-v6.13-net-phy-realtek-change-order-of-calls-in-C22-read_st.patch
deleted file mode 100644 (file)
index 2e5d7bb..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From 68d5cd09e8919679ce13b85950debea4b2e98e04 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 10 Oct 2024 14:07:26 +0100
-Subject: [PATCH] net: phy: realtek: change order of calls in C22 read_status()
-
-Always call rtlgen_read_status() first, so genphy_read_status() which
-is called by it clears bits in case auto-negotiation has not completed.
-Also clear 10GBT link-partner advertisement bits in case auto-negotiation
-is disabled or has not completed.
-
-Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://patch.msgid.link/b15929a41621d215c6b2b57393368086589569ec.1728565530.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek.c | 22 +++++++++++++++-------
- 1 file changed, 15 insertions(+), 7 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -950,17 +950,25 @@ static void rtl822xb_update_interface(st
- static int rtl822x_read_status(struct phy_device *phydev)
- {
--      if (phydev->autoneg == AUTONEG_ENABLE) {
--              int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
-+      int lpadv, ret;
--              if (lpadv < 0)
--                      return lpadv;
-+      ret = rtlgen_read_status(phydev);
-+      if (ret < 0)
-+              return ret;
--              mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
--                                                lpadv);
-+      if (phydev->autoneg == AUTONEG_DISABLE ||
-+          !phydev->autoneg_complete) {
-+              mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
-+              return 0;
-       }
--      return rtlgen_read_status(phydev);
-+      lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
-+      if (lpadv < 0)
-+              return lpadv;
-+
-+      mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
-+
-+      return 0;
- }
- static int rtl822xb_read_status(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.18/781-03-v6.13-net-phy-realtek-clear-1000Base-T-link-partner-advert.patch b/target/linux/generic/backport-6.18/781-03-v6.13-net-phy-realtek-clear-1000Base-T-link-partner-advert.patch
deleted file mode 100644 (file)
index f7d8a5a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 5cb409b3960e75467cbb0a8e1e5596b4490570e3 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 10 Oct 2024 14:07:39 +0100
-Subject: [PATCH] net: phy: realtek: clear 1000Base-T link partner
- advertisement
-
-Clear 1000Base-T link partner advertisement bits in Clause-45
-read_status() function in case auto-negotiation is disabled or has not
-been completed.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://patch.msgid.link/9dc9b47b2d675708afef3ad366bfd78eb584d958.1728565530.git.daniel@makrotopia.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1027,6 +1027,10 @@ static int rtl822x_c45_read_status(struc
-       if (ret < 0)
-               return ret;
-+      if (phydev->autoneg == AUTONEG_DISABLE ||
-+          !genphy_c45_aneg_done(phydev))
-+              mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
-+
-       /* Vendor register as C45 has no standardized support for 1000BaseT */
-       if (phydev->autoneg == AUTONEG_ENABLE) {
-               val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
diff --git a/target/linux/generic/backport-6.18/781-06-v6.14-net-phy-realtek-add-support-for-reading-MDIO_MMD_VEN.patch b/target/linux/generic/backport-6.18/781-06-v6.14-net-phy-realtek-add-support-for-reading-MDIO_MMD_VEN.patch
deleted file mode 100644 (file)
index 2add672..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From 3d483a10327f38595f714f9f9e9dde43a622cb0f Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 11 Jan 2025 21:49:31 +0100
-Subject: [PATCH] net: phy: realtek: add support for reading MDIO_MMD_VEND2
- regs on RTL8125/RTL8126
-
-RTL8125/RTL8126 don't support MMD access to the internal PHY, but
-provide a mechanism to access at least all MDIO_MMD_VEND2 registers.
-By exposing this mechanism standard MMD access functions can be used
-to access the MDIO_MMD_VEND2 registers.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/e821b302-5fe6-49ab-aabd-05da500581c0@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -736,7 +736,11 @@ static int rtlgen_read_mmd(struct phy_de
- {
-       int ret;
--      if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
-+      if (devnum == MDIO_MMD_VEND2) {
-+              rtl821x_write_page(phydev, regnum >> 4);
-+              ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1));
-+              rtl821x_write_page(phydev, 0);
-+      } else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
-               rtl821x_write_page(phydev, 0xa5c);
-               ret = __phy_read(phydev, 0x12);
-               rtl821x_write_page(phydev, 0);
-@@ -760,7 +764,11 @@ static int rtlgen_write_mmd(struct phy_d
- {
-       int ret;
--      if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
-+      if (devnum == MDIO_MMD_VEND2) {
-+              rtl821x_write_page(phydev, regnum >> 4);
-+              ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val);
-+              rtl821x_write_page(phydev, 0);
-+      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
-               rtl821x_write_page(phydev, 0xa5d);
-               ret = __phy_write(phydev, 0x10, val);
-               rtl821x_write_page(phydev, 0);
diff --git a/target/linux/generic/backport-6.18/781-07-v6.14-net-phy-realtek-clear-1000Base-T-lpa-if-link-is-down.patch b/target/linux/generic/backport-6.18/781-07-v6.14-net-phy-realtek-clear-1000Base-T-lpa-if-link-is-down.patch
deleted file mode 100644 (file)
index 002b99e..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From 34d5a86ff7bbe225fba3ad91f9b4dc85fb408e18 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 15 Jan 2025 14:43:35 +0000
-Subject: [PATCH] net: phy: realtek: clear 1000Base-T lpa if link is down
-
-Only read 1000Base-T link partner advertisement if autonegotiation has
-completed and otherwise 1000Base-T link partner advertisement bits.
-
-This fixes bogus 1000Base-T link partner advertisement after link goes
-down (eg. by disconnecting the wire).
-Fixes: 5cb409b3960e ("net: phy: realtek: clear 1000Base-T link partner advertisement")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/realtek.c | 19 ++++++++-----------
- 1 file changed, 8 insertions(+), 11 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1031,23 +1031,20 @@ static int rtl822x_c45_read_status(struc
- {
-       int ret, val;
--      ret = genphy_c45_read_status(phydev);
--      if (ret < 0)
--              return ret;
--
--      if (phydev->autoneg == AUTONEG_DISABLE ||
--          !genphy_c45_aneg_done(phydev))
--              mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
--
-       /* Vendor register as C45 has no standardized support for 1000BaseT */
--      if (phydev->autoneg == AUTONEG_ENABLE) {
-+      if (phydev->autoneg == AUTONEG_ENABLE && genphy_c45_aneg_done(phydev)) {
-               val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
-                                  RTL822X_VND2_GANLPAR);
-               if (val < 0)
-                       return val;
--
--              mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
-+      } else {
-+              val = 0;
-       }
-+      mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
-+
-+      ret = genphy_c45_read_status(phydev);
-+      if (ret < 0)
-+              return ret;
-       if (!phydev->link)
-               return 0;
diff --git a/target/linux/generic/backport-6.18/781-08-v6.14-net-phy-realtek-clear-master_slave_state-if-link-is-.patch b/target/linux/generic/backport-6.18/781-08-v6.14-net-phy-realtek-clear-master_slave_state-if-link-is-.patch
deleted file mode 100644 (file)
index f8cfc4d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From ea8318cb33e593bbfc59d637eae45a69732c5387 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 15 Jan 2025 14:43:43 +0000
-Subject: [PATCH] net: phy: realtek: clear master_slave_state if link is down
-
-rtlgen_decode_physr() which sets master_slave_state isn't called in case
-the link is down and other than rtlgen_read_status(),
-rtl822x_c45_read_status() doesn't implicitely clear master_slave_state.
-
-Avoid stale master_slave_state by always setting it to
-MASTER_SLAVE_STATE_UNKNOWN in rtl822x_c45_read_status() in case the link
-is down.
-
-Fixes: 081c9c0265c9 ("net: phy: realtek: read duplex and gbit master from PHYSR register")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/realtek.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1046,8 +1046,10 @@ static int rtl822x_c45_read_status(struc
-       if (ret < 0)
-               return ret;
--      if (!phydev->link)
-+      if (!phydev->link) {
-+              phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
-               return 0;
-+      }
-       /* Read actual speed from vendor register. */
-       val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
diff --git a/target/linux/generic/backport-6.18/781-09-v6.14-net-phy-realtek-always-clear-NBase-T-lpa.patch b/target/linux/generic/backport-6.18/781-09-v6.14-net-phy-realtek-always-clear-NBase-T-lpa.patch
deleted file mode 100644 (file)
index e628bed..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From d3eb58549842c60ed46f37da7f4da969e3d6ecd3 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 15 Jan 2025 14:45:00 +0000
-Subject: [PATCH] net: phy: realtek: always clear NBase-T lpa
-
-Clear NBase-T link partner advertisement before calling
-rtlgen_read_status() to avoid phy_resolve_aneg_linkmode() wrongly
-setting speed and duplex.
-
-This fixes bogus 2.5G/5G/10G link partner advertisement and thus
-speed and duplex being set by phy_resolve_aneg_linkmode() due to stale
-NBase-T lpa.
-
-Fixes: 68d5cd09e891 ("net: phy: realtek: change order of calls in C22 read_status()")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/realtek.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -960,15 +960,15 @@ static int rtl822x_read_status(struct ph
- {
-       int lpadv, ret;
-+      mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
-+
-       ret = rtlgen_read_status(phydev);
-       if (ret < 0)
-               return ret;
-       if (phydev->autoneg == AUTONEG_DISABLE ||
--          !phydev->autoneg_complete) {
--              mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
-+          !phydev->autoneg_complete)
-               return 0;
--      }
-       lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
-       if (lpadv < 0)
diff --git a/target/linux/generic/backport-6.18/781-10-v6.14-net-phy-move-realtek-PHY-driver-to-its-own-subdirect.patch b/target/linux/generic/backport-6.18/781-10-v6.14-net-phy-move-realtek-PHY-driver-to-its-own-subdirect.patch
deleted file mode 100644 (file)
index 633468f..0000000
+++ /dev/null
@@ -1,3247 +0,0 @@
-From 1416a9b2ba710d31954131c06d46f298e340aa2c Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 11 Jan 2025 21:50:19 +0100
-Subject: [PATCH] net: phy: move realtek PHY driver to its own subdirectory
-
-In preparation of adding a source file with hwmon support, move the
-Realtek PHY driver to its own subdirectory and rename realtek.c to
-realtek_main.c.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/c566551b-c915-4e34-9b33-129a6ddd6e4c@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/Kconfig                               | 5 +----
- drivers/net/phy/Makefile                              | 2 +-
- drivers/net/phy/realtek/Kconfig                       | 5 +++++
- drivers/net/phy/realtek/Makefile                      | 3 +++
- drivers/net/phy/{realtek.c => realtek/realtek_main.c} | 0
- 5 files changed, 10 insertions(+), 5 deletions(-)
- create mode 100644 drivers/net/phy/realtek/Kconfig
- create mode 100644 drivers/net/phy/realtek/Makefile
- rename drivers/net/phy/{realtek.c => realtek/realtek_main.c} (100%)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -343,10 +343,7 @@ config QSEMI_PHY
-       help
-         Currently supports the qs6612
--config REALTEK_PHY
--      tristate "Realtek PHYs"
--      help
--        Supports the Realtek 821x PHY.
-+source "drivers/net/phy/realtek/Kconfig"
- config RENESAS_PHY
-       tristate "Renesas PHYs"
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -94,7 +94,7 @@ obj-$(CONFIG_NXP_CBTX_PHY)   += nxp-cbtx.o
- obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o
- obj-y                         += qcom/
- obj-$(CONFIG_QSEMI_PHY)               += qsemi.o
--obj-$(CONFIG_REALTEK_PHY)     += realtek.o
-+obj-$(CONFIG_REALTEK_PHY)     += realtek/
- obj-$(CONFIG_RENESAS_PHY)     += uPD60620.o
- obj-$(CONFIG_ROCKCHIP_PHY)    += rockchip.o
- obj-$(CONFIG_SMSC_PHY)                += smsc.o
---- /dev/null
-+++ b/drivers/net/phy/realtek/Kconfig
-@@ -0,0 +1,5 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+config REALTEK_PHY
-+      tristate "Realtek PHYs"
-+      help
-+        Currently supports RTL821x/RTL822x and fast ethernet PHYs
---- /dev/null
-+++ b/drivers/net/phy/realtek/Makefile
-@@ -0,0 +1,3 @@
-+# SPDX-License-Identifier: GPL-2.0
-+realtek-y                     += realtek_main.o
-+obj-$(CONFIG_REALTEK_PHY)     += realtek.o
---- a/drivers/net/phy/realtek.c
-+++ /dev/null
-@@ -1,1589 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0+
--/* drivers/net/phy/realtek.c
-- *
-- * Driver for Realtek PHYs
-- *
-- * Author: Johnson Leung <r58129@freescale.com>
-- *
-- * Copyright (c) 2004 Freescale Semiconductor, Inc.
-- */
--#include <linux/bitops.h>
--#include <linux/of.h>
--#include <linux/phy.h>
--#include <linux/module.h>
--#include <linux/delay.h>
--#include <linux/clk.h>
--
--#define RTL821x_PHYSR                         0x11
--#define RTL821x_PHYSR_DUPLEX                  BIT(13)
--#define RTL821x_PHYSR_SPEED                   GENMASK(15, 14)
--
--#define RTL821x_INER                          0x12
--#define RTL8211B_INER_INIT                    0x6400
--#define RTL8211E_INER_LINK_STATUS             BIT(10)
--#define RTL8211F_INER_LINK_STATUS             BIT(4)
--
--#define RTL821x_INSR                          0x13
--
--#define RTL821x_EXT_PAGE_SELECT                       0x1e
--#define RTL821x_PAGE_SELECT                   0x1f
--
--#define RTL8211F_PHYCR1                               0x18
--#define RTL8211F_PHYCR2                               0x19
--#define RTL8211F_INSR                         0x1d
--
--#define RTL8211F_LEDCR                                0x10
--#define RTL8211F_LEDCR_MODE                   BIT(15)
--#define RTL8211F_LEDCR_ACT_TXRX                       BIT(4)
--#define RTL8211F_LEDCR_LINK_1000              BIT(3)
--#define RTL8211F_LEDCR_LINK_100                       BIT(1)
--#define RTL8211F_LEDCR_LINK_10                        BIT(0)
--#define RTL8211F_LEDCR_MASK                   GENMASK(4, 0)
--#define RTL8211F_LEDCR_SHIFT                  5
--
--#define RTL8211F_TX_DELAY                     BIT(8)
--#define RTL8211F_RX_DELAY                     BIT(3)
--
--#define RTL8211F_ALDPS_PLL_OFF                        BIT(1)
--#define RTL8211F_ALDPS_ENABLE                 BIT(2)
--#define RTL8211F_ALDPS_XTAL_OFF                       BIT(12)
--
--#define RTL8211E_CTRL_DELAY                   BIT(13)
--#define RTL8211E_TX_DELAY                     BIT(12)
--#define RTL8211E_RX_DELAY                     BIT(11)
--
--#define RTL8211F_CLKOUT_EN                    BIT(0)
--
--#define RTL8201F_ISR                          0x1e
--#define RTL8201F_ISR_ANERR                    BIT(15)
--#define RTL8201F_ISR_DUPLEX                   BIT(13)
--#define RTL8201F_ISR_LINK                     BIT(11)
--#define RTL8201F_ISR_MASK                     (RTL8201F_ISR_ANERR | \
--                                               RTL8201F_ISR_DUPLEX | \
--                                               RTL8201F_ISR_LINK)
--#define RTL8201F_IER                          0x13
--
--#define RTL822X_VND1_SERDES_OPTION                    0x697a
--#define RTL822X_VND1_SERDES_OPTION_MODE_MASK          GENMASK(5, 0)
--#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII               0
--#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX             2
--
--#define RTL822X_VND1_SERDES_CTRL3                     0x7580
--#define RTL822X_VND1_SERDES_CTRL3_MODE_MASK           GENMASK(5, 0)
--#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII                  0x02
--#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX              0x16
--
--/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
-- * is set, they cannot be accessed by C45-over-C22.
-- */
--#define RTL822X_VND2_GBCR                             0xa412
--
--#define RTL822X_VND2_GANLPAR                          0xa414
--
--#define RTL8366RB_POWER_SAVE                  0x15
--#define RTL8366RB_POWER_SAVE_ON                       BIT(12)
--
--#define RTL9000A_GINMR                                0x14
--#define RTL9000A_GINMR_LINK_STATUS            BIT(4)
--
--#define RTL_VND2_PHYSR                                0xa434
--#define RTL_VND2_PHYSR_DUPLEX                 BIT(3)
--#define RTL_VND2_PHYSR_SPEEDL                 GENMASK(5, 4)
--#define RTL_VND2_PHYSR_SPEEDH                 GENMASK(10, 9)
--#define RTL_VND2_PHYSR_MASTER                 BIT(11)
--#define RTL_VND2_PHYSR_SPEED_MASK             (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
--
--#define RTL_GENERIC_PHYID                     0x001cc800
--#define RTL_8211FVD_PHYID                     0x001cc878
--#define RTL_8221B                             0x001cc840
--#define RTL_8221B_VB_CG                               0x001cc849
--#define RTL_8221B_VN_CG                               0x001cc84a
--#define RTL_8251B                             0x001cc862
--
--#define RTL8211F_LED_COUNT                    3
--
--MODULE_DESCRIPTION("Realtek PHY driver");
--MODULE_AUTHOR("Johnson Leung");
--MODULE_LICENSE("GPL");
--
--struct rtl821x_priv {
--      u16 phycr1;
--      u16 phycr2;
--      bool has_phycr2;
--      struct clk *clk;
--};
--
--static int rtl821x_read_page(struct phy_device *phydev)
--{
--      return __phy_read(phydev, RTL821x_PAGE_SELECT);
--}
--
--static int rtl821x_write_page(struct phy_device *phydev, int page)
--{
--      return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
--}
--
--static int rtl821x_probe(struct phy_device *phydev)
--{
--      struct device *dev = &phydev->mdio.dev;
--      struct rtl821x_priv *priv;
--      u32 phy_id = phydev->drv->phy_id;
--      int ret;
--
--      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
--      if (!priv)
--              return -ENOMEM;
--
--      priv->clk = devm_clk_get_optional_enabled(dev, NULL);
--      if (IS_ERR(priv->clk))
--              return dev_err_probe(dev, PTR_ERR(priv->clk),
--                                   "failed to get phy clock\n");
--
--      ret = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR1);
--      if (ret < 0)
--              return ret;
--
--      priv->phycr1 = ret & (RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF);
--      if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
--              priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
--
--      priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
--      if (priv->has_phycr2) {
--              ret = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR2);
--              if (ret < 0)
--                      return ret;
--
--              priv->phycr2 = ret & RTL8211F_CLKOUT_EN;
--              if (of_property_read_bool(dev->of_node, "realtek,clkout-disable"))
--                      priv->phycr2 &= ~RTL8211F_CLKOUT_EN;
--      }
--
--      phydev->priv = priv;
--
--      return 0;
--}
--
--static int rtl8201_ack_interrupt(struct phy_device *phydev)
--{
--      int err;
--
--      err = phy_read(phydev, RTL8201F_ISR);
--
--      return (err < 0) ? err : 0;
--}
--
--static int rtl821x_ack_interrupt(struct phy_device *phydev)
--{
--      int err;
--
--      err = phy_read(phydev, RTL821x_INSR);
--
--      return (err < 0) ? err : 0;
--}
--
--static int rtl8211f_ack_interrupt(struct phy_device *phydev)
--{
--      int err;
--
--      err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
--
--      return (err < 0) ? err : 0;
--}
--
--static int rtl8201_config_intr(struct phy_device *phydev)
--{
--      u16 val;
--      int err;
--
--      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
--              err = rtl8201_ack_interrupt(phydev);
--              if (err)
--                      return err;
--
--              val = BIT(13) | BIT(12) | BIT(11);
--              err = phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
--      } else {
--              val = 0;
--              err = phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
--              if (err)
--                      return err;
--
--              err = rtl8201_ack_interrupt(phydev);
--      }
--
--      return err;
--}
--
--static int rtl8211b_config_intr(struct phy_device *phydev)
--{
--      int err;
--
--      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
--              err = rtl821x_ack_interrupt(phydev);
--              if (err)
--                      return err;
--
--              err = phy_write(phydev, RTL821x_INER,
--                              RTL8211B_INER_INIT);
--      } else {
--              err = phy_write(phydev, RTL821x_INER, 0);
--              if (err)
--                      return err;
--
--              err = rtl821x_ack_interrupt(phydev);
--      }
--
--      return err;
--}
--
--static int rtl8211e_config_intr(struct phy_device *phydev)
--{
--      int err;
--
--      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
--              err = rtl821x_ack_interrupt(phydev);
--              if (err)
--                      return err;
--
--              err = phy_write(phydev, RTL821x_INER,
--                              RTL8211E_INER_LINK_STATUS);
--      } else {
--              err = phy_write(phydev, RTL821x_INER, 0);
--              if (err)
--                      return err;
--
--              err = rtl821x_ack_interrupt(phydev);
--      }
--
--      return err;
--}
--
--static int rtl8211f_config_intr(struct phy_device *phydev)
--{
--      u16 val;
--      int err;
--
--      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
--              err = rtl8211f_ack_interrupt(phydev);
--              if (err)
--                      return err;
--
--              val = RTL8211F_INER_LINK_STATUS;
--              err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
--      } else {
--              val = 0;
--              err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
--              if (err)
--                      return err;
--
--              err = rtl8211f_ack_interrupt(phydev);
--      }
--
--      return err;
--}
--
--static irqreturn_t rtl8201_handle_interrupt(struct phy_device *phydev)
--{
--      int irq_status;
--
--      irq_status = phy_read(phydev, RTL8201F_ISR);
--      if (irq_status < 0) {
--              phy_error(phydev);
--              return IRQ_NONE;
--      }
--
--      if (!(irq_status & RTL8201F_ISR_MASK))
--              return IRQ_NONE;
--
--      phy_trigger_machine(phydev);
--
--      return IRQ_HANDLED;
--}
--
--static irqreturn_t rtl821x_handle_interrupt(struct phy_device *phydev)
--{
--      int irq_status, irq_enabled;
--
--      irq_status = phy_read(phydev, RTL821x_INSR);
--      if (irq_status < 0) {
--              phy_error(phydev);
--              return IRQ_NONE;
--      }
--
--      irq_enabled = phy_read(phydev, RTL821x_INER);
--      if (irq_enabled < 0) {
--              phy_error(phydev);
--              return IRQ_NONE;
--      }
--
--      if (!(irq_status & irq_enabled))
--              return IRQ_NONE;
--
--      phy_trigger_machine(phydev);
--
--      return IRQ_HANDLED;
--}
--
--static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev)
--{
--      int irq_status;
--
--      irq_status = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
--      if (irq_status < 0) {
--              phy_error(phydev);
--              return IRQ_NONE;
--      }
--
--      if (!(irq_status & RTL8211F_INER_LINK_STATUS))
--              return IRQ_NONE;
--
--      phy_trigger_machine(phydev);
--
--      return IRQ_HANDLED;
--}
--
--static int rtl8211_config_aneg(struct phy_device *phydev)
--{
--      int ret;
--
--      ret = genphy_config_aneg(phydev);
--      if (ret < 0)
--              return ret;
--
--      /* Quirk was copied from vendor driver. Unfortunately it includes no
--       * description of the magic numbers.
--       */
--      if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
--              phy_write(phydev, 0x17, 0x2138);
--              phy_write(phydev, 0x0e, 0x0260);
--      } else {
--              phy_write(phydev, 0x17, 0x2108);
--              phy_write(phydev, 0x0e, 0x0000);
--      }
--
--      return 0;
--}
--
--static int rtl8211c_config_init(struct phy_device *phydev)
--{
--      /* RTL8211C has an issue when operating in Gigabit slave mode */
--      return phy_set_bits(phydev, MII_CTRL1000,
--                          CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
--}
--
--static int rtl8211f_config_init(struct phy_device *phydev)
--{
--      struct rtl821x_priv *priv = phydev->priv;
--      struct device *dev = &phydev->mdio.dev;
--      u16 val_txdly, val_rxdly;
--      int ret;
--
--      ret = phy_modify_paged_changed(phydev, 0xa43, RTL8211F_PHYCR1,
--                                     RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
--                                     priv->phycr1);
--      if (ret < 0) {
--              dev_err(dev, "aldps mode  configuration failed: %pe\n",
--                      ERR_PTR(ret));
--              return ret;
--      }
--
--      switch (phydev->interface) {
--      case PHY_INTERFACE_MODE_RGMII:
--              val_txdly = 0;
--              val_rxdly = 0;
--              break;
--
--      case PHY_INTERFACE_MODE_RGMII_RXID:
--              val_txdly = 0;
--              val_rxdly = RTL8211F_RX_DELAY;
--              break;
--
--      case PHY_INTERFACE_MODE_RGMII_TXID:
--              val_txdly = RTL8211F_TX_DELAY;
--              val_rxdly = 0;
--              break;
--
--      case PHY_INTERFACE_MODE_RGMII_ID:
--              val_txdly = RTL8211F_TX_DELAY;
--              val_rxdly = RTL8211F_RX_DELAY;
--              break;
--
--      default: /* the rest of the modes imply leaving delay as is. */
--              return 0;
--      }
--
--      ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
--                                     val_txdly);
--      if (ret < 0) {
--              dev_err(dev, "Failed to update the TX delay register\n");
--              return ret;
--      } else if (ret) {
--              dev_dbg(dev,
--                      "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
--                      val_txdly ? "Enabling" : "Disabling");
--      } else {
--              dev_dbg(dev,
--                      "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
--                      val_txdly ? "enabled" : "disabled");
--      }
--
--      ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
--                                     val_rxdly);
--      if (ret < 0) {
--              dev_err(dev, "Failed to update the RX delay register\n");
--              return ret;
--      } else if (ret) {
--              dev_dbg(dev,
--                      "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
--                      val_rxdly ? "Enabling" : "Disabling");
--      } else {
--              dev_dbg(dev,
--                      "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
--                      val_rxdly ? "enabled" : "disabled");
--      }
--
--      if (priv->has_phycr2) {
--              ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2,
--                                     RTL8211F_CLKOUT_EN, priv->phycr2);
--              if (ret < 0) {
--                      dev_err(dev, "clkout configuration failed: %pe\n",
--                              ERR_PTR(ret));
--                      return ret;
--              }
--
--              return genphy_soft_reset(phydev);
--      }
--
--      return 0;
--}
--
--static int rtl821x_suspend(struct phy_device *phydev)
--{
--      struct rtl821x_priv *priv = phydev->priv;
--      int ret = 0;
--
--      if (!phydev->wol_enabled) {
--              ret = genphy_suspend(phydev);
--
--              if (ret)
--                      return ret;
--
--              clk_disable_unprepare(priv->clk);
--      }
--
--      return ret;
--}
--
--static int rtl821x_resume(struct phy_device *phydev)
--{
--      struct rtl821x_priv *priv = phydev->priv;
--      int ret;
--
--      if (!phydev->wol_enabled)
--              clk_prepare_enable(priv->clk);
--
--      ret = genphy_resume(phydev);
--      if (ret < 0)
--              return ret;
--
--      msleep(20);
--
--      return 0;
--}
--
--static int rtl8211f_led_hw_is_supported(struct phy_device *phydev, u8 index,
--                                      unsigned long rules)
--{
--      const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) |
--                                 BIT(TRIGGER_NETDEV_LINK_100) |
--                                 BIT(TRIGGER_NETDEV_LINK_1000) |
--                                 BIT(TRIGGER_NETDEV_RX) |
--                                 BIT(TRIGGER_NETDEV_TX);
--
--      /* The RTL8211F PHY supports these LED settings on up to three LEDs:
--       * - Link: Configurable subset of 10/100/1000 link rates
--       * - Active: Blink on activity, RX or TX is not differentiated
--       * The Active option has two modes, A and B:
--       * - A: Link and Active indication at configurable, but matching,
--       *      subset of 10/100/1000 link rates
--       * - B: Link indication at configurable subset of 10/100/1000 link
--       *      rates and Active indication always at all three 10+100+1000
--       *      link rates.
--       * This code currently uses mode B only.
--       */
--
--      if (index >= RTL8211F_LED_COUNT)
--              return -EINVAL;
--
--      /* Filter out any other unsupported triggers. */
--      if (rules & ~mask)
--              return -EOPNOTSUPP;
--
--      /* RX and TX are not differentiated, either both are set or not set. */
--      if (!(rules & BIT(TRIGGER_NETDEV_RX)) ^ !(rules & BIT(TRIGGER_NETDEV_TX)))
--              return -EOPNOTSUPP;
--
--      return 0;
--}
--
--static int rtl8211f_led_hw_control_get(struct phy_device *phydev, u8 index,
--                                     unsigned long *rules)
--{
--      int val;
--
--      if (index >= RTL8211F_LED_COUNT)
--              return -EINVAL;
--
--      val = phy_read_paged(phydev, 0xd04, RTL8211F_LEDCR);
--      if (val < 0)
--              return val;
--
--      val >>= RTL8211F_LEDCR_SHIFT * index;
--      val &= RTL8211F_LEDCR_MASK;
--
--      if (val & RTL8211F_LEDCR_LINK_10)
--              set_bit(TRIGGER_NETDEV_LINK_10, rules);
--
--      if (val & RTL8211F_LEDCR_LINK_100)
--              set_bit(TRIGGER_NETDEV_LINK_100, rules);
--
--      if (val & RTL8211F_LEDCR_LINK_1000)
--              set_bit(TRIGGER_NETDEV_LINK_1000, rules);
--
--      if (val & RTL8211F_LEDCR_ACT_TXRX) {
--              set_bit(TRIGGER_NETDEV_RX, rules);
--              set_bit(TRIGGER_NETDEV_TX, rules);
--      }
--
--      return 0;
--}
--
--static int rtl8211f_led_hw_control_set(struct phy_device *phydev, u8 index,
--                                     unsigned long rules)
--{
--      const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
--      u16 reg = 0;
--
--      if (index >= RTL8211F_LED_COUNT)
--              return -EINVAL;
--
--      if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
--              reg |= RTL8211F_LEDCR_LINK_10;
--
--      if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
--              reg |= RTL8211F_LEDCR_LINK_100;
--
--      if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
--              reg |= RTL8211F_LEDCR_LINK_1000;
--
--      if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
--          test_bit(TRIGGER_NETDEV_TX, &rules)) {
--              reg |= RTL8211F_LEDCR_ACT_TXRX;
--      }
--
--      reg <<= RTL8211F_LEDCR_SHIFT * index;
--      reg |= RTL8211F_LEDCR_MODE;      /* Mode B */
--
--      return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
--}
--
--static int rtl8211e_config_init(struct phy_device *phydev)
--{
--      int ret = 0, oldpage;
--      u16 val;
--
--      /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
--      switch (phydev->interface) {
--      case PHY_INTERFACE_MODE_RGMII:
--              val = RTL8211E_CTRL_DELAY | 0;
--              break;
--      case PHY_INTERFACE_MODE_RGMII_ID:
--              val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
--              break;
--      case PHY_INTERFACE_MODE_RGMII_RXID:
--              val = RTL8211E_CTRL_DELAY | RTL8211E_RX_DELAY;
--              break;
--      case PHY_INTERFACE_MODE_RGMII_TXID:
--              val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY;
--              break;
--      default: /* the rest of the modes imply leaving delays as is. */
--              return 0;
--      }
--
--      /* According to a sample driver there is a 0x1c config register on the
--       * 0xa4 extension page (0x7) layout. It can be used to disable/enable
--       * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins.
--       * The configuration register definition:
--       * 14 = reserved
--       * 13 = Force Tx RX Delay controlled by bit12 bit11,
--       * 12 = RX Delay, 11 = TX Delay
--       * 10:0 = Test && debug settings reserved by realtek
--       */
--      oldpage = phy_select_page(phydev, 0x7);
--      if (oldpage < 0)
--              goto err_restore_page;
--
--      ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
--      if (ret)
--              goto err_restore_page;
--
--      ret = __phy_modify(phydev, 0x1c, RTL8211E_CTRL_DELAY
--                         | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
--                         val);
--
--err_restore_page:
--      return phy_restore_page(phydev, oldpage, ret);
--}
--
--static int rtl8211b_suspend(struct phy_device *phydev)
--{
--      phy_write(phydev, MII_MMD_DATA, BIT(9));
--
--      return genphy_suspend(phydev);
--}
--
--static int rtl8211b_resume(struct phy_device *phydev)
--{
--      phy_write(phydev, MII_MMD_DATA, 0);
--
--      return genphy_resume(phydev);
--}
--
--static int rtl8366rb_config_init(struct phy_device *phydev)
--{
--      int ret;
--
--      ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
--                         RTL8366RB_POWER_SAVE_ON);
--      if (ret) {
--              dev_err(&phydev->mdio.dev,
--                      "error enabling power management\n");
--      }
--
--      return ret;
--}
--
--/* get actual speed to cover the downshift case */
--static void rtlgen_decode_physr(struct phy_device *phydev, int val)
--{
--      /* bit 3
--       * 0: Half Duplex
--       * 1: Full Duplex
--       */
--      if (val & RTL_VND2_PHYSR_DUPLEX)
--              phydev->duplex = DUPLEX_FULL;
--      else
--              phydev->duplex = DUPLEX_HALF;
--
--      switch (val & RTL_VND2_PHYSR_SPEED_MASK) {
--      case 0x0000:
--              phydev->speed = SPEED_10;
--              break;
--      case 0x0010:
--              phydev->speed = SPEED_100;
--              break;
--      case 0x0020:
--              phydev->speed = SPEED_1000;
--              break;
--      case 0x0200:
--              phydev->speed = SPEED_10000;
--              break;
--      case 0x0210:
--              phydev->speed = SPEED_2500;
--              break;
--      case 0x0220:
--              phydev->speed = SPEED_5000;
--              break;
--      default:
--              break;
--      }
--
--      /* bit 11
--       * 0: Slave Mode
--       * 1: Master Mode
--       */
--      if (phydev->speed >= 1000) {
--              if (val & RTL_VND2_PHYSR_MASTER)
--                      phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
--              else
--                      phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
--      } else {
--              phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
--      }
--}
--
--static int rtlgen_read_status(struct phy_device *phydev)
--{
--      int ret, val;
--
--      ret = genphy_read_status(phydev);
--      if (ret < 0)
--              return ret;
--
--      if (!phydev->link)
--              return 0;
--
--      val = phy_read_paged(phydev, 0xa43, 0x12);
--      if (val < 0)
--              return val;
--
--      rtlgen_decode_physr(phydev, val);
--
--      return 0;
--}
--
--static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
--{
--      int ret;
--
--      if (devnum == MDIO_MMD_VEND2) {
--              rtl821x_write_page(phydev, regnum >> 4);
--              ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1));
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
--              rtl821x_write_page(phydev, 0xa5c);
--              ret = __phy_read(phydev, 0x12);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
--              rtl821x_write_page(phydev, 0xa5d);
--              ret = __phy_read(phydev, 0x10);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
--              rtl821x_write_page(phydev, 0xa5d);
--              ret = __phy_read(phydev, 0x11);
--              rtl821x_write_page(phydev, 0);
--      } else {
--              ret = -EOPNOTSUPP;
--      }
--
--      return ret;
--}
--
--static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
--                          u16 val)
--{
--      int ret;
--
--      if (devnum == MDIO_MMD_VEND2) {
--              rtl821x_write_page(phydev, regnum >> 4);
--              ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
--              rtl821x_write_page(phydev, 0xa5d);
--              ret = __phy_write(phydev, 0x10, val);
--              rtl821x_write_page(phydev, 0);
--      } else {
--              ret = -EOPNOTSUPP;
--      }
--
--      return ret;
--}
--
--static int rtl822x_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
--{
--      int ret = rtlgen_read_mmd(phydev, devnum, regnum);
--
--      if (ret != -EOPNOTSUPP)
--              return ret;
--
--      if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
--              rtl821x_write_page(phydev, 0xa6e);
--              ret = __phy_read(phydev, 0x16);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
--              rtl821x_write_page(phydev, 0xa6d);
--              ret = __phy_read(phydev, 0x12);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
--              rtl821x_write_page(phydev, 0xa6d);
--              ret = __phy_read(phydev, 0x10);
--              rtl821x_write_page(phydev, 0);
--      }
--
--      return ret;
--}
--
--static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
--                           u16 val)
--{
--      int ret = rtlgen_write_mmd(phydev, devnum, regnum, val);
--
--      if (ret != -EOPNOTSUPP)
--              return ret;
--
--      if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
--              rtl821x_write_page(phydev, 0xa6d);
--              ret = __phy_write(phydev, 0x12, val);
--              rtl821x_write_page(phydev, 0);
--      }
--
--      return ret;
--}
--
--static int rtl822xb_config_init(struct phy_device *phydev)
--{
--      bool has_2500, has_sgmii;
--      u16 mode;
--      int ret;
--
--      has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
--                          phydev->host_interfaces) ||
--                 phydev->interface == PHY_INTERFACE_MODE_2500BASEX;
--
--      has_sgmii = test_bit(PHY_INTERFACE_MODE_SGMII,
--                           phydev->host_interfaces) ||
--                  phydev->interface == PHY_INTERFACE_MODE_SGMII;
--
--      /* fill in possible interfaces */
--      __assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
--                   has_2500);
--      __assign_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces,
--                   has_sgmii);
--
--      if (!has_2500 && !has_sgmii)
--              return 0;
--
--      /* determine SerDes option mode */
--      if (has_2500 && !has_sgmii) {
--              mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX;
--              phydev->rate_matching = RATE_MATCH_PAUSE;
--      } else {
--              mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII;
--              phydev->rate_matching = RATE_MATCH_NONE;
--      }
--
--      /* the following sequence with magic numbers sets up the SerDes
--       * option mode
--       */
--      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
--      if (ret < 0)
--              return ret;
--
--      ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1,
--                                   RTL822X_VND1_SERDES_OPTION,
--                                   RTL822X_VND1_SERDES_OPTION_MODE_MASK,
--                                   mode);
--      if (ret < 0)
--              return ret;
--
--      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
--      if (ret < 0)
--              return ret;
--
--      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
--      if (ret < 0)
--              return ret;
--
--      return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
--}
--
--static int rtl822xb_get_rate_matching(struct phy_device *phydev,
--                                    phy_interface_t iface)
--{
--      int val;
--
--      /* Only rate matching at 2500base-x */
--      if (iface != PHY_INTERFACE_MODE_2500BASEX)
--              return RATE_MATCH_NONE;
--
--      val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_OPTION);
--      if (val < 0)
--              return val;
--
--      if ((val & RTL822X_VND1_SERDES_OPTION_MODE_MASK) ==
--          RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX)
--              return RATE_MATCH_PAUSE;
--
--      /* RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII */
--      return RATE_MATCH_NONE;
--}
--
--static int rtl822x_get_features(struct phy_device *phydev)
--{
--      int val;
--
--      val = phy_read_paged(phydev, 0xa61, 0x13);
--      if (val < 0)
--              return val;
--
--      linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
--                       phydev->supported, val & MDIO_PMA_SPEED_2_5G);
--      linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
--                       phydev->supported, val & MDIO_PMA_SPEED_5G);
--      linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
--                       phydev->supported, val & MDIO_SPEED_10G);
--
--      return genphy_read_abilities(phydev);
--}
--
--static int rtl822x_config_aneg(struct phy_device *phydev)
--{
--      int ret = 0;
--
--      if (phydev->autoneg == AUTONEG_ENABLE) {
--              u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
--
--              ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
--                                             MDIO_AN_10GBT_CTRL_ADV2_5G |
--                                             MDIO_AN_10GBT_CTRL_ADV5G,
--                                             adv);
--              if (ret < 0)
--                      return ret;
--      }
--
--      return __genphy_config_aneg(phydev, ret);
--}
--
--static void rtl822xb_update_interface(struct phy_device *phydev)
--{
--      int val;
--
--      if (!phydev->link)
--              return;
--
--      /* Change interface according to serdes mode */
--      val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CTRL3);
--      if (val < 0)
--              return;
--
--      switch (val & RTL822X_VND1_SERDES_CTRL3_MODE_MASK) {
--      case RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX:
--              phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
--              break;
--      case RTL822X_VND1_SERDES_CTRL3_MODE_SGMII:
--              phydev->interface = PHY_INTERFACE_MODE_SGMII;
--              break;
--      }
--}
--
--static int rtl822x_read_status(struct phy_device *phydev)
--{
--      int lpadv, ret;
--
--      mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
--
--      ret = rtlgen_read_status(phydev);
--      if (ret < 0)
--              return ret;
--
--      if (phydev->autoneg == AUTONEG_DISABLE ||
--          !phydev->autoneg_complete)
--              return 0;
--
--      lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
--      if (lpadv < 0)
--              return lpadv;
--
--      mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
--
--      return 0;
--}
--
--static int rtl822xb_read_status(struct phy_device *phydev)
--{
--      int ret;
--
--      ret = rtl822x_read_status(phydev);
--      if (ret < 0)
--              return ret;
--
--      rtl822xb_update_interface(phydev);
--
--      return 0;
--}
--
--static int rtl822x_c45_get_features(struct phy_device *phydev)
--{
--      linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
--                       phydev->supported);
--
--      return genphy_c45_pma_read_abilities(phydev);
--}
--
--static int rtl822x_c45_config_aneg(struct phy_device *phydev)
--{
--      bool changed = false;
--      int ret, val;
--
--      if (phydev->autoneg == AUTONEG_DISABLE)
--              return genphy_c45_pma_setup_forced(phydev);
--
--      ret = genphy_c45_an_config_aneg(phydev);
--      if (ret < 0)
--              return ret;
--      if (ret > 0)
--              changed = true;
--
--      val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
--
--      /* Vendor register as C45 has no standardized support for 1000BaseT */
--      ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR,
--                                   ADVERTISE_1000FULL, val);
--      if (ret < 0)
--              return ret;
--      if (ret > 0)
--              changed = true;
--
--      return genphy_c45_check_and_restart_aneg(phydev, changed);
--}
--
--static int rtl822x_c45_read_status(struct phy_device *phydev)
--{
--      int ret, val;
--
--      /* Vendor register as C45 has no standardized support for 1000BaseT */
--      if (phydev->autoneg == AUTONEG_ENABLE && genphy_c45_aneg_done(phydev)) {
--              val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
--                                 RTL822X_VND2_GANLPAR);
--              if (val < 0)
--                      return val;
--      } else {
--              val = 0;
--      }
--      mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
--
--      ret = genphy_c45_read_status(phydev);
--      if (ret < 0)
--              return ret;
--
--      if (!phydev->link) {
--              phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
--              return 0;
--      }
--
--      /* Read actual speed from vendor register. */
--      val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
--      if (val < 0)
--              return val;
--
--      rtlgen_decode_physr(phydev, val);
--
--      return 0;
--}
--
--static int rtl822xb_c45_read_status(struct phy_device *phydev)
--{
--      int ret;
--
--      ret = rtl822x_c45_read_status(phydev);
--      if (ret < 0)
--              return ret;
--
--      rtl822xb_update_interface(phydev);
--
--      return 0;
--}
--
--static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
--{
--      int val;
--
--      phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
--      val = phy_read(phydev, 0x13);
--      phy_write(phydev, RTL821x_PAGE_SELECT, 0);
--
--      return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
--}
--
--/* On internal PHY's MMD reads over C22 always return 0.
-- * Check a MMD register which is known to be non-zero.
-- */
--static bool rtlgen_supports_mmd(struct phy_device *phydev)
--{
--      int val;
--
--      phy_lock_mdio_bus(phydev);
--      __phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS);
--      __phy_write(phydev, MII_MMD_DATA, MDIO_PCS_EEE_ABLE);
--      __phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS | MII_MMD_CTRL_NOINCR);
--      val = __phy_read(phydev, MII_MMD_DATA);
--      phy_unlock_mdio_bus(phydev);
--
--      return val > 0;
--}
--
--static int rtlgen_match_phy_device(struct phy_device *phydev)
--{
--      return phydev->phy_id == RTL_GENERIC_PHYID &&
--             !rtlgen_supports_2_5gbps(phydev);
--}
--
--static int rtl8226_match_phy_device(struct phy_device *phydev)
--{
--      return phydev->phy_id == RTL_GENERIC_PHYID &&
--             rtlgen_supports_2_5gbps(phydev) &&
--             rtlgen_supports_mmd(phydev);
--}
--
--static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
--                             bool is_c45)
--{
--      if (phydev->is_c45)
--              return is_c45 && (id == phydev->c45_ids.device_ids[1]);
--      else
--              return !is_c45 && (id == phydev->phy_id);
--}
--
--static int rtl8221b_match_phy_device(struct phy_device *phydev)
--{
--      return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
--}
--
--static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
--{
--      return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
--}
--
--static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
--{
--      return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
--}
--
--static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
--{
--      return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
--}
--
--static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
--{
--      return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
--}
--
--static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev)
--{
--      if (phydev->is_c45)
--              return false;
--
--      switch (phydev->phy_id) {
--      case RTL_GENERIC_PHYID:
--      case RTL_8221B:
--      case RTL_8251B:
--      case 0x001cc841:
--              break;
--      default:
--              return false;
--      }
--
--      return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev);
--}
--
--static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
--{
--      return rtlgen_is_c45_match(phydev, RTL_8251B, true);
--}
--
--static int rtlgen_resume(struct phy_device *phydev)
--{
--      int ret = genphy_resume(phydev);
--
--      /* Internal PHY's from RTL8168h up may not be instantly ready */
--      msleep(20);
--
--      return ret;
--}
--
--static int rtlgen_c45_resume(struct phy_device *phydev)
--{
--      int ret = genphy_c45_pma_resume(phydev);
--
--      msleep(20);
--
--      return ret;
--}
--
--static int rtl9000a_config_init(struct phy_device *phydev)
--{
--      phydev->autoneg = AUTONEG_DISABLE;
--      phydev->speed = SPEED_100;
--      phydev->duplex = DUPLEX_FULL;
--
--      return 0;
--}
--
--static int rtl9000a_config_aneg(struct phy_device *phydev)
--{
--      int ret;
--      u16 ctl = 0;
--
--      switch (phydev->master_slave_set) {
--      case MASTER_SLAVE_CFG_MASTER_FORCE:
--              ctl |= CTL1000_AS_MASTER;
--              break;
--      case MASTER_SLAVE_CFG_SLAVE_FORCE:
--              break;
--      case MASTER_SLAVE_CFG_UNKNOWN:
--      case MASTER_SLAVE_CFG_UNSUPPORTED:
--              return 0;
--      default:
--              phydev_warn(phydev, "Unsupported Master/Slave mode\n");
--              return -EOPNOTSUPP;
--      }
--
--      ret = phy_modify_changed(phydev, MII_CTRL1000, CTL1000_AS_MASTER, ctl);
--      if (ret == 1)
--              ret = genphy_soft_reset(phydev);
--
--      return ret;
--}
--
--static int rtl9000a_read_status(struct phy_device *phydev)
--{
--      int ret;
--
--      phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
--      phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
--
--      ret = genphy_update_link(phydev);
--      if (ret)
--              return ret;
--
--      ret = phy_read(phydev, MII_CTRL1000);
--      if (ret < 0)
--              return ret;
--      if (ret & CTL1000_AS_MASTER)
--              phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;
--      else
--              phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;
--
--      ret = phy_read(phydev, MII_STAT1000);
--      if (ret < 0)
--              return ret;
--      if (ret & LPA_1000MSRES)
--              phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
--      else
--              phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
--
--      return 0;
--}
--
--static int rtl9000a_ack_interrupt(struct phy_device *phydev)
--{
--      int err;
--
--      err = phy_read(phydev, RTL8211F_INSR);
--
--      return (err < 0) ? err : 0;
--}
--
--static int rtl9000a_config_intr(struct phy_device *phydev)
--{
--      u16 val;
--      int err;
--
--      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
--              err = rtl9000a_ack_interrupt(phydev);
--              if (err)
--                      return err;
--
--              val = (u16)~RTL9000A_GINMR_LINK_STATUS;
--              err = phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
--      } else {
--              val = ~0;
--              err = phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
--              if (err)
--                      return err;
--
--              err = rtl9000a_ack_interrupt(phydev);
--      }
--
--      return phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
--}
--
--static irqreturn_t rtl9000a_handle_interrupt(struct phy_device *phydev)
--{
--      int irq_status;
--
--      irq_status = phy_read(phydev, RTL8211F_INSR);
--      if (irq_status < 0) {
--              phy_error(phydev);
--              return IRQ_NONE;
--      }
--
--      if (!(irq_status & RTL8211F_INER_LINK_STATUS))
--              return IRQ_NONE;
--
--      phy_trigger_machine(phydev);
--
--      return IRQ_HANDLED;
--}
--
--static struct phy_driver realtek_drvs[] = {
--      {
--              PHY_ID_MATCH_EXACT(0x00008201),
--              .name           = "RTL8201CP Ethernet",
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc816),
--              .name           = "RTL8201F Fast Ethernet",
--              .config_intr    = &rtl8201_config_intr,
--              .handle_interrupt = rtl8201_handle_interrupt,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_MODEL(0x001cc880),
--              .name           = "RTL8208 Fast Ethernet",
--              .read_mmd       = genphy_read_mmd_unsupported,
--              .write_mmd      = genphy_write_mmd_unsupported,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc910),
--              .name           = "RTL8211 Gigabit Ethernet",
--              .config_aneg    = rtl8211_config_aneg,
--              .read_mmd       = &genphy_read_mmd_unsupported,
--              .write_mmd      = &genphy_write_mmd_unsupported,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc912),
--              .name           = "RTL8211B Gigabit Ethernet",
--              .config_intr    = &rtl8211b_config_intr,
--              .handle_interrupt = rtl821x_handle_interrupt,
--              .read_mmd       = &genphy_read_mmd_unsupported,
--              .write_mmd      = &genphy_write_mmd_unsupported,
--              .suspend        = rtl8211b_suspend,
--              .resume         = rtl8211b_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc913),
--              .name           = "RTL8211C Gigabit Ethernet",
--              .config_init    = rtl8211c_config_init,
--              .read_mmd       = &genphy_read_mmd_unsupported,
--              .write_mmd      = &genphy_write_mmd_unsupported,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc914),
--              .name           = "RTL8211DN Gigabit Ethernet",
--              .config_intr    = rtl8211e_config_intr,
--              .handle_interrupt = rtl821x_handle_interrupt,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc915),
--              .name           = "RTL8211E Gigabit Ethernet",
--              .config_init    = &rtl8211e_config_init,
--              .config_intr    = &rtl8211e_config_intr,
--              .handle_interrupt = rtl821x_handle_interrupt,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc916),
--              .name           = "RTL8211F Gigabit Ethernet",
--              .probe          = rtl821x_probe,
--              .config_init    = &rtl8211f_config_init,
--              .read_status    = rtlgen_read_status,
--              .config_intr    = &rtl8211f_config_intr,
--              .handle_interrupt = rtl8211f_handle_interrupt,
--              .suspend        = rtl821x_suspend,
--              .resume         = rtl821x_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--              .flags          = PHY_ALWAYS_CALL_SUSPEND,
--              .led_hw_is_supported = rtl8211f_led_hw_is_supported,
--              .led_hw_control_get = rtl8211f_led_hw_control_get,
--              .led_hw_control_set = rtl8211f_led_hw_control_set,
--      }, {
--              PHY_ID_MATCH_EXACT(RTL_8211FVD_PHYID),
--              .name           = "RTL8211F-VD Gigabit Ethernet",
--              .probe          = rtl821x_probe,
--              .config_init    = &rtl8211f_config_init,
--              .read_status    = rtlgen_read_status,
--              .config_intr    = &rtl8211f_config_intr,
--              .handle_interrupt = rtl8211f_handle_interrupt,
--              .suspend        = rtl821x_suspend,
--              .resume         = rtl821x_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--              .flags          = PHY_ALWAYS_CALL_SUSPEND,
--      }, {
--              .name           = "Generic FE-GE Realtek PHY",
--              .match_phy_device = rtlgen_match_phy_device,
--              .read_status    = rtlgen_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--              .read_mmd       = rtlgen_read_mmd,
--              .write_mmd      = rtlgen_write_mmd,
--      }, {
--              .name           = "RTL8226 2.5Gbps PHY",
--              .match_phy_device = rtl8226_match_phy_device,
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .read_status    = rtl822x_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              .match_phy_device = rtl8221b_match_phy_device,
--              .name           = "RTL8226B_RTL8221B 2.5Gbps PHY",
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .config_init    = rtl822xb_config_init,
--              .get_rate_matching = rtl822xb_get_rate_matching,
--              .read_status    = rtl822xb_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc838),
--              .name           = "RTL8226-CG 2.5Gbps PHY",
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .read_status    = rtl822x_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc848),
--              .name           = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .config_init    = rtl822xb_config_init,
--              .get_rate_matching = rtl822xb_get_rate_matching,
--              .read_status    = rtl822xb_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
--              .name           = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .config_init    = rtl822xb_config_init,
--              .get_rate_matching = rtl822xb_get_rate_matching,
--              .read_status    = rtl822xb_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
--              .name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
--              .config_init    = rtl822xb_config_init,
--              .get_rate_matching = rtl822xb_get_rate_matching,
--              .get_features   = rtl822x_c45_get_features,
--              .config_aneg    = rtl822x_c45_config_aneg,
--              .read_status    = rtl822xb_c45_read_status,
--              .suspend        = genphy_c45_pma_suspend,
--              .resume         = rtlgen_c45_resume,
--      }, {
--              .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
--              .name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .config_init    = rtl822xb_config_init,
--              .get_rate_matching = rtl822xb_get_rate_matching,
--              .read_status    = rtl822xb_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
--              .name           = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
--              .config_init    = rtl822xb_config_init,
--              .get_rate_matching = rtl822xb_get_rate_matching,
--              .get_features   = rtl822x_c45_get_features,
--              .config_aneg    = rtl822x_c45_config_aneg,
--              .read_status    = rtl822xb_c45_read_status,
--              .suspend        = genphy_c45_pma_suspend,
--              .resume         = rtlgen_c45_resume,
--      }, {
--              .match_phy_device = rtl8251b_c45_match_phy_device,
--              .name           = "RTL8251B 5Gbps PHY",
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .read_status    = rtl822x_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              .match_phy_device = rtl_internal_nbaset_match_phy_device,
--              .name           = "Realtek Internal NBASE-T PHY",
--              .flags          = PHY_IS_INTERNAL,
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .read_status    = rtl822x_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--              .read_mmd       = rtl822x_read_mmd,
--              .write_mmd      = rtl822x_write_mmd,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001ccad0),
--              .name           = "RTL8224 2.5Gbps PHY",
--              .get_features   = rtl822x_c45_get_features,
--              .config_aneg    = rtl822x_c45_config_aneg,
--              .read_status    = rtl822x_c45_read_status,
--              .suspend        = genphy_c45_pma_suspend,
--              .resume         = rtlgen_c45_resume,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc961),
--              .name           = "RTL8366RB Gigabit Ethernet",
--              .config_init    = &rtl8366rb_config_init,
--              /* These interrupts are handled by the irq controller
--               * embedded inside the RTL8366RB, they get unmasked when the
--               * irq is requested and ACKed by reading the status register,
--               * which is done by the irqchip code.
--               */
--              .config_intr    = genphy_no_config_intr,
--              .handle_interrupt = genphy_handle_interrupt_no_ack,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001ccb00),
--              .name           = "RTL9000AA_RTL9000AN Ethernet",
--              .features       = PHY_BASIC_T1_FEATURES,
--              .config_init    = rtl9000a_config_init,
--              .config_aneg    = rtl9000a_config_aneg,
--              .read_status    = rtl9000a_read_status,
--              .config_intr    = rtl9000a_config_intr,
--              .handle_interrupt = rtl9000a_handle_interrupt,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc942),
--              .name           = "RTL8365MB-VC Gigabit Ethernet",
--              /* Interrupt handling analogous to RTL8366RB */
--              .config_intr    = genphy_no_config_intr,
--              .handle_interrupt = genphy_handle_interrupt_no_ack,
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--      }, {
--              PHY_ID_MATCH_EXACT(0x001cc960),
--              .name           = "RTL8366S Gigabit Ethernet",
--              .suspend        = genphy_suspend,
--              .resume         = genphy_resume,
--              .read_mmd       = genphy_read_mmd_unsupported,
--              .write_mmd      = genphy_write_mmd_unsupported,
--      },
--};
--
--module_phy_driver(realtek_drvs);
--
--static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
--      { PHY_ID_MATCH_VENDOR(0x001cc800) },
--      { }
--};
--
--MODULE_DEVICE_TABLE(mdio, realtek_tbl);
---- /dev/null
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -0,0 +1,1589 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/* drivers/net/phy/realtek.c
-+ *
-+ * Driver for Realtek PHYs
-+ *
-+ * Author: Johnson Leung <r58129@freescale.com>
-+ *
-+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
-+ */
-+#include <linux/bitops.h>
-+#include <linux/of.h>
-+#include <linux/phy.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/clk.h>
-+
-+#define RTL821x_PHYSR                         0x11
-+#define RTL821x_PHYSR_DUPLEX                  BIT(13)
-+#define RTL821x_PHYSR_SPEED                   GENMASK(15, 14)
-+
-+#define RTL821x_INER                          0x12
-+#define RTL8211B_INER_INIT                    0x6400
-+#define RTL8211E_INER_LINK_STATUS             BIT(10)
-+#define RTL8211F_INER_LINK_STATUS             BIT(4)
-+
-+#define RTL821x_INSR                          0x13
-+
-+#define RTL821x_EXT_PAGE_SELECT                       0x1e
-+#define RTL821x_PAGE_SELECT                   0x1f
-+
-+#define RTL8211F_PHYCR1                               0x18
-+#define RTL8211F_PHYCR2                               0x19
-+#define RTL8211F_INSR                         0x1d
-+
-+#define RTL8211F_LEDCR                                0x10
-+#define RTL8211F_LEDCR_MODE                   BIT(15)
-+#define RTL8211F_LEDCR_ACT_TXRX                       BIT(4)
-+#define RTL8211F_LEDCR_LINK_1000              BIT(3)
-+#define RTL8211F_LEDCR_LINK_100                       BIT(1)
-+#define RTL8211F_LEDCR_LINK_10                        BIT(0)
-+#define RTL8211F_LEDCR_MASK                   GENMASK(4, 0)
-+#define RTL8211F_LEDCR_SHIFT                  5
-+
-+#define RTL8211F_TX_DELAY                     BIT(8)
-+#define RTL8211F_RX_DELAY                     BIT(3)
-+
-+#define RTL8211F_ALDPS_PLL_OFF                        BIT(1)
-+#define RTL8211F_ALDPS_ENABLE                 BIT(2)
-+#define RTL8211F_ALDPS_XTAL_OFF                       BIT(12)
-+
-+#define RTL8211E_CTRL_DELAY                   BIT(13)
-+#define RTL8211E_TX_DELAY                     BIT(12)
-+#define RTL8211E_RX_DELAY                     BIT(11)
-+
-+#define RTL8211F_CLKOUT_EN                    BIT(0)
-+
-+#define RTL8201F_ISR                          0x1e
-+#define RTL8201F_ISR_ANERR                    BIT(15)
-+#define RTL8201F_ISR_DUPLEX                   BIT(13)
-+#define RTL8201F_ISR_LINK                     BIT(11)
-+#define RTL8201F_ISR_MASK                     (RTL8201F_ISR_ANERR | \
-+                                               RTL8201F_ISR_DUPLEX | \
-+                                               RTL8201F_ISR_LINK)
-+#define RTL8201F_IER                          0x13
-+
-+#define RTL822X_VND1_SERDES_OPTION                    0x697a
-+#define RTL822X_VND1_SERDES_OPTION_MODE_MASK          GENMASK(5, 0)
-+#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII               0
-+#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX             2
-+
-+#define RTL822X_VND1_SERDES_CTRL3                     0x7580
-+#define RTL822X_VND1_SERDES_CTRL3_MODE_MASK           GENMASK(5, 0)
-+#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII                  0x02
-+#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX              0x16
-+
-+/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
-+ * is set, they cannot be accessed by C45-over-C22.
-+ */
-+#define RTL822X_VND2_GBCR                             0xa412
-+
-+#define RTL822X_VND2_GANLPAR                          0xa414
-+
-+#define RTL8366RB_POWER_SAVE                  0x15
-+#define RTL8366RB_POWER_SAVE_ON                       BIT(12)
-+
-+#define RTL9000A_GINMR                                0x14
-+#define RTL9000A_GINMR_LINK_STATUS            BIT(4)
-+
-+#define RTL_VND2_PHYSR                                0xa434
-+#define RTL_VND2_PHYSR_DUPLEX                 BIT(3)
-+#define RTL_VND2_PHYSR_SPEEDL                 GENMASK(5, 4)
-+#define RTL_VND2_PHYSR_SPEEDH                 GENMASK(10, 9)
-+#define RTL_VND2_PHYSR_MASTER                 BIT(11)
-+#define RTL_VND2_PHYSR_SPEED_MASK             (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
-+
-+#define RTL_GENERIC_PHYID                     0x001cc800
-+#define RTL_8211FVD_PHYID                     0x001cc878
-+#define RTL_8221B                             0x001cc840
-+#define RTL_8221B_VB_CG                               0x001cc849
-+#define RTL_8221B_VN_CG                               0x001cc84a
-+#define RTL_8251B                             0x001cc862
-+
-+#define RTL8211F_LED_COUNT                    3
-+
-+MODULE_DESCRIPTION("Realtek PHY driver");
-+MODULE_AUTHOR("Johnson Leung");
-+MODULE_LICENSE("GPL");
-+
-+struct rtl821x_priv {
-+      u16 phycr1;
-+      u16 phycr2;
-+      bool has_phycr2;
-+      struct clk *clk;
-+};
-+
-+static int rtl821x_read_page(struct phy_device *phydev)
-+{
-+      return __phy_read(phydev, RTL821x_PAGE_SELECT);
-+}
-+
-+static int rtl821x_write_page(struct phy_device *phydev, int page)
-+{
-+      return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
-+}
-+
-+static int rtl821x_probe(struct phy_device *phydev)
-+{
-+      struct device *dev = &phydev->mdio.dev;
-+      struct rtl821x_priv *priv;
-+      u32 phy_id = phydev->drv->phy_id;
-+      int ret;
-+
-+      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+
-+      priv->clk = devm_clk_get_optional_enabled(dev, NULL);
-+      if (IS_ERR(priv->clk))
-+              return dev_err_probe(dev, PTR_ERR(priv->clk),
-+                                   "failed to get phy clock\n");
-+
-+      ret = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR1);
-+      if (ret < 0)
-+              return ret;
-+
-+      priv->phycr1 = ret & (RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF);
-+      if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
-+              priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
-+
-+      priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
-+      if (priv->has_phycr2) {
-+              ret = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR2);
-+              if (ret < 0)
-+                      return ret;
-+
-+              priv->phycr2 = ret & RTL8211F_CLKOUT_EN;
-+              if (of_property_read_bool(dev->of_node, "realtek,clkout-disable"))
-+                      priv->phycr2 &= ~RTL8211F_CLKOUT_EN;
-+      }
-+
-+      phydev->priv = priv;
-+
-+      return 0;
-+}
-+
-+static int rtl8201_ack_interrupt(struct phy_device *phydev)
-+{
-+      int err;
-+
-+      err = phy_read(phydev, RTL8201F_ISR);
-+
-+      return (err < 0) ? err : 0;
-+}
-+
-+static int rtl821x_ack_interrupt(struct phy_device *phydev)
-+{
-+      int err;
-+
-+      err = phy_read(phydev, RTL821x_INSR);
-+
-+      return (err < 0) ? err : 0;
-+}
-+
-+static int rtl8211f_ack_interrupt(struct phy_device *phydev)
-+{
-+      int err;
-+
-+      err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
-+
-+      return (err < 0) ? err : 0;
-+}
-+
-+static int rtl8201_config_intr(struct phy_device *phydev)
-+{
-+      u16 val;
-+      int err;
-+
-+      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+              err = rtl8201_ack_interrupt(phydev);
-+              if (err)
-+                      return err;
-+
-+              val = BIT(13) | BIT(12) | BIT(11);
-+              err = phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
-+      } else {
-+              val = 0;
-+              err = phy_write_paged(phydev, 0x7, RTL8201F_IER, val);
-+              if (err)
-+                      return err;
-+
-+              err = rtl8201_ack_interrupt(phydev);
-+      }
-+
-+      return err;
-+}
-+
-+static int rtl8211b_config_intr(struct phy_device *phydev)
-+{
-+      int err;
-+
-+      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+              err = rtl821x_ack_interrupt(phydev);
-+              if (err)
-+                      return err;
-+
-+              err = phy_write(phydev, RTL821x_INER,
-+                              RTL8211B_INER_INIT);
-+      } else {
-+              err = phy_write(phydev, RTL821x_INER, 0);
-+              if (err)
-+                      return err;
-+
-+              err = rtl821x_ack_interrupt(phydev);
-+      }
-+
-+      return err;
-+}
-+
-+static int rtl8211e_config_intr(struct phy_device *phydev)
-+{
-+      int err;
-+
-+      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+              err = rtl821x_ack_interrupt(phydev);
-+              if (err)
-+                      return err;
-+
-+              err = phy_write(phydev, RTL821x_INER,
-+                              RTL8211E_INER_LINK_STATUS);
-+      } else {
-+              err = phy_write(phydev, RTL821x_INER, 0);
-+              if (err)
-+                      return err;
-+
-+              err = rtl821x_ack_interrupt(phydev);
-+      }
-+
-+      return err;
-+}
-+
-+static int rtl8211f_config_intr(struct phy_device *phydev)
-+{
-+      u16 val;
-+      int err;
-+
-+      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+              err = rtl8211f_ack_interrupt(phydev);
-+              if (err)
-+                      return err;
-+
-+              val = RTL8211F_INER_LINK_STATUS;
-+              err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
-+      } else {
-+              val = 0;
-+              err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
-+              if (err)
-+                      return err;
-+
-+              err = rtl8211f_ack_interrupt(phydev);
-+      }
-+
-+      return err;
-+}
-+
-+static irqreturn_t rtl8201_handle_interrupt(struct phy_device *phydev)
-+{
-+      int irq_status;
-+
-+      irq_status = phy_read(phydev, RTL8201F_ISR);
-+      if (irq_status < 0) {
-+              phy_error(phydev);
-+              return IRQ_NONE;
-+      }
-+
-+      if (!(irq_status & RTL8201F_ISR_MASK))
-+              return IRQ_NONE;
-+
-+      phy_trigger_machine(phydev);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t rtl821x_handle_interrupt(struct phy_device *phydev)
-+{
-+      int irq_status, irq_enabled;
-+
-+      irq_status = phy_read(phydev, RTL821x_INSR);
-+      if (irq_status < 0) {
-+              phy_error(phydev);
-+              return IRQ_NONE;
-+      }
-+
-+      irq_enabled = phy_read(phydev, RTL821x_INER);
-+      if (irq_enabled < 0) {
-+              phy_error(phydev);
-+              return IRQ_NONE;
-+      }
-+
-+      if (!(irq_status & irq_enabled))
-+              return IRQ_NONE;
-+
-+      phy_trigger_machine(phydev);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev)
-+{
-+      int irq_status;
-+
-+      irq_status = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
-+      if (irq_status < 0) {
-+              phy_error(phydev);
-+              return IRQ_NONE;
-+      }
-+
-+      if (!(irq_status & RTL8211F_INER_LINK_STATUS))
-+              return IRQ_NONE;
-+
-+      phy_trigger_machine(phydev);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static int rtl8211_config_aneg(struct phy_device *phydev)
-+{
-+      int ret;
-+
-+      ret = genphy_config_aneg(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Quirk was copied from vendor driver. Unfortunately it includes no
-+       * description of the magic numbers.
-+       */
-+      if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) {
-+              phy_write(phydev, 0x17, 0x2138);
-+              phy_write(phydev, 0x0e, 0x0260);
-+      } else {
-+              phy_write(phydev, 0x17, 0x2108);
-+              phy_write(phydev, 0x0e, 0x0000);
-+      }
-+
-+      return 0;
-+}
-+
-+static int rtl8211c_config_init(struct phy_device *phydev)
-+{
-+      /* RTL8211C has an issue when operating in Gigabit slave mode */
-+      return phy_set_bits(phydev, MII_CTRL1000,
-+                          CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
-+}
-+
-+static int rtl8211f_config_init(struct phy_device *phydev)
-+{
-+      struct rtl821x_priv *priv = phydev->priv;
-+      struct device *dev = &phydev->mdio.dev;
-+      u16 val_txdly, val_rxdly;
-+      int ret;
-+
-+      ret = phy_modify_paged_changed(phydev, 0xa43, RTL8211F_PHYCR1,
-+                                     RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
-+                                     priv->phycr1);
-+      if (ret < 0) {
-+              dev_err(dev, "aldps mode  configuration failed: %pe\n",
-+                      ERR_PTR(ret));
-+              return ret;
-+      }
-+
-+      switch (phydev->interface) {
-+      case PHY_INTERFACE_MODE_RGMII:
-+              val_txdly = 0;
-+              val_rxdly = 0;
-+              break;
-+
-+      case PHY_INTERFACE_MODE_RGMII_RXID:
-+              val_txdly = 0;
-+              val_rxdly = RTL8211F_RX_DELAY;
-+              break;
-+
-+      case PHY_INTERFACE_MODE_RGMII_TXID:
-+              val_txdly = RTL8211F_TX_DELAY;
-+              val_rxdly = 0;
-+              break;
-+
-+      case PHY_INTERFACE_MODE_RGMII_ID:
-+              val_txdly = RTL8211F_TX_DELAY;
-+              val_rxdly = RTL8211F_RX_DELAY;
-+              break;
-+
-+      default: /* the rest of the modes imply leaving delay as is. */
-+              return 0;
-+      }
-+
-+      ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
-+                                     val_txdly);
-+      if (ret < 0) {
-+              dev_err(dev, "Failed to update the TX delay register\n");
-+              return ret;
-+      } else if (ret) {
-+              dev_dbg(dev,
-+                      "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
-+                      val_txdly ? "Enabling" : "Disabling");
-+      } else {
-+              dev_dbg(dev,
-+                      "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
-+                      val_txdly ? "enabled" : "disabled");
-+      }
-+
-+      ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
-+                                     val_rxdly);
-+      if (ret < 0) {
-+              dev_err(dev, "Failed to update the RX delay register\n");
-+              return ret;
-+      } else if (ret) {
-+              dev_dbg(dev,
-+                      "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
-+                      val_rxdly ? "Enabling" : "Disabling");
-+      } else {
-+              dev_dbg(dev,
-+                      "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
-+                      val_rxdly ? "enabled" : "disabled");
-+      }
-+
-+      if (priv->has_phycr2) {
-+              ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2,
-+                                     RTL8211F_CLKOUT_EN, priv->phycr2);
-+              if (ret < 0) {
-+                      dev_err(dev, "clkout configuration failed: %pe\n",
-+                              ERR_PTR(ret));
-+                      return ret;
-+              }
-+
-+              return genphy_soft_reset(phydev);
-+      }
-+
-+      return 0;
-+}
-+
-+static int rtl821x_suspend(struct phy_device *phydev)
-+{
-+      struct rtl821x_priv *priv = phydev->priv;
-+      int ret = 0;
-+
-+      if (!phydev->wol_enabled) {
-+              ret = genphy_suspend(phydev);
-+
-+              if (ret)
-+                      return ret;
-+
-+              clk_disable_unprepare(priv->clk);
-+      }
-+
-+      return ret;
-+}
-+
-+static int rtl821x_resume(struct phy_device *phydev)
-+{
-+      struct rtl821x_priv *priv = phydev->priv;
-+      int ret;
-+
-+      if (!phydev->wol_enabled)
-+              clk_prepare_enable(priv->clk);
-+
-+      ret = genphy_resume(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      msleep(20);
-+
-+      return 0;
-+}
-+
-+static int rtl8211f_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+                                      unsigned long rules)
-+{
-+      const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) |
-+                                 BIT(TRIGGER_NETDEV_LINK_100) |
-+                                 BIT(TRIGGER_NETDEV_LINK_1000) |
-+                                 BIT(TRIGGER_NETDEV_RX) |
-+                                 BIT(TRIGGER_NETDEV_TX);
-+
-+      /* The RTL8211F PHY supports these LED settings on up to three LEDs:
-+       * - Link: Configurable subset of 10/100/1000 link rates
-+       * - Active: Blink on activity, RX or TX is not differentiated
-+       * The Active option has two modes, A and B:
-+       * - A: Link and Active indication at configurable, but matching,
-+       *      subset of 10/100/1000 link rates
-+       * - B: Link indication at configurable subset of 10/100/1000 link
-+       *      rates and Active indication always at all three 10+100+1000
-+       *      link rates.
-+       * This code currently uses mode B only.
-+       */
-+
-+      if (index >= RTL8211F_LED_COUNT)
-+              return -EINVAL;
-+
-+      /* Filter out any other unsupported triggers. */
-+      if (rules & ~mask)
-+              return -EOPNOTSUPP;
-+
-+      /* RX and TX are not differentiated, either both are set or not set. */
-+      if (!(rules & BIT(TRIGGER_NETDEV_RX)) ^ !(rules & BIT(TRIGGER_NETDEV_TX)))
-+              return -EOPNOTSUPP;
-+
-+      return 0;
-+}
-+
-+static int rtl8211f_led_hw_control_get(struct phy_device *phydev, u8 index,
-+                                     unsigned long *rules)
-+{
-+      int val;
-+
-+      if (index >= RTL8211F_LED_COUNT)
-+              return -EINVAL;
-+
-+      val = phy_read_paged(phydev, 0xd04, RTL8211F_LEDCR);
-+      if (val < 0)
-+              return val;
-+
-+      val >>= RTL8211F_LEDCR_SHIFT * index;
-+      val &= RTL8211F_LEDCR_MASK;
-+
-+      if (val & RTL8211F_LEDCR_LINK_10)
-+              set_bit(TRIGGER_NETDEV_LINK_10, rules);
-+
-+      if (val & RTL8211F_LEDCR_LINK_100)
-+              set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+
-+      if (val & RTL8211F_LEDCR_LINK_1000)
-+              set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+
-+      if (val & RTL8211F_LEDCR_ACT_TXRX) {
-+              set_bit(TRIGGER_NETDEV_RX, rules);
-+              set_bit(TRIGGER_NETDEV_TX, rules);
-+      }
-+
-+      return 0;
-+}
-+
-+static int rtl8211f_led_hw_control_set(struct phy_device *phydev, u8 index,
-+                                     unsigned long rules)
-+{
-+      const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
-+      u16 reg = 0;
-+
-+      if (index >= RTL8211F_LED_COUNT)
-+              return -EINVAL;
-+
-+      if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+              reg |= RTL8211F_LEDCR_LINK_10;
-+
-+      if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+              reg |= RTL8211F_LEDCR_LINK_100;
-+
-+      if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+              reg |= RTL8211F_LEDCR_LINK_1000;
-+
-+      if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
-+          test_bit(TRIGGER_NETDEV_TX, &rules)) {
-+              reg |= RTL8211F_LEDCR_ACT_TXRX;
-+      }
-+
-+      reg <<= RTL8211F_LEDCR_SHIFT * index;
-+      reg |= RTL8211F_LEDCR_MODE;      /* Mode B */
-+
-+      return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
-+}
-+
-+static int rtl8211e_config_init(struct phy_device *phydev)
-+{
-+      int ret = 0, oldpage;
-+      u16 val;
-+
-+      /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
-+      switch (phydev->interface) {
-+      case PHY_INTERFACE_MODE_RGMII:
-+              val = RTL8211E_CTRL_DELAY | 0;
-+              break;
-+      case PHY_INTERFACE_MODE_RGMII_ID:
-+              val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
-+              break;
-+      case PHY_INTERFACE_MODE_RGMII_RXID:
-+              val = RTL8211E_CTRL_DELAY | RTL8211E_RX_DELAY;
-+              break;
-+      case PHY_INTERFACE_MODE_RGMII_TXID:
-+              val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY;
-+              break;
-+      default: /* the rest of the modes imply leaving delays as is. */
-+              return 0;
-+      }
-+
-+      /* According to a sample driver there is a 0x1c config register on the
-+       * 0xa4 extension page (0x7) layout. It can be used to disable/enable
-+       * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins.
-+       * The configuration register definition:
-+       * 14 = reserved
-+       * 13 = Force Tx RX Delay controlled by bit12 bit11,
-+       * 12 = RX Delay, 11 = TX Delay
-+       * 10:0 = Test && debug settings reserved by realtek
-+       */
-+      oldpage = phy_select_page(phydev, 0x7);
-+      if (oldpage < 0)
-+              goto err_restore_page;
-+
-+      ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
-+      if (ret)
-+              goto err_restore_page;
-+
-+      ret = __phy_modify(phydev, 0x1c, RTL8211E_CTRL_DELAY
-+                         | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
-+                         val);
-+
-+err_restore_page:
-+      return phy_restore_page(phydev, oldpage, ret);
-+}
-+
-+static int rtl8211b_suspend(struct phy_device *phydev)
-+{
-+      phy_write(phydev, MII_MMD_DATA, BIT(9));
-+
-+      return genphy_suspend(phydev);
-+}
-+
-+static int rtl8211b_resume(struct phy_device *phydev)
-+{
-+      phy_write(phydev, MII_MMD_DATA, 0);
-+
-+      return genphy_resume(phydev);
-+}
-+
-+static int rtl8366rb_config_init(struct phy_device *phydev)
-+{
-+      int ret;
-+
-+      ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
-+                         RTL8366RB_POWER_SAVE_ON);
-+      if (ret) {
-+              dev_err(&phydev->mdio.dev,
-+                      "error enabling power management\n");
-+      }
-+
-+      return ret;
-+}
-+
-+/* get actual speed to cover the downshift case */
-+static void rtlgen_decode_physr(struct phy_device *phydev, int val)
-+{
-+      /* bit 3
-+       * 0: Half Duplex
-+       * 1: Full Duplex
-+       */
-+      if (val & RTL_VND2_PHYSR_DUPLEX)
-+              phydev->duplex = DUPLEX_FULL;
-+      else
-+              phydev->duplex = DUPLEX_HALF;
-+
-+      switch (val & RTL_VND2_PHYSR_SPEED_MASK) {
-+      case 0x0000:
-+              phydev->speed = SPEED_10;
-+              break;
-+      case 0x0010:
-+              phydev->speed = SPEED_100;
-+              break;
-+      case 0x0020:
-+              phydev->speed = SPEED_1000;
-+              break;
-+      case 0x0200:
-+              phydev->speed = SPEED_10000;
-+              break;
-+      case 0x0210:
-+              phydev->speed = SPEED_2500;
-+              break;
-+      case 0x0220:
-+              phydev->speed = SPEED_5000;
-+              break;
-+      default:
-+              break;
-+      }
-+
-+      /* bit 11
-+       * 0: Slave Mode
-+       * 1: Master Mode
-+       */
-+      if (phydev->speed >= 1000) {
-+              if (val & RTL_VND2_PHYSR_MASTER)
-+                      phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
-+              else
-+                      phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
-+      } else {
-+              phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
-+      }
-+}
-+
-+static int rtlgen_read_status(struct phy_device *phydev)
-+{
-+      int ret, val;
-+
-+      ret = genphy_read_status(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (!phydev->link)
-+              return 0;
-+
-+      val = phy_read_paged(phydev, 0xa43, 0x12);
-+      if (val < 0)
-+              return val;
-+
-+      rtlgen_decode_physr(phydev, val);
-+
-+      return 0;
-+}
-+
-+static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
-+{
-+      int ret;
-+
-+      if (devnum == MDIO_MMD_VEND2) {
-+              rtl821x_write_page(phydev, regnum >> 4);
-+              ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1));
-+              rtl821x_write_page(phydev, 0);
-+      } else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
-+              rtl821x_write_page(phydev, 0xa5c);
-+              ret = __phy_read(phydev, 0x12);
-+              rtl821x_write_page(phydev, 0);
-+      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
-+              rtl821x_write_page(phydev, 0xa5d);
-+              ret = __phy_read(phydev, 0x10);
-+              rtl821x_write_page(phydev, 0);
-+      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
-+              rtl821x_write_page(phydev, 0xa5d);
-+              ret = __phy_read(phydev, 0x11);
-+              rtl821x_write_page(phydev, 0);
-+      } else {
-+              ret = -EOPNOTSUPP;
-+      }
-+
-+      return ret;
-+}
-+
-+static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
-+                          u16 val)
-+{
-+      int ret;
-+
-+      if (devnum == MDIO_MMD_VEND2) {
-+              rtl821x_write_page(phydev, regnum >> 4);
-+              ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val);
-+              rtl821x_write_page(phydev, 0);
-+      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
-+              rtl821x_write_page(phydev, 0xa5d);
-+              ret = __phy_write(phydev, 0x10, val);
-+              rtl821x_write_page(phydev, 0);
-+      } else {
-+              ret = -EOPNOTSUPP;
-+      }
-+
-+      return ret;
-+}
-+
-+static int rtl822x_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
-+{
-+      int ret = rtlgen_read_mmd(phydev, devnum, regnum);
-+
-+      if (ret != -EOPNOTSUPP)
-+              return ret;
-+
-+      if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
-+              rtl821x_write_page(phydev, 0xa6e);
-+              ret = __phy_read(phydev, 0x16);
-+              rtl821x_write_page(phydev, 0);
-+      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
-+              rtl821x_write_page(phydev, 0xa6d);
-+              ret = __phy_read(phydev, 0x12);
-+              rtl821x_write_page(phydev, 0);
-+      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
-+              rtl821x_write_page(phydev, 0xa6d);
-+              ret = __phy_read(phydev, 0x10);
-+              rtl821x_write_page(phydev, 0);
-+      }
-+
-+      return ret;
-+}
-+
-+static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
-+                           u16 val)
-+{
-+      int ret = rtlgen_write_mmd(phydev, devnum, regnum, val);
-+
-+      if (ret != -EOPNOTSUPP)
-+              return ret;
-+
-+      if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
-+              rtl821x_write_page(phydev, 0xa6d);
-+              ret = __phy_write(phydev, 0x12, val);
-+              rtl821x_write_page(phydev, 0);
-+      }
-+
-+      return ret;
-+}
-+
-+static int rtl822xb_config_init(struct phy_device *phydev)
-+{
-+      bool has_2500, has_sgmii;
-+      u16 mode;
-+      int ret;
-+
-+      has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
-+                          phydev->host_interfaces) ||
-+                 phydev->interface == PHY_INTERFACE_MODE_2500BASEX;
-+
-+      has_sgmii = test_bit(PHY_INTERFACE_MODE_SGMII,
-+                           phydev->host_interfaces) ||
-+                  phydev->interface == PHY_INTERFACE_MODE_SGMII;
-+
-+      /* fill in possible interfaces */
-+      __assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
-+                   has_2500);
-+      __assign_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces,
-+                   has_sgmii);
-+
-+      if (!has_2500 && !has_sgmii)
-+              return 0;
-+
-+      /* determine SerDes option mode */
-+      if (has_2500 && !has_sgmii) {
-+              mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX;
-+              phydev->rate_matching = RATE_MATCH_PAUSE;
-+      } else {
-+              mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII;
-+              phydev->rate_matching = RATE_MATCH_NONE;
-+      }
-+
-+      /* the following sequence with magic numbers sets up the SerDes
-+       * option mode
-+       */
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
-+      if (ret < 0)
-+              return ret;
-+
-+      ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1,
-+                                   RTL822X_VND1_SERDES_OPTION,
-+                                   RTL822X_VND1_SERDES_OPTION_MODE_MASK,
-+                                   mode);
-+      if (ret < 0)
-+              return ret;
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
-+      if (ret < 0)
-+              return ret;
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
-+      if (ret < 0)
-+              return ret;
-+
-+      return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
-+}
-+
-+static int rtl822xb_get_rate_matching(struct phy_device *phydev,
-+                                    phy_interface_t iface)
-+{
-+      int val;
-+
-+      /* Only rate matching at 2500base-x */
-+      if (iface != PHY_INTERFACE_MODE_2500BASEX)
-+              return RATE_MATCH_NONE;
-+
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_OPTION);
-+      if (val < 0)
-+              return val;
-+
-+      if ((val & RTL822X_VND1_SERDES_OPTION_MODE_MASK) ==
-+          RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX)
-+              return RATE_MATCH_PAUSE;
-+
-+      /* RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII */
-+      return RATE_MATCH_NONE;
-+}
-+
-+static int rtl822x_get_features(struct phy_device *phydev)
-+{
-+      int val;
-+
-+      val = phy_read_paged(phydev, 0xa61, 0x13);
-+      if (val < 0)
-+              return val;
-+
-+      linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-+                       phydev->supported, val & MDIO_PMA_SPEED_2_5G);
-+      linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-+                       phydev->supported, val & MDIO_PMA_SPEED_5G);
-+      linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
-+                       phydev->supported, val & MDIO_SPEED_10G);
-+
-+      return genphy_read_abilities(phydev);
-+}
-+
-+static int rtl822x_config_aneg(struct phy_device *phydev)
-+{
-+      int ret = 0;
-+
-+      if (phydev->autoneg == AUTONEG_ENABLE) {
-+              u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
-+
-+              ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
-+                                             MDIO_AN_10GBT_CTRL_ADV2_5G |
-+                                             MDIO_AN_10GBT_CTRL_ADV5G,
-+                                             adv);
-+              if (ret < 0)
-+                      return ret;
-+      }
-+
-+      return __genphy_config_aneg(phydev, ret);
-+}
-+
-+static void rtl822xb_update_interface(struct phy_device *phydev)
-+{
-+      int val;
-+
-+      if (!phydev->link)
-+              return;
-+
-+      /* Change interface according to serdes mode */
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CTRL3);
-+      if (val < 0)
-+              return;
-+
-+      switch (val & RTL822X_VND1_SERDES_CTRL3_MODE_MASK) {
-+      case RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX:
-+              phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+              break;
-+      case RTL822X_VND1_SERDES_CTRL3_MODE_SGMII:
-+              phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+              break;
-+      }
-+}
-+
-+static int rtl822x_read_status(struct phy_device *phydev)
-+{
-+      int lpadv, ret;
-+
-+      mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
-+
-+      ret = rtlgen_read_status(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (phydev->autoneg == AUTONEG_DISABLE ||
-+          !phydev->autoneg_complete)
-+              return 0;
-+
-+      lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
-+      if (lpadv < 0)
-+              return lpadv;
-+
-+      mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
-+
-+      return 0;
-+}
-+
-+static int rtl822xb_read_status(struct phy_device *phydev)
-+{
-+      int ret;
-+
-+      ret = rtl822x_read_status(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      rtl822xb_update_interface(phydev);
-+
-+      return 0;
-+}
-+
-+static int rtl822x_c45_get_features(struct phy_device *phydev)
-+{
-+      linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
-+                       phydev->supported);
-+
-+      return genphy_c45_pma_read_abilities(phydev);
-+}
-+
-+static int rtl822x_c45_config_aneg(struct phy_device *phydev)
-+{
-+      bool changed = false;
-+      int ret, val;
-+
-+      if (phydev->autoneg == AUTONEG_DISABLE)
-+              return genphy_c45_pma_setup_forced(phydev);
-+
-+      ret = genphy_c45_an_config_aneg(phydev);
-+      if (ret < 0)
-+              return ret;
-+      if (ret > 0)
-+              changed = true;
-+
-+      val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
-+
-+      /* Vendor register as C45 has no standardized support for 1000BaseT */
-+      ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR,
-+                                   ADVERTISE_1000FULL, val);
-+      if (ret < 0)
-+              return ret;
-+      if (ret > 0)
-+              changed = true;
-+
-+      return genphy_c45_check_and_restart_aneg(phydev, changed);
-+}
-+
-+static int rtl822x_c45_read_status(struct phy_device *phydev)
-+{
-+      int ret, val;
-+
-+      /* Vendor register as C45 has no standardized support for 1000BaseT */
-+      if (phydev->autoneg == AUTONEG_ENABLE && genphy_c45_aneg_done(phydev)) {
-+              val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
-+                                 RTL822X_VND2_GANLPAR);
-+              if (val < 0)
-+                      return val;
-+      } else {
-+              val = 0;
-+      }
-+      mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
-+
-+      ret = genphy_c45_read_status(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (!phydev->link) {
-+              phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
-+              return 0;
-+      }
-+
-+      /* Read actual speed from vendor register. */
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
-+      if (val < 0)
-+              return val;
-+
-+      rtlgen_decode_physr(phydev, val);
-+
-+      return 0;
-+}
-+
-+static int rtl822xb_c45_read_status(struct phy_device *phydev)
-+{
-+      int ret;
-+
-+      ret = rtl822x_c45_read_status(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      rtl822xb_update_interface(phydev);
-+
-+      return 0;
-+}
-+
-+static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
-+{
-+      int val;
-+
-+      phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
-+      val = phy_read(phydev, 0x13);
-+      phy_write(phydev, RTL821x_PAGE_SELECT, 0);
-+
-+      return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
-+}
-+
-+/* On internal PHY's MMD reads over C22 always return 0.
-+ * Check a MMD register which is known to be non-zero.
-+ */
-+static bool rtlgen_supports_mmd(struct phy_device *phydev)
-+{
-+      int val;
-+
-+      phy_lock_mdio_bus(phydev);
-+      __phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS);
-+      __phy_write(phydev, MII_MMD_DATA, MDIO_PCS_EEE_ABLE);
-+      __phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS | MII_MMD_CTRL_NOINCR);
-+      val = __phy_read(phydev, MII_MMD_DATA);
-+      phy_unlock_mdio_bus(phydev);
-+
-+      return val > 0;
-+}
-+
-+static int rtlgen_match_phy_device(struct phy_device *phydev)
-+{
-+      return phydev->phy_id == RTL_GENERIC_PHYID &&
-+             !rtlgen_supports_2_5gbps(phydev);
-+}
-+
-+static int rtl8226_match_phy_device(struct phy_device *phydev)
-+{
-+      return phydev->phy_id == RTL_GENERIC_PHYID &&
-+             rtlgen_supports_2_5gbps(phydev) &&
-+             rtlgen_supports_mmd(phydev);
-+}
-+
-+static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
-+                             bool is_c45)
-+{
-+      if (phydev->is_c45)
-+              return is_c45 && (id == phydev->c45_ids.device_ids[1]);
-+      else
-+              return !is_c45 && (id == phydev->phy_id);
-+}
-+
-+static int rtl8221b_match_phy_device(struct phy_device *phydev)
-+{
-+      return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
-+}
-+
-+static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
-+{
-+      return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
-+}
-+
-+static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
-+{
-+      return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
-+}
-+
-+static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
-+{
-+      return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
-+}
-+
-+static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
-+{
-+      return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
-+}
-+
-+static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev)
-+{
-+      if (phydev->is_c45)
-+              return false;
-+
-+      switch (phydev->phy_id) {
-+      case RTL_GENERIC_PHYID:
-+      case RTL_8221B:
-+      case RTL_8251B:
-+      case 0x001cc841:
-+              break;
-+      default:
-+              return false;
-+      }
-+
-+      return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev);
-+}
-+
-+static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
-+{
-+      return rtlgen_is_c45_match(phydev, RTL_8251B, true);
-+}
-+
-+static int rtlgen_resume(struct phy_device *phydev)
-+{
-+      int ret = genphy_resume(phydev);
-+
-+      /* Internal PHY's from RTL8168h up may not be instantly ready */
-+      msleep(20);
-+
-+      return ret;
-+}
-+
-+static int rtlgen_c45_resume(struct phy_device *phydev)
-+{
-+      int ret = genphy_c45_pma_resume(phydev);
-+
-+      msleep(20);
-+
-+      return ret;
-+}
-+
-+static int rtl9000a_config_init(struct phy_device *phydev)
-+{
-+      phydev->autoneg = AUTONEG_DISABLE;
-+      phydev->speed = SPEED_100;
-+      phydev->duplex = DUPLEX_FULL;
-+
-+      return 0;
-+}
-+
-+static int rtl9000a_config_aneg(struct phy_device *phydev)
-+{
-+      int ret;
-+      u16 ctl = 0;
-+
-+      switch (phydev->master_slave_set) {
-+      case MASTER_SLAVE_CFG_MASTER_FORCE:
-+              ctl |= CTL1000_AS_MASTER;
-+              break;
-+      case MASTER_SLAVE_CFG_SLAVE_FORCE:
-+              break;
-+      case MASTER_SLAVE_CFG_UNKNOWN:
-+      case MASTER_SLAVE_CFG_UNSUPPORTED:
-+              return 0;
-+      default:
-+              phydev_warn(phydev, "Unsupported Master/Slave mode\n");
-+              return -EOPNOTSUPP;
-+      }
-+
-+      ret = phy_modify_changed(phydev, MII_CTRL1000, CTL1000_AS_MASTER, ctl);
-+      if (ret == 1)
-+              ret = genphy_soft_reset(phydev);
-+
-+      return ret;
-+}
-+
-+static int rtl9000a_read_status(struct phy_device *phydev)
-+{
-+      int ret;
-+
-+      phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
-+      phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
-+
-+      ret = genphy_update_link(phydev);
-+      if (ret)
-+              return ret;
-+
-+      ret = phy_read(phydev, MII_CTRL1000);
-+      if (ret < 0)
-+              return ret;
-+      if (ret & CTL1000_AS_MASTER)
-+              phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;
-+      else
-+              phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;
-+
-+      ret = phy_read(phydev, MII_STAT1000);
-+      if (ret < 0)
-+              return ret;
-+      if (ret & LPA_1000MSRES)
-+              phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
-+      else
-+              phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
-+
-+      return 0;
-+}
-+
-+static int rtl9000a_ack_interrupt(struct phy_device *phydev)
-+{
-+      int err;
-+
-+      err = phy_read(phydev, RTL8211F_INSR);
-+
-+      return (err < 0) ? err : 0;
-+}
-+
-+static int rtl9000a_config_intr(struct phy_device *phydev)
-+{
-+      u16 val;
-+      int err;
-+
-+      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+              err = rtl9000a_ack_interrupt(phydev);
-+              if (err)
-+                      return err;
-+
-+              val = (u16)~RTL9000A_GINMR_LINK_STATUS;
-+              err = phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
-+      } else {
-+              val = ~0;
-+              err = phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
-+              if (err)
-+                      return err;
-+
-+              err = rtl9000a_ack_interrupt(phydev);
-+      }
-+
-+      return phy_write_paged(phydev, 0xa42, RTL9000A_GINMR, val);
-+}
-+
-+static irqreturn_t rtl9000a_handle_interrupt(struct phy_device *phydev)
-+{
-+      int irq_status;
-+
-+      irq_status = phy_read(phydev, RTL8211F_INSR);
-+      if (irq_status < 0) {
-+              phy_error(phydev);
-+              return IRQ_NONE;
-+      }
-+
-+      if (!(irq_status & RTL8211F_INER_LINK_STATUS))
-+              return IRQ_NONE;
-+
-+      phy_trigger_machine(phydev);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static struct phy_driver realtek_drvs[] = {
-+      {
-+              PHY_ID_MATCH_EXACT(0x00008201),
-+              .name           = "RTL8201CP Ethernet",
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc816),
-+              .name           = "RTL8201F Fast Ethernet",
-+              .config_intr    = &rtl8201_config_intr,
-+              .handle_interrupt = rtl8201_handle_interrupt,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_MODEL(0x001cc880),
-+              .name           = "RTL8208 Fast Ethernet",
-+              .read_mmd       = genphy_read_mmd_unsupported,
-+              .write_mmd      = genphy_write_mmd_unsupported,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc910),
-+              .name           = "RTL8211 Gigabit Ethernet",
-+              .config_aneg    = rtl8211_config_aneg,
-+              .read_mmd       = &genphy_read_mmd_unsupported,
-+              .write_mmd      = &genphy_write_mmd_unsupported,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc912),
-+              .name           = "RTL8211B Gigabit Ethernet",
-+              .config_intr    = &rtl8211b_config_intr,
-+              .handle_interrupt = rtl821x_handle_interrupt,
-+              .read_mmd       = &genphy_read_mmd_unsupported,
-+              .write_mmd      = &genphy_write_mmd_unsupported,
-+              .suspend        = rtl8211b_suspend,
-+              .resume         = rtl8211b_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc913),
-+              .name           = "RTL8211C Gigabit Ethernet",
-+              .config_init    = rtl8211c_config_init,
-+              .read_mmd       = &genphy_read_mmd_unsupported,
-+              .write_mmd      = &genphy_write_mmd_unsupported,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc914),
-+              .name           = "RTL8211DN Gigabit Ethernet",
-+              .config_intr    = rtl8211e_config_intr,
-+              .handle_interrupt = rtl821x_handle_interrupt,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc915),
-+              .name           = "RTL8211E Gigabit Ethernet",
-+              .config_init    = &rtl8211e_config_init,
-+              .config_intr    = &rtl8211e_config_intr,
-+              .handle_interrupt = rtl821x_handle_interrupt,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc916),
-+              .name           = "RTL8211F Gigabit Ethernet",
-+              .probe          = rtl821x_probe,
-+              .config_init    = &rtl8211f_config_init,
-+              .read_status    = rtlgen_read_status,
-+              .config_intr    = &rtl8211f_config_intr,
-+              .handle_interrupt = rtl8211f_handle_interrupt,
-+              .suspend        = rtl821x_suspend,
-+              .resume         = rtl821x_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+              .flags          = PHY_ALWAYS_CALL_SUSPEND,
-+              .led_hw_is_supported = rtl8211f_led_hw_is_supported,
-+              .led_hw_control_get = rtl8211f_led_hw_control_get,
-+              .led_hw_control_set = rtl8211f_led_hw_control_set,
-+      }, {
-+              PHY_ID_MATCH_EXACT(RTL_8211FVD_PHYID),
-+              .name           = "RTL8211F-VD Gigabit Ethernet",
-+              .probe          = rtl821x_probe,
-+              .config_init    = &rtl8211f_config_init,
-+              .read_status    = rtlgen_read_status,
-+              .config_intr    = &rtl8211f_config_intr,
-+              .handle_interrupt = rtl8211f_handle_interrupt,
-+              .suspend        = rtl821x_suspend,
-+              .resume         = rtl821x_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+              .flags          = PHY_ALWAYS_CALL_SUSPEND,
-+      }, {
-+              .name           = "Generic FE-GE Realtek PHY",
-+              .match_phy_device = rtlgen_match_phy_device,
-+              .read_status    = rtlgen_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+              .read_mmd       = rtlgen_read_mmd,
-+              .write_mmd      = rtlgen_write_mmd,
-+      }, {
-+              .name           = "RTL8226 2.5Gbps PHY",
-+              .match_phy_device = rtl8226_match_phy_device,
-+              .get_features   = rtl822x_get_features,
-+              .config_aneg    = rtl822x_config_aneg,
-+              .read_status    = rtl822x_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              .match_phy_device = rtl8221b_match_phy_device,
-+              .name           = "RTL8226B_RTL8221B 2.5Gbps PHY",
-+              .get_features   = rtl822x_get_features,
-+              .config_aneg    = rtl822x_config_aneg,
-+              .config_init    = rtl822xb_config_init,
-+              .get_rate_matching = rtl822xb_get_rate_matching,
-+              .read_status    = rtl822xb_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc838),
-+              .name           = "RTL8226-CG 2.5Gbps PHY",
-+              .get_features   = rtl822x_get_features,
-+              .config_aneg    = rtl822x_config_aneg,
-+              .read_status    = rtl822x_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc848),
-+              .name           = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
-+              .get_features   = rtl822x_get_features,
-+              .config_aneg    = rtl822x_config_aneg,
-+              .config_init    = rtl822xb_config_init,
-+              .get_rate_matching = rtl822xb_get_rate_matching,
-+              .read_status    = rtl822xb_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
-+              .name           = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
-+              .get_features   = rtl822x_get_features,
-+              .config_aneg    = rtl822x_config_aneg,
-+              .config_init    = rtl822xb_config_init,
-+              .get_rate_matching = rtl822xb_get_rate_matching,
-+              .read_status    = rtl822xb_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
-+              .name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
-+              .config_init    = rtl822xb_config_init,
-+              .get_rate_matching = rtl822xb_get_rate_matching,
-+              .get_features   = rtl822x_c45_get_features,
-+              .config_aneg    = rtl822x_c45_config_aneg,
-+              .read_status    = rtl822xb_c45_read_status,
-+              .suspend        = genphy_c45_pma_suspend,
-+              .resume         = rtlgen_c45_resume,
-+      }, {
-+              .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
-+              .name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
-+              .get_features   = rtl822x_get_features,
-+              .config_aneg    = rtl822x_config_aneg,
-+              .config_init    = rtl822xb_config_init,
-+              .get_rate_matching = rtl822xb_get_rate_matching,
-+              .read_status    = rtl822xb_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
-+              .name           = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
-+              .config_init    = rtl822xb_config_init,
-+              .get_rate_matching = rtl822xb_get_rate_matching,
-+              .get_features   = rtl822x_c45_get_features,
-+              .config_aneg    = rtl822x_c45_config_aneg,
-+              .read_status    = rtl822xb_c45_read_status,
-+              .suspend        = genphy_c45_pma_suspend,
-+              .resume         = rtlgen_c45_resume,
-+      }, {
-+              .match_phy_device = rtl8251b_c45_match_phy_device,
-+              .name           = "RTL8251B 5Gbps PHY",
-+              .get_features   = rtl822x_get_features,
-+              .config_aneg    = rtl822x_config_aneg,
-+              .read_status    = rtl822x_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              .match_phy_device = rtl_internal_nbaset_match_phy_device,
-+              .name           = "Realtek Internal NBASE-T PHY",
-+              .flags          = PHY_IS_INTERNAL,
-+              .get_features   = rtl822x_get_features,
-+              .config_aneg    = rtl822x_config_aneg,
-+              .read_status    = rtl822x_read_status,
-+              .suspend        = genphy_suspend,
-+              .resume         = rtlgen_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+              .read_mmd       = rtl822x_read_mmd,
-+              .write_mmd      = rtl822x_write_mmd,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001ccad0),
-+              .name           = "RTL8224 2.5Gbps PHY",
-+              .get_features   = rtl822x_c45_get_features,
-+              .config_aneg    = rtl822x_c45_config_aneg,
-+              .read_status    = rtl822x_c45_read_status,
-+              .suspend        = genphy_c45_pma_suspend,
-+              .resume         = rtlgen_c45_resume,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc961),
-+              .name           = "RTL8366RB Gigabit Ethernet",
-+              .config_init    = &rtl8366rb_config_init,
-+              /* These interrupts are handled by the irq controller
-+               * embedded inside the RTL8366RB, they get unmasked when the
-+               * irq is requested and ACKed by reading the status register,
-+               * which is done by the irqchip code.
-+               */
-+              .config_intr    = genphy_no_config_intr,
-+              .handle_interrupt = genphy_handle_interrupt_no_ack,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001ccb00),
-+              .name           = "RTL9000AA_RTL9000AN Ethernet",
-+              .features       = PHY_BASIC_T1_FEATURES,
-+              .config_init    = rtl9000a_config_init,
-+              .config_aneg    = rtl9000a_config_aneg,
-+              .read_status    = rtl9000a_read_status,
-+              .config_intr    = rtl9000a_config_intr,
-+              .handle_interrupt = rtl9000a_handle_interrupt,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_page      = rtl821x_read_page,
-+              .write_page     = rtl821x_write_page,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc942),
-+              .name           = "RTL8365MB-VC Gigabit Ethernet",
-+              /* Interrupt handling analogous to RTL8366RB */
-+              .config_intr    = genphy_no_config_intr,
-+              .handle_interrupt = genphy_handle_interrupt_no_ack,
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+      }, {
-+              PHY_ID_MATCH_EXACT(0x001cc960),
-+              .name           = "RTL8366S Gigabit Ethernet",
-+              .suspend        = genphy_suspend,
-+              .resume         = genphy_resume,
-+              .read_mmd       = genphy_read_mmd_unsupported,
-+              .write_mmd      = genphy_write_mmd_unsupported,
-+      },
-+};
-+
-+module_phy_driver(realtek_drvs);
-+
-+static const struct mdio_device_id __maybe_unused realtek_tbl[] = {
-+      { PHY_ID_MATCH_VENDOR(0x001cc800) },
-+      { }
-+};
-+
-+MODULE_DEVICE_TABLE(mdio, realtek_tbl);
diff --git a/target/linux/generic/backport-6.18/781-11-v6.14-net-phy-realtek-add-hwmon-support-for-temp-sensor-on.patch b/target/linux/generic/backport-6.18/781-11-v6.14-net-phy-realtek-add-hwmon-support-for-temp-sensor-on.patch
deleted file mode 100644 (file)
index 2dec701..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-From 33700ca45b7d2e1655d4cad95e25671e8a94e2f0 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 11 Jan 2025 21:51:24 +0100
-Subject: [PATCH] net: phy: realtek: add hwmon support for temp sensor on
- RTL822x
-
-This adds hwmon support for the temperature sensor on RTL822x.
-It's available on the standalone versions of the PHY's, and on
-the integrated PHY's in RTL8125B/RTL8125D/RTL8126.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/ad6bfe9f-6375-4a00-84b4-bfb38a21bd71@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/Kconfig         |  6 ++
- drivers/net/phy/realtek/Makefile        |  1 +
- drivers/net/phy/realtek/realtek.h       | 10 ++++
- drivers/net/phy/realtek/realtek_hwmon.c | 79 +++++++++++++++++++++++++
- drivers/net/phy/realtek/realtek_main.c  | 12 ++++
- 5 files changed, 108 insertions(+)
- create mode 100644 drivers/net/phy/realtek/realtek.h
- create mode 100644 drivers/net/phy/realtek/realtek_hwmon.c
-
---- a/drivers/net/phy/realtek/Kconfig
-+++ b/drivers/net/phy/realtek/Kconfig
-@@ -3,3 +3,9 @@ config REALTEK_PHY
-       tristate "Realtek PHYs"
-       help
-         Currently supports RTL821x/RTL822x and fast ethernet PHYs
-+
-+config REALTEK_PHY_HWMON
-+      def_bool REALTEK_PHY && HWMON
-+      depends on !(REALTEK_PHY=y && HWMON=m)
-+      help
-+        Optional hwmon support for the temperature sensor
---- a/drivers/net/phy/realtek/Makefile
-+++ b/drivers/net/phy/realtek/Makefile
-@@ -1,3 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
- realtek-y                     += realtek_main.o
-+realtek-$(CONFIG_REALTEK_PHY_HWMON) += realtek_hwmon.o
- obj-$(CONFIG_REALTEK_PHY)     += realtek.o
---- /dev/null
-+++ b/drivers/net/phy/realtek/realtek.h
-@@ -0,0 +1,10 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+
-+#ifndef REALTEK_H
-+#define REALTEK_H
-+
-+#include <linux/phy.h>
-+
-+int rtl822x_hwmon_init(struct phy_device *phydev);
-+
-+#endif /* REALTEK_H */
---- /dev/null
-+++ b/drivers/net/phy/realtek/realtek_hwmon.c
-@@ -0,0 +1,79 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * HWMON support for Realtek PHY's
-+ *
-+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
-+ */
-+
-+#include <linux/hwmon.h>
-+#include <linux/phy.h>
-+
-+#include "realtek.h"
-+
-+#define RTL822X_VND2_TSALRM                           0xa662
-+#define RTL822X_VND2_TSRR                             0xbd84
-+#define RTL822X_VND2_TSSR                             0xb54c
-+
-+static int rtl822x_hwmon_get_temp(int raw)
-+{
-+      if (raw >= 512)
-+              raw -= 1024;
-+
-+      return 1000 * raw / 2;
-+}
-+
-+static int rtl822x_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
-+                            u32 attr, int channel, long *val)
-+{
-+      struct phy_device *phydev = dev_get_drvdata(dev);
-+      int raw;
-+
-+      switch (attr) {
-+      case hwmon_temp_input:
-+              raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSRR) & 0x3ff;
-+              *val = rtl822x_hwmon_get_temp(raw);
-+              break;
-+      case hwmon_temp_max:
-+              /* Chip reduces speed to 1G if threshold is exceeded */
-+              raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSSR) >> 6;
-+              *val = rtl822x_hwmon_get_temp(raw);
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static const struct hwmon_ops rtl822x_hwmon_ops = {
-+      .visible = 0444,
-+      .read = rtl822x_hwmon_read,
-+};
-+
-+static const struct hwmon_channel_info * const rtl822x_hwmon_info[] = {
-+      HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX),
-+      NULL
-+};
-+
-+static const struct hwmon_chip_info rtl822x_hwmon_chip_info = {
-+      .ops = &rtl822x_hwmon_ops,
-+      .info = rtl822x_hwmon_info,
-+};
-+
-+int rtl822x_hwmon_init(struct phy_device *phydev)
-+{
-+      struct device *hwdev, *dev = &phydev->mdio.dev;
-+      const char *name;
-+
-+      /* Ensure over-temp alarm is reset. */
-+      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSALRM, 3);
-+
-+      name = devm_hwmon_sanitize_name(dev, dev_name(dev));
-+      if (IS_ERR(name))
-+              return PTR_ERR(name);
-+
-+      hwdev = devm_hwmon_device_register_with_info(dev, name, phydev,
-+                                                   &rtl822x_hwmon_chip_info,
-+                                                   NULL);
-+      return PTR_ERR_OR_ZERO(hwdev);
-+}
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -14,6 +14,8 @@
- #include <linux/delay.h>
- #include <linux/clk.h>
-+#include "realtek.h"
-+
- #define RTL821x_PHYSR                         0x11
- #define RTL821x_PHYSR_DUPLEX                  BIT(13)
- #define RTL821x_PHYSR_SPEED                   GENMASK(15, 14)
-@@ -820,6 +822,15 @@ static int rtl822x_write_mmd(struct phy_
-       return ret;
- }
-+static int rtl822x_probe(struct phy_device *phydev)
-+{
-+      if (IS_ENABLED(CONFIG_REALTEK_PHY_HWMON) &&
-+          phydev->phy_id != RTL_GENERIC_PHYID)
-+              return rtl822x_hwmon_init(phydev);
-+
-+      return 0;
-+}
-+
- static int rtl822xb_config_init(struct phy_device *phydev)
- {
-       bool has_2500, has_sgmii;
-@@ -1518,6 +1529,7 @@ static struct phy_driver realtek_drvs[]
-               .match_phy_device = rtl_internal_nbaset_match_phy_device,
-               .name           = "Realtek Internal NBASE-T PHY",
-               .flags          = PHY_IS_INTERNAL,
-+              .probe          = rtl822x_probe,
-               .get_features   = rtl822x_get_features,
-               .config_aneg    = rtl822x_config_aneg,
-               .read_status    = rtl822x_read_status,
diff --git a/target/linux/generic/backport-6.18/781-12-v6.14-net-phy-realtek-HWMON-support-for-standalone-version.patch b/target/linux/generic/backport-6.18/781-12-v6.14-net-phy-realtek-HWMON-support-for-standalone-version.patch
deleted file mode 100644 (file)
index 8b8c97c..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-From 64ff63aeefb03139ae27454bd4208244579ae88e Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Fri, 17 Jan 2025 23:24:21 +0100
-Subject: [PATCH] net: phy: realtek: HWMON support for standalone versions of
- RTL8221B and RTL8251
-
-HWMON support has been added for the RTL8221/8251 PHYs integrated together
-with the MAC inside the RTL8125/8126 chips. This patch extends temperature
-reading support for standalone variants of the mentioned PHYs.
-
-I don't know whether the earlier revisions of the RTL8226 also have a
-built-in temperature sensor, so they have been skipped for now.
-
-Tested on RTL8221B-VB-CG.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/realtek/realtek_main.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1474,6 +1474,7 @@ static struct phy_driver realtek_drvs[]
-       }, {
-               .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
-               .name           = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
-+              .probe          = rtl822x_probe,
-               .get_features   = rtl822x_get_features,
-               .config_aneg    = rtl822x_config_aneg,
-               .config_init    = rtl822xb_config_init,
-@@ -1486,6 +1487,7 @@ static struct phy_driver realtek_drvs[]
-       }, {
-               .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
-               .name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
-+              .probe          = rtl822x_probe,
-               .config_init    = rtl822xb_config_init,
-               .get_rate_matching = rtl822xb_get_rate_matching,
-               .get_features   = rtl822x_c45_get_features,
-@@ -1496,6 +1498,7 @@ static struct phy_driver realtek_drvs[]
-       }, {
-               .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
-               .name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
-+              .probe          = rtl822x_probe,
-               .get_features   = rtl822x_get_features,
-               .config_aneg    = rtl822x_config_aneg,
-               .config_init    = rtl822xb_config_init,
-@@ -1508,6 +1511,7 @@ static struct phy_driver realtek_drvs[]
-       }, {
-               .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
-               .name           = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
-+              .probe          = rtl822x_probe,
-               .config_init    = rtl822xb_config_init,
-               .get_rate_matching = rtl822xb_get_rate_matching,
-               .get_features   = rtl822x_c45_get_features,
-@@ -1518,6 +1522,7 @@ static struct phy_driver realtek_drvs[]
-       }, {
-               .match_phy_device = rtl8251b_c45_match_phy_device,
-               .name           = "RTL8251B 5Gbps PHY",
-+              .probe          = rtl822x_probe,
-               .get_features   = rtl822x_get_features,
-               .config_aneg    = rtl822x_config_aneg,
-               .read_status    = rtl822x_read_status,
diff --git a/target/linux/generic/backport-6.18/781-13-v6.15-net-phy-realtek-make-HWMON-support-a-user-visible-Kc.patch b/target/linux/generic/backport-6.18/781-13-v6.15-net-phy-realtek-make-HWMON-support-a-user-visible-Kc.patch
deleted file mode 100644 (file)
index 821d7ee..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 51773846fab24a353bed4ebb660997ced4bc32d7 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 3 Feb 2025 21:33:39 +0100
-Subject: [PATCH] net: phy: realtek: make HWMON support a user-visible Kconfig
- symbol
-
-Make config symbol REALTEK_PHY_HWMON user-visible, so that users can
-remove support if not needed.
-
-Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/3466ee92-166a-4b0f-9ae7-42b9e046f333@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/Kconfig | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek/Kconfig
-+++ b/drivers/net/phy/realtek/Kconfig
-@@ -4,8 +4,12 @@ config REALTEK_PHY
-       help
-         Currently supports RTL821x/RTL822x and fast ethernet PHYs
-+if REALTEK_PHY
-+
- config REALTEK_PHY_HWMON
--      def_bool REALTEK_PHY && HWMON
--      depends on !(REALTEK_PHY=y && HWMON=m)
-+      bool "HWMON support for Realtek PHYs"
-+      depends on HWMON && !(REALTEK_PHY=y && HWMON=m)
-       help
-         Optional hwmon support for the temperature sensor
-+
-+endif # REALTEK_PHY
diff --git a/target/linux/generic/backport-6.18/781-14-v6.15-net-phy-realtek-use-string-choices-helpers.patch b/target/linux/generic/backport-6.18/781-14-v6.15-net-phy-realtek-use-string-choices-helpers.patch
deleted file mode 100644 (file)
index d3e09bc..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-From 0bea93fdbaf8675b7e8124bdcaf51497dcc8bcfa Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 3 Feb 2025 21:41:36 +0100
-Subject: [PATCH] net: phy: realtek: use string choices helpers
-
-Use string choices helpers to simplify the code.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Closes: https://lore.kernel.org/oe-kbuild-all/202501190707.qQS8PGHW-lkp@intel.com/
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/realtek/realtek_main.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -13,6 +13,7 @@
- #include <linux/module.h>
- #include <linux/delay.h>
- #include <linux/clk.h>
-+#include <linux/string_choices.h>
- #include "realtek.h"
-@@ -422,11 +423,11 @@ static int rtl8211f_config_init(struct p
-       } else if (ret) {
-               dev_dbg(dev,
-                       "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
--                      val_txdly ? "Enabling" : "Disabling");
-+                      str_enable_disable(val_txdly));
-       } else {
-               dev_dbg(dev,
-                       "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
--                      val_txdly ? "enabled" : "disabled");
-+                      str_enabled_disabled(val_txdly));
-       }
-       ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
-@@ -437,11 +438,11 @@ static int rtl8211f_config_init(struct p
-       } else if (ret) {
-               dev_dbg(dev,
-                       "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
--                      val_rxdly ? "Enabling" : "Disabling");
-+                      str_enable_disable(val_rxdly));
-       } else {
-               dev_dbg(dev,
-                       "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
--                      val_rxdly ? "enabled" : "disabled");
-+                      str_enabled_disabled(val_rxdly));
-       }
-       if (priv->has_phycr2) {
diff --git a/target/linux/generic/backport-6.18/781-15-v6.15-net-phy-realtek-improve-mmd-register-access-for-inte.patch b/target/linux/generic/backport-6.18/781-15-v6.15-net-phy-realtek-improve-mmd-register-access-for-inte.patch
deleted file mode 100644 (file)
index 3a3a20d..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-From da681ed73fb980286fc29de707b35d76bb33e123 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 13 Feb 2025 20:18:17 +0100
-Subject: [PATCH] net: phy: realtek: improve mmd register access for internal
- PHY's
-
-r8169 provides the MDIO bus for the internal PHY's. It has been extended
-with c45 access functions for addressing MDIO_MMD_VEND2 registers.
-So we can switch from paged access to directly addressing the
-MDIO_MMD_VEND2 registers.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/a5f2333c-dda9-48ad-9801-77049766e632@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 79 +++++++++++---------------
- 1 file changed, 33 insertions(+), 46 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -735,29 +735,31 @@ static int rtlgen_read_status(struct phy
-       return 0;
- }
-+static int rtlgen_read_vend2(struct phy_device *phydev, int regnum)
-+{
-+      return __mdiobus_c45_read(phydev->mdio.bus, 0, MDIO_MMD_VEND2, regnum);
-+}
-+
-+static int rtlgen_write_vend2(struct phy_device *phydev, int regnum, u16 val)
-+{
-+      return __mdiobus_c45_write(phydev->mdio.bus, 0, MDIO_MMD_VEND2, regnum,
-+                                 val);
-+}
-+
- static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
- {
-       int ret;
--      if (devnum == MDIO_MMD_VEND2) {
--              rtl821x_write_page(phydev, regnum >> 4);
--              ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1));
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
--              rtl821x_write_page(phydev, 0xa5c);
--              ret = __phy_read(phydev, 0x12);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
--              rtl821x_write_page(phydev, 0xa5d);
--              ret = __phy_read(phydev, 0x10);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) {
--              rtl821x_write_page(phydev, 0xa5d);
--              ret = __phy_read(phydev, 0x11);
--              rtl821x_write_page(phydev, 0);
--      } else {
-+      if (devnum == MDIO_MMD_VEND2)
-+              ret = rtlgen_read_vend2(phydev, regnum);
-+      else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE)
-+              ret = rtlgen_read_vend2(phydev, 0xa5c4);
-+      else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV)
-+              ret = rtlgen_read_vend2(phydev, 0xa5d0);
-+      else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE)
-+              ret = rtlgen_read_vend2(phydev, 0xa5d2);
-+      else
-               ret = -EOPNOTSUPP;
--      }
-       return ret;
- }
-@@ -767,17 +769,12 @@ static int rtlgen_write_mmd(struct phy_d
- {
-       int ret;
--      if (devnum == MDIO_MMD_VEND2) {
--              rtl821x_write_page(phydev, regnum >> 4);
--              ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
--              rtl821x_write_page(phydev, 0xa5d);
--              ret = __phy_write(phydev, 0x10, val);
--              rtl821x_write_page(phydev, 0);
--      } else {
-+      if (devnum == MDIO_MMD_VEND2)
-+              ret = rtlgen_write_vend2(phydev, regnum, val);
-+      else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV)
-+              ret = rtlgen_write_vend2(phydev, regnum, 0xa5d0);
-+      else
-               ret = -EOPNOTSUPP;
--      }
-       return ret;
- }
-@@ -789,19 +786,12 @@ static int rtl822x_read_mmd(struct phy_d
-       if (ret != -EOPNOTSUPP)
-               return ret;
--      if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) {
--              rtl821x_write_page(phydev, 0xa6e);
--              ret = __phy_read(phydev, 0x16);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
--              rtl821x_write_page(phydev, 0xa6d);
--              ret = __phy_read(phydev, 0x12);
--              rtl821x_write_page(phydev, 0);
--      } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) {
--              rtl821x_write_page(phydev, 0xa6d);
--              ret = __phy_read(phydev, 0x10);
--              rtl821x_write_page(phydev, 0);
--      }
-+      if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2)
-+              ret = rtlgen_read_vend2(phydev, 0xa6ec);
-+      else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2)
-+              ret = rtlgen_read_vend2(phydev, 0xa6d4);
-+      else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2)
-+              ret = rtlgen_read_vend2(phydev, 0xa6d0);
-       return ret;
- }
-@@ -814,11 +804,8 @@ static int rtl822x_write_mmd(struct phy_
-       if (ret != -EOPNOTSUPP)
-               return ret;
--      if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) {
--              rtl821x_write_page(phydev, 0xa6d);
--              ret = __phy_write(phydev, 0x12, val);
--              rtl821x_write_page(phydev, 0);
--      }
-+      if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2)
-+              ret = rtlgen_write_vend2(phydev, 0xa6d4, val);
-       return ret;
- }
diff --git a/target/linux/generic/backport-6.18/781-16-v6.15-net-phy-realtek-switch-from-paged-to-MMD-ops-in-rtl8.patch b/target/linux/generic/backport-6.18/781-16-v6.15-net-phy-realtek-switch-from-paged-to-MMD-ops-in-rtl8.patch
deleted file mode 100644 (file)
index 5e3c3ce..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From 02d3b306ac2f0b174753d1c5b9e4e5fb8ec5057e Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 13 Feb 2025 20:19:14 +0100
-Subject: [PATCH] net: phy: realtek: switch from paged to MMD ops in rtl822x
- functions
-
-The MDIO bus provided by r8169 for the internal PHY's now supports
-c45 ops for the MDIO_MMD_VEND2 device. So we can switch to standard
-MMD ops here.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/81416f95-0fac-4225-87b4-828e3738b8ed@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 11 +++++------
- 1 file changed, 5 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -901,7 +901,7 @@ static int rtl822x_get_features(struct p
- {
-       int val;
--      val = phy_read_paged(phydev, 0xa61, 0x13);
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa616);
-       if (val < 0)
-               return val;
-@@ -922,10 +922,9 @@ static int rtl822x_config_aneg(struct ph
-       if (phydev->autoneg == AUTONEG_ENABLE) {
-               u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
--              ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
--                                             MDIO_AN_10GBT_CTRL_ADV2_5G |
--                                             MDIO_AN_10GBT_CTRL_ADV5G,
--                                             adv);
-+              ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, 0xa5d4,
-+                                           MDIO_AN_10GBT_CTRL_ADV2_5G |
-+                                           MDIO_AN_10GBT_CTRL_ADV5G, adv);
-               if (ret < 0)
-                       return ret;
-       }
-@@ -969,7 +968,7 @@ static int rtl822x_read_status(struct ph
-           !phydev->autoneg_complete)
-               return 0;
--      lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
-+      lpadv = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa5d6);
-       if (lpadv < 0)
-               return lpadv;
diff --git a/target/linux/generic/backport-6.18/781-17-v6.15-net-phy-realtek-add-helper-RTL822X_VND2_C22_REG.patch b/target/linux/generic/backport-6.18/781-17-v6.15-net-phy-realtek-add-helper-RTL822X_VND2_C22_REG.patch
deleted file mode 100644 (file)
index 5134d08..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From 8af2136e77989a64fae0284bf76fd584e32edd3a Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Fri, 14 Feb 2025 21:31:14 +0100
-Subject: [PATCH] net: phy: realtek: add helper RTL822X_VND2_C22_REG
-
-C22 register space is mapped to 0xa400 in MMD VEND2 register space.
-Add a helper to access mapped C22 registers.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/6344277b-c5c7-449b-ac89-d5425306ca76@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 9 ++++-----
- 1 file changed, 4 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -79,9 +79,7 @@
- /* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
-  * is set, they cannot be accessed by C45-over-C22.
-  */
--#define RTL822X_VND2_GBCR                             0xa412
--
--#define RTL822X_VND2_GANLPAR                          0xa414
-+#define RTL822X_VND2_C22_REG(reg)             (0xa400 + 2 * (reg))
- #define RTL8366RB_POWER_SAVE                  0x15
- #define RTL8366RB_POWER_SAVE_ON                       BIT(12)
-@@ -1015,7 +1013,8 @@ static int rtl822x_c45_config_aneg(struc
-       val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
-       /* Vendor register as C45 has no standardized support for 1000BaseT */
--      ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR,
-+      ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2,
-+                                   RTL822X_VND2_C22_REG(MII_CTRL1000),
-                                    ADVERTISE_1000FULL, val);
-       if (ret < 0)
-               return ret;
-@@ -1032,7 +1031,7 @@ static int rtl822x_c45_read_status(struc
-       /* Vendor register as C45 has no standardized support for 1000BaseT */
-       if (phydev->autoneg == AUTONEG_ENABLE && genphy_c45_aneg_done(phydev)) {
-               val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
--                                 RTL822X_VND2_GANLPAR);
-+                                 RTL822X_VND2_C22_REG(MII_STAT1000));
-               if (val < 0)
-                       return val;
-       } else {
diff --git a/target/linux/generic/backport-6.18/781-18-v6.15-net-phy-realtek-add-defines-for-shadowed-c45-standar.patch b/target/linux/generic/backport-6.18/781-18-v6.15-net-phy-realtek-add-defines-for-shadowed-c45-standar.patch
deleted file mode 100644 (file)
index ff7d5b1..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-From fabcfd6d10999024a721ae1b965b57eb8a305ace Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 15 Feb 2025 14:29:15 +0100
-Subject: [PATCH] net: phy: realtek: add defines for shadowed c45 standard
- registers
-
-Realtek shadows standard c45 registers in VEND2 device register space.
-Add defines for these VEND2 registers, based on the names of the
-standard c45 registers.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/c90bdf76-f8b8-4d06-9656-7a52d5658ee6@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 33 +++++++++++++++++---------
- 1 file changed, 22 insertions(+), 11 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -94,6 +94,16 @@
- #define RTL_VND2_PHYSR_MASTER                 BIT(11)
- #define RTL_VND2_PHYSR_SPEED_MASK             (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH)
-+#define       RTL_MDIO_PCS_EEE_ABLE                   0xa5c4
-+#define       RTL_MDIO_AN_EEE_ADV                     0xa5d0
-+#define       RTL_MDIO_AN_EEE_LPABLE                  0xa5d2
-+#define       RTL_MDIO_AN_10GBT_CTRL                  0xa5d4
-+#define       RTL_MDIO_AN_10GBT_STAT                  0xa5d6
-+#define       RTL_MDIO_PMA_SPEED                      0xa616
-+#define       RTL_MDIO_AN_EEE_LPABLE2                 0xa6d0
-+#define       RTL_MDIO_AN_EEE_ADV2                    0xa6d4
-+#define       RTL_MDIO_PCS_EEE_ABLE2                  0xa6ec
-+
- #define RTL_GENERIC_PHYID                     0x001cc800
- #define RTL_8211FVD_PHYID                     0x001cc878
- #define RTL_8221B                             0x001cc840
-@@ -751,11 +761,11 @@ static int rtlgen_read_mmd(struct phy_de
-       if (devnum == MDIO_MMD_VEND2)
-               ret = rtlgen_read_vend2(phydev, regnum);
-       else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE)
--              ret = rtlgen_read_vend2(phydev, 0xa5c4);
-+              ret = rtlgen_read_vend2(phydev, RTL_MDIO_PCS_EEE_ABLE);
-       else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV)
--              ret = rtlgen_read_vend2(phydev, 0xa5d0);
-+              ret = rtlgen_read_vend2(phydev, RTL_MDIO_AN_EEE_ADV);
-       else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE)
--              ret = rtlgen_read_vend2(phydev, 0xa5d2);
-+              ret = rtlgen_read_vend2(phydev, RTL_MDIO_AN_EEE_LPABLE);
-       else
-               ret = -EOPNOTSUPP;
-@@ -770,7 +780,7 @@ static int rtlgen_write_mmd(struct phy_d
-       if (devnum == MDIO_MMD_VEND2)
-               ret = rtlgen_write_vend2(phydev, regnum, val);
-       else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV)
--              ret = rtlgen_write_vend2(phydev, regnum, 0xa5d0);
-+              ret = rtlgen_write_vend2(phydev, regnum, RTL_MDIO_AN_EEE_ADV);
-       else
-               ret = -EOPNOTSUPP;
-@@ -785,11 +795,11 @@ static int rtl822x_read_mmd(struct phy_d
-               return ret;
-       if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2)
--              ret = rtlgen_read_vend2(phydev, 0xa6ec);
-+              ret = rtlgen_read_vend2(phydev, RTL_MDIO_PCS_EEE_ABLE2);
-       else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2)
--              ret = rtlgen_read_vend2(phydev, 0xa6d4);
-+              ret = rtlgen_read_vend2(phydev, RTL_MDIO_AN_EEE_ADV2);
-       else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2)
--              ret = rtlgen_read_vend2(phydev, 0xa6d0);
-+              ret = rtlgen_read_vend2(phydev, RTL_MDIO_AN_EEE_LPABLE2);
-       return ret;
- }
-@@ -803,7 +813,7 @@ static int rtl822x_write_mmd(struct phy_
-               return ret;
-       if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2)
--              ret = rtlgen_write_vend2(phydev, 0xa6d4, val);
-+              ret = rtlgen_write_vend2(phydev, RTL_MDIO_AN_EEE_ADV2, val);
-       return ret;
- }
-@@ -899,7 +909,7 @@ static int rtl822x_get_features(struct p
- {
-       int val;
--      val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa616);
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_MDIO_PMA_SPEED);
-       if (val < 0)
-               return val;
-@@ -920,7 +930,8 @@ static int rtl822x_config_aneg(struct ph
-       if (phydev->autoneg == AUTONEG_ENABLE) {
-               u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
--              ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, 0xa5d4,
-+              ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2,
-+                                           RTL_MDIO_AN_10GBT_CTRL,
-                                            MDIO_AN_10GBT_CTRL_ADV2_5G |
-                                            MDIO_AN_10GBT_CTRL_ADV5G, adv);
-               if (ret < 0)
-@@ -966,7 +977,7 @@ static int rtl822x_read_status(struct ph
-           !phydev->autoneg_complete)
-               return 0;
--      lpadv = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa5d6);
-+      lpadv = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_MDIO_AN_10GBT_STAT);
-       if (lpadv < 0)
-               return lpadv;
diff --git a/target/linux/generic/backport-6.18/781-19-v6.15-net-phy-realtek-disable-PHY-mode-EEE.patch b/target/linux/generic/backport-6.18/781-19-v6.15-net-phy-realtek-disable-PHY-mode-EEE.patch
deleted file mode 100644 (file)
index 4d755d4..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-From bfc17c1658353f22843c7c13e27c2d31950f1887 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Sun, 16 Mar 2025 12:39:54 +0000
-Subject: [PATCH] net: phy: realtek: disable PHY-mode EEE
-
-Realtek RTL8211F has a "PHY-mode" EEE support which interferes with an
-IEEE 802.3 compliant implementation. This mode defaults to enabled, and
-results in the MAC receive path not seeing the link transition to LPI
-state.
-
-Fix this by disabling PHY-mode EEE.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/E1ttnHW-00785s-Uq@rmk-PC.armlinux.org.uk
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek/realtek_main.c | 11 +++++++++--
- 1 file changed, 9 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -33,6 +33,9 @@
- #define RTL8211F_PHYCR1                               0x18
- #define RTL8211F_PHYCR2                               0x19
-+#define RTL8211F_CLKOUT_EN                    BIT(0)
-+#define RTL8211F_PHYCR2_PHY_EEE_ENABLE                BIT(5)
-+
- #define RTL8211F_INSR                         0x1d
- #define RTL8211F_LEDCR                                0x10
-@@ -55,8 +58,6 @@
- #define RTL8211E_TX_DELAY                     BIT(12)
- #define RTL8211E_RX_DELAY                     BIT(11)
--#define RTL8211F_CLKOUT_EN                    BIT(0)
--
- #define RTL8201F_ISR                          0x1e
- #define RTL8201F_ISR_ANERR                    BIT(15)
- #define RTL8201F_ISR_DUPLEX                   BIT(13)
-@@ -453,6 +454,12 @@ static int rtl8211f_config_init(struct p
-                       str_enabled_disabled(val_rxdly));
-       }
-+      /* Disable PHY-mode EEE so LPI is passed to the MAC */
-+      ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2,
-+                             RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
-+      if (ret)
-+              return ret;
-+
-       if (priv->has_phycr2) {
-               ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2,
-                                      RTL8211F_CLKOUT_EN, priv->phycr2);
diff --git a/target/linux/generic/backport-6.18/781-20-v6.16-net-phy-realtek-Add-support-for-WOL-magic-packet-on.patch b/target/linux/generic/backport-6.18/781-20-v6.16-net-phy-realtek-Add-support-for-WOL-magic-packet-on.patch
deleted file mode 100644 (file)
index 4ba06cc..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-From 7840e4d6f48a75413470935ebdc4bab4fc0c035e Mon Sep 17 00:00:00 2001
-From: Daniel Braunwarth <daniel.braunwarth@kuka.com>
-Date: Tue, 29 Apr 2025 13:33:37 +0200
-Subject: [PATCH] net: phy: realtek: Add support for WOL magic packet on
- RTL8211F
-
-The RTL8211F supports multiple WOL modes. This patch adds support for
-magic packets.
-
-The PHY notifies the system via the INTB/PMEB pin when a WOL event
-occurs.
-
-Signed-off-by: Daniel Braunwarth <daniel.braunwarth@kuka.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250429-realtek_wol-v2-1-8f84def1ef2c@kuka.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 69 ++++++++++++++++++++++++++
- 1 file changed, 69 insertions(+)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -10,6 +10,7 @@
- #include <linux/bitops.h>
- #include <linux/of.h>
- #include <linux/phy.h>
-+#include <linux/netdevice.h>
- #include <linux/module.h>
- #include <linux/delay.h>
- #include <linux/clk.h>
-@@ -38,6 +39,24 @@
- #define RTL8211F_INSR                         0x1d
-+/* RTL8211F WOL interrupt configuration */
-+#define RTL8211F_INTBCR_PAGE                  0xd40
-+#define RTL8211F_INTBCR                               0x16
-+#define RTL8211F_INTBCR_INTB_PMEB             BIT(5)
-+
-+/* RTL8211F WOL settings */
-+#define RTL8211F_WOL_SETTINGS_PAGE            0xd8a
-+#define RTL8211F_WOL_SETTINGS_EVENTS          16
-+#define RTL8211F_WOL_EVENT_MAGIC              BIT(12)
-+#define RTL8211F_WOL_SETTINGS_STATUS          17
-+#define RTL8211F_WOL_STATUS_RESET             (BIT(15) | 0x1fff)
-+
-+/* RTL8211F Unique phyiscal and multicast address (WOL) */
-+#define RTL8211F_PHYSICAL_ADDR_PAGE           0xd8c
-+#define RTL8211F_PHYSICAL_ADDR_WORD0          16
-+#define RTL8211F_PHYSICAL_ADDR_WORD1          17
-+#define RTL8211F_PHYSICAL_ADDR_WORD2          18
-+
- #define RTL8211F_LEDCR                                0x10
- #define RTL8211F_LEDCR_MODE                   BIT(15)
- #define RTL8211F_LEDCR_ACT_TXRX                       BIT(4)
-@@ -123,6 +142,7 @@ struct rtl821x_priv {
-       u16 phycr2;
-       bool has_phycr2;
-       struct clk *clk;
-+      u32 saved_wolopts;
- };
- static int rtl821x_read_page(struct phy_device *phydev)
-@@ -354,6 +374,53 @@ static irqreturn_t rtl8211f_handle_inter
-       return IRQ_HANDLED;
- }
-+static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
-+{
-+      wol->supported = WAKE_MAGIC;
-+      if (phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS)
-+          & RTL8211F_WOL_EVENT_MAGIC)
-+              wol->wolopts = WAKE_MAGIC;
-+}
-+
-+static int rtl8211f_set_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
-+{
-+      const u8 *mac_addr = dev->attached_dev->dev_addr;
-+      int oldpage;
-+
-+      oldpage = phy_save_page(dev);
-+      if (oldpage < 0)
-+              goto err;
-+
-+      if (wol->wolopts & WAKE_MAGIC) {
-+              /* Store the device address for the magic packet */
-+              rtl821x_write_page(dev, RTL8211F_PHYSICAL_ADDR_PAGE);
-+              __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD0, mac_addr[1] << 8 | (mac_addr[0]));
-+              __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD1, mac_addr[3] << 8 | (mac_addr[2]));
-+              __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD2, mac_addr[5] << 8 | (mac_addr[4]));
-+
-+              /* Enable magic packet matching and reset WOL status */
-+              rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
-+              __phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, RTL8211F_WOL_EVENT_MAGIC);
-+              __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
-+
-+              /* Enable the WOL interrupt */
-+              rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
-+              __phy_set_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
-+      } else {
-+              /* Disable the WOL interrupt */
-+              rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
-+              __phy_clear_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
-+
-+              /* Disable magic packet matching and reset WOL status */
-+              rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
-+              __phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, 0);
-+              __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
-+      }
-+
-+err:
-+      return phy_restore_page(dev, oldpage, 0);
-+}
-+
- static int rtl8211_config_aneg(struct phy_device *phydev)
- {
-       int ret;
-@@ -1400,6 +1467,8 @@ static struct phy_driver realtek_drvs[]
-               .read_status    = rtlgen_read_status,
-               .config_intr    = &rtl8211f_config_intr,
-               .handle_interrupt = rtl8211f_handle_interrupt,
-+              .set_wol        = rtl8211f_set_wol,
-+              .get_wol        = rtl8211f_get_wol,
-               .suspend        = rtl821x_suspend,
-               .resume         = rtl821x_resume,
-               .read_page      = rtl821x_read_page,
diff --git a/target/linux/generic/backport-6.18/781-21-v6.16-net-phy-realtek-remove-unsed-RTL821x_PHYSR-macros.patch b/target/linux/generic/backport-6.18/781-21-v6.16-net-phy-realtek-remove-unsed-RTL821x_PHYSR-macros.patch
deleted file mode 100644 (file)
index e054937..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From f3b265358b911fe9e495619bdfa7797749474f95 Mon Sep 17 00:00:00 2001
-From: Michael Klein <michael@fossekall.de>
-Date: Sun, 4 May 2025 19:29:11 +0200
-Subject: [PATCH] net: phy: realtek: remove unsed RTL821x_PHYSR* macros
-
-These macros have there since the first revision but were never used, so
-let's just remove them.
-
-Signed-off-by: Michael Klein <michael@fossekall.de>
-Link: https://patch.msgid.link/20250504172916.243185-2-michael@fossekall.de
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek/realtek_main.c | 4 ----
- 1 file changed, 4 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -18,10 +18,6 @@
- #include "realtek.h"
--#define RTL821x_PHYSR                         0x11
--#define RTL821x_PHYSR_DUPLEX                  BIT(13)
--#define RTL821x_PHYSR_SPEED                   GENMASK(15, 14)
--
- #define RTL821x_INER                          0x12
- #define RTL8211B_INER_INIT                    0x6400
- #define RTL8211E_INER_LINK_STATUS             BIT(10)
diff --git a/target/linux/generic/backport-6.18/781-22-v6.16-net-phy-realtek-Clean-up-RTL821x-ExtPage-access.patch b/target/linux/generic/backport-6.18/781-22-v6.16-net-phy-realtek-Clean-up-RTL821x-ExtPage-access.patch
deleted file mode 100644 (file)
index 62bbf32..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-From 7c6fa3ffd2650347b1d37f028e232e53d617c1af Mon Sep 17 00:00:00 2001
-From: Michael Klein <michael@fossekall.de>
-Date: Sun, 4 May 2025 19:29:12 +0200
-Subject: [PATCH] net: phy: realtek: Clean up RTL821x ExtPage access
-
-Factor out RTL8211E extension page access code to
-rtl821x_modify_ext_page() and clean up rtl8211e_config_init()
-
-Signed-off-by: Michael Klein <michael@fossekall.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250504172916.243185-3-michael@fossekall.de
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek/realtek_main.c | 38 ++++++++++++++++----------
- 1 file changed, 23 insertions(+), 15 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -26,7 +26,9 @@
- #define RTL821x_INSR                          0x13
- #define RTL821x_EXT_PAGE_SELECT                       0x1e
-+
- #define RTL821x_PAGE_SELECT                   0x1f
-+#define RTL821x_SET_EXT_PAGE                  0x07
- #define RTL8211F_PHYCR1                               0x18
- #define RTL8211F_PHYCR2                               0x19
-@@ -69,9 +71,12 @@
- #define RTL8211F_ALDPS_ENABLE                 BIT(2)
- #define RTL8211F_ALDPS_XTAL_OFF                       BIT(12)
-+#define RTL8211E_RGMII_EXT_PAGE                       0xa4
-+#define RTL8211E_RGMII_DELAY                  0x1c
- #define RTL8211E_CTRL_DELAY                   BIT(13)
- #define RTL8211E_TX_DELAY                     BIT(12)
- #define RTL8211E_RX_DELAY                     BIT(11)
-+#define RTL8211E_DELAY_MASK                   GENMASK(13, 11)
- #define RTL8201F_ISR                          0x1e
- #define RTL8201F_ISR_ANERR                    BIT(15)
-@@ -151,6 +156,21 @@ static int rtl821x_write_page(struct phy
-       return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
- }
-+static int rtl821x_modify_ext_page(struct phy_device *phydev, u16 ext_page,
-+                                 u32 regnum, u16 mask, u16 set)
-+{
-+      int oldpage, ret = 0;
-+
-+      oldpage = phy_select_page(phydev, RTL821x_SET_EXT_PAGE);
-+      if (oldpage >= 0) {
-+              ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, ext_page);
-+              if (ret == 0)
-+                      ret = __phy_modify(phydev, regnum, mask, set);
-+      }
-+
-+      return phy_restore_page(phydev, oldpage, ret);
-+}
-+
- static int rtl821x_probe(struct phy_device *phydev)
- {
-       struct device *dev = &phydev->mdio.dev;
-@@ -670,7 +690,6 @@ static int rtl8211f_led_hw_control_set(s
- static int rtl8211e_config_init(struct phy_device *phydev)
- {
--      int ret = 0, oldpage;
-       u16 val;
-       /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
-@@ -700,20 +719,9 @@ static int rtl8211e_config_init(struct p
-        * 12 = RX Delay, 11 = TX Delay
-        * 10:0 = Test && debug settings reserved by realtek
-        */
--      oldpage = phy_select_page(phydev, 0x7);
--      if (oldpage < 0)
--              goto err_restore_page;
--
--      ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4);
--      if (ret)
--              goto err_restore_page;
--
--      ret = __phy_modify(phydev, 0x1c, RTL8211E_CTRL_DELAY
--                         | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
--                         val);
--
--err_restore_page:
--      return phy_restore_page(phydev, oldpage, ret);
-+      return rtl821x_modify_ext_page(phydev, RTL8211E_RGMII_EXT_PAGE,
-+                                     RTL8211E_RGMII_DELAY,
-+                                     RTL8211E_DELAY_MASK, val);
- }
- static int rtl8211b_suspend(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.18/781-23-v6.16-net-phy-realtek-add-RTL8211F-register-defines.patch b/target/linux/generic/backport-6.18/781-23-v6.16-net-phy-realtek-add-RTL8211F-register-defines.patch
deleted file mode 100644 (file)
index 9116992..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-From 12d40df259e38851a0d973535e6023b33e2ea4f9 Mon Sep 17 00:00:00 2001
-From: Michael Klein <michael@fossekall.de>
-Date: Sun, 4 May 2025 19:29:13 +0200
-Subject: [PATCH] net: phy: realtek: add RTL8211F register defines
-
-Add some more defines for RTL8211F page and register numbers.
-
-Signed-off-by: Michael Klein <michael@fossekall.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250504172916.243185-4-michael@fossekall.de
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek/realtek_main.c | 34 ++++++++++++++++++--------
- 1 file changed, 24 insertions(+), 10 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -30,11 +30,14 @@
- #define RTL821x_PAGE_SELECT                   0x1f
- #define RTL821x_SET_EXT_PAGE                  0x07
-+/* RTL8211F PHY configuration */
-+#define RTL8211F_PHYCR_PAGE                   0xa43
- #define RTL8211F_PHYCR1                               0x18
- #define RTL8211F_PHYCR2                               0x19
- #define RTL8211F_CLKOUT_EN                    BIT(0)
- #define RTL8211F_PHYCR2_PHY_EEE_ENABLE                BIT(5)
-+#define RTL8211F_INSR_PAGE                    0xa43
- #define RTL8211F_INSR                         0x1d
- /* RTL8211F WOL interrupt configuration */
-@@ -55,6 +58,8 @@
- #define RTL8211F_PHYSICAL_ADDR_WORD1          17
- #define RTL8211F_PHYSICAL_ADDR_WORD2          18
-+/* RTL8211F LED configuration */
-+#define RTL8211F_LEDCR_PAGE                   0xd04
- #define RTL8211F_LEDCR                                0x10
- #define RTL8211F_LEDCR_MODE                   BIT(15)
- #define RTL8211F_LEDCR_ACT_TXRX                       BIT(4)
-@@ -64,7 +69,13 @@
- #define RTL8211F_LEDCR_MASK                   GENMASK(4, 0)
- #define RTL8211F_LEDCR_SHIFT                  5
-+/* RTL8211F RGMII configuration */
-+#define RTL8211F_RGMII_PAGE                   0xd08
-+
-+#define RTL8211F_TXCR                         0x11
- #define RTL8211F_TX_DELAY                     BIT(8)
-+
-+#define RTL8211F_RXCR                         0x15
- #define RTL8211F_RX_DELAY                     BIT(3)
- #define RTL8211F_ALDPS_PLL_OFF                        BIT(1)
-@@ -187,7 +198,7 @@ static int rtl821x_probe(struct phy_devi
-               return dev_err_probe(dev, PTR_ERR(priv->clk),
-                                    "failed to get phy clock\n");
--      ret = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR1);
-+      ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1);
-       if (ret < 0)
-               return ret;
-@@ -197,7 +208,7 @@ static int rtl821x_probe(struct phy_devi
-       priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
-       if (priv->has_phycr2) {
--              ret = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR2);
-+              ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2);
-               if (ret < 0)
-                       return ret;
-@@ -233,7 +244,7 @@ static int rtl8211f_ack_interrupt(struct
- {
-       int err;
--      err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
-+      err = phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
-       return (err < 0) ? err : 0;
- }
-@@ -376,7 +387,7 @@ static irqreturn_t rtl8211f_handle_inter
- {
-       int irq_status;
--      irq_status = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
-+      irq_status = phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
-       if (irq_status < 0) {
-               phy_error(phydev);
-               return IRQ_NONE;
-@@ -473,7 +484,7 @@ static int rtl8211f_config_init(struct p
-       u16 val_txdly, val_rxdly;
-       int ret;
--      ret = phy_modify_paged_changed(phydev, 0xa43, RTL8211F_PHYCR1,
-+      ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
-                                      RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
-                                      priv->phycr1);
-       if (ret < 0) {
-@@ -507,7 +518,8 @@ static int rtl8211f_config_init(struct p
-               return 0;
-       }
--      ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
-+      ret = phy_modify_paged_changed(phydev, RTL8211F_RGMII_PAGE,
-+                                     RTL8211F_TXCR, RTL8211F_TX_DELAY,
-                                      val_txdly);
-       if (ret < 0) {
-               dev_err(dev, "Failed to update the TX delay register\n");
-@@ -522,7 +534,8 @@ static int rtl8211f_config_init(struct p
-                       str_enabled_disabled(val_txdly));
-       }
--      ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
-+      ret = phy_modify_paged_changed(phydev, RTL8211F_RGMII_PAGE,
-+                                     RTL8211F_RXCR, RTL8211F_RX_DELAY,
-                                      val_rxdly);
-       if (ret < 0) {
-               dev_err(dev, "Failed to update the RX delay register\n");
-@@ -538,14 +551,15 @@ static int rtl8211f_config_init(struct p
-       }
-       /* Disable PHY-mode EEE so LPI is passed to the MAC */
--      ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2,
-+      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
-                              RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
-       if (ret)
-               return ret;
-       if (priv->has_phycr2) {
--              ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2,
--                                     RTL8211F_CLKOUT_EN, priv->phycr2);
-+              ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
-+                                     RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
-+                                     priv->phycr2);
-               if (ret < 0) {
-                       dev_err(dev, "clkout configuration failed: %pe\n",
-                               ERR_PTR(ret));
diff --git a/target/linux/generic/backport-6.18/781-24-v6.16-net-phy-realtek-Group-RTL82-macro-definitions.patch b/target/linux/generic/backport-6.18/781-24-v6.16-net-phy-realtek-Group-RTL82-macro-definitions.patch
deleted file mode 100644 (file)
index 0319a2b..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-From 8c4d0172657c1f2d86b9c19172150abcd0e35c39 Mon Sep 17 00:00:00 2001
-From: Michael Klein <michael@fossekall.de>
-Date: Sun, 4 May 2025 19:29:14 +0200
-Subject: [PATCH] net: phy: realtek: Group RTL82* macro definitions
-
-Group macro definitions by PHY in lexicographic order. Within each PHY
-block, definitions are order by page number and then register number.
-
-Signed-off-by: Michael Klein <michael@fossekall.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250504172916.243185-5-michael@fossekall.de
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek/realtek_main.c | 72 +++++++++++++-------------
- 1 file changed, 37 insertions(+), 35 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -18,6 +18,16 @@
- #include "realtek.h"
-+#define RTL8201F_IER                          0x13
-+
-+#define RTL8201F_ISR                          0x1e
-+#define RTL8201F_ISR_ANERR                    BIT(15)
-+#define RTL8201F_ISR_DUPLEX                   BIT(13)
-+#define RTL8201F_ISR_LINK                     BIT(11)
-+#define RTL8201F_ISR_MASK                     (RTL8201F_ISR_ANERR | \
-+                                               RTL8201F_ISR_DUPLEX | \
-+                                               RTL8201F_ISR_LINK)
-+
- #define RTL821x_INER                          0x12
- #define RTL8211B_INER_INIT                    0x6400
- #define RTL8211E_INER_LINK_STATUS             BIT(10)
-@@ -30,9 +40,21 @@
- #define RTL821x_PAGE_SELECT                   0x1f
- #define RTL821x_SET_EXT_PAGE                  0x07
-+/* RTL8211E extension page 164/0xa4 */
-+#define RTL8211E_RGMII_EXT_PAGE                       0xa4
-+#define RTL8211E_RGMII_DELAY                  0x1c
-+#define RTL8211E_CTRL_DELAY                   BIT(13)
-+#define RTL8211E_TX_DELAY                     BIT(12)
-+#define RTL8211E_RX_DELAY                     BIT(11)
-+#define RTL8211E_DELAY_MASK                   GENMASK(13, 11)
-+
- /* RTL8211F PHY configuration */
- #define RTL8211F_PHYCR_PAGE                   0xa43
- #define RTL8211F_PHYCR1                               0x18
-+#define RTL8211F_ALDPS_PLL_OFF                        BIT(1)
-+#define RTL8211F_ALDPS_ENABLE                 BIT(2)
-+#define RTL8211F_ALDPS_XTAL_OFF                       BIT(12)
-+
- #define RTL8211F_PHYCR2                               0x19
- #define RTL8211F_CLKOUT_EN                    BIT(0)
- #define RTL8211F_PHYCR2_PHY_EEE_ENABLE                BIT(5)
-@@ -40,24 +62,6 @@
- #define RTL8211F_INSR_PAGE                    0xa43
- #define RTL8211F_INSR                         0x1d
--/* RTL8211F WOL interrupt configuration */
--#define RTL8211F_INTBCR_PAGE                  0xd40
--#define RTL8211F_INTBCR                               0x16
--#define RTL8211F_INTBCR_INTB_PMEB             BIT(5)
--
--/* RTL8211F WOL settings */
--#define RTL8211F_WOL_SETTINGS_PAGE            0xd8a
--#define RTL8211F_WOL_SETTINGS_EVENTS          16
--#define RTL8211F_WOL_EVENT_MAGIC              BIT(12)
--#define RTL8211F_WOL_SETTINGS_STATUS          17
--#define RTL8211F_WOL_STATUS_RESET             (BIT(15) | 0x1fff)
--
--/* RTL8211F Unique phyiscal and multicast address (WOL) */
--#define RTL8211F_PHYSICAL_ADDR_PAGE           0xd8c
--#define RTL8211F_PHYSICAL_ADDR_WORD0          16
--#define RTL8211F_PHYSICAL_ADDR_WORD1          17
--#define RTL8211F_PHYSICAL_ADDR_WORD2          18
--
- /* RTL8211F LED configuration */
- #define RTL8211F_LEDCR_PAGE                   0xd04
- #define RTL8211F_LEDCR                                0x10
-@@ -78,25 +82,23 @@
- #define RTL8211F_RXCR                         0x15
- #define RTL8211F_RX_DELAY                     BIT(3)
--#define RTL8211F_ALDPS_PLL_OFF                        BIT(1)
--#define RTL8211F_ALDPS_ENABLE                 BIT(2)
--#define RTL8211F_ALDPS_XTAL_OFF                       BIT(12)
-+/* RTL8211F WOL interrupt configuration */
-+#define RTL8211F_INTBCR_PAGE                  0xd40
-+#define RTL8211F_INTBCR                               0x16
-+#define RTL8211F_INTBCR_INTB_PMEB             BIT(5)
--#define RTL8211E_RGMII_EXT_PAGE                       0xa4
--#define RTL8211E_RGMII_DELAY                  0x1c
--#define RTL8211E_CTRL_DELAY                   BIT(13)
--#define RTL8211E_TX_DELAY                     BIT(12)
--#define RTL8211E_RX_DELAY                     BIT(11)
--#define RTL8211E_DELAY_MASK                   GENMASK(13, 11)
-+/* RTL8211F WOL settings */
-+#define RTL8211F_WOL_SETTINGS_PAGE            0xd8a
-+#define RTL8211F_WOL_SETTINGS_EVENTS          16
-+#define RTL8211F_WOL_EVENT_MAGIC              BIT(12)
-+#define RTL8211F_WOL_SETTINGS_STATUS          17
-+#define RTL8211F_WOL_STATUS_RESET             (BIT(15) | 0x1fff)
--#define RTL8201F_ISR                          0x1e
--#define RTL8201F_ISR_ANERR                    BIT(15)
--#define RTL8201F_ISR_DUPLEX                   BIT(13)
--#define RTL8201F_ISR_LINK                     BIT(11)
--#define RTL8201F_ISR_MASK                     (RTL8201F_ISR_ANERR | \
--                                               RTL8201F_ISR_DUPLEX | \
--                                               RTL8201F_ISR_LINK)
--#define RTL8201F_IER                          0x13
-+/* RTL8211F Unique phyiscal and multicast address (WOL) */
-+#define RTL8211F_PHYSICAL_ADDR_PAGE           0xd8c
-+#define RTL8211F_PHYSICAL_ADDR_WORD0          16
-+#define RTL8211F_PHYSICAL_ADDR_WORD1          17
-+#define RTL8211F_PHYSICAL_ADDR_WORD2          18
- #define RTL822X_VND1_SERDES_OPTION                    0x697a
- #define RTL822X_VND1_SERDES_OPTION_MODE_MASK          GENMASK(5, 0)
diff --git a/target/linux/generic/backport-6.18/781-25-v6.16-net-phy-realtek-use-__set_bit-in-rtl8211f_led_hw_con.patch b/target/linux/generic/backport-6.18/781-25-v6.16-net-phy-realtek-use-__set_bit-in-rtl8211f_led_hw_con.patch
deleted file mode 100644 (file)
index a9e3f90..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From be1cc96ddf82bb0c0a159751f73239d6d3e9594a Mon Sep 17 00:00:00 2001
-From: Michael Klein <michael@fossekall.de>
-Date: Sun, 4 May 2025 19:29:15 +0200
-Subject: [PATCH] net: phy: realtek: use __set_bit() in
- rtl8211f_led_hw_control_get()
-
-rtl8211f_led_hw_control_get() does not need atomic bit operations,
-replace set_bit() by __set_bit().
-
-Signed-off-by: Michael Klein <michael@fossekall.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250504172916.243185-6-michael@fossekall.de
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek/realtek_main.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -659,17 +659,17 @@ static int rtl8211f_led_hw_control_get(s
-       val &= RTL8211F_LEDCR_MASK;
-       if (val & RTL8211F_LEDCR_LINK_10)
--              set_bit(TRIGGER_NETDEV_LINK_10, rules);
-+              __set_bit(TRIGGER_NETDEV_LINK_10, rules);
-       if (val & RTL8211F_LEDCR_LINK_100)
--              set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+              __set_bit(TRIGGER_NETDEV_LINK_100, rules);
-       if (val & RTL8211F_LEDCR_LINK_1000)
--              set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+              __set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-       if (val & RTL8211F_LEDCR_ACT_TXRX) {
--              set_bit(TRIGGER_NETDEV_RX, rules);
--              set_bit(TRIGGER_NETDEV_TX, rules);
-+              __set_bit(TRIGGER_NETDEV_RX, rules);
-+              __set_bit(TRIGGER_NETDEV_TX, rules);
-       }
-       return 0;
diff --git a/target/linux/generic/backport-6.18/781-26-v6.16-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211E.patch b/target/linux/generic/backport-6.18/781-26-v6.16-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211E.patch
deleted file mode 100644 (file)
index a4b6450..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-From 708686132ba02659267c0cebcc414348ece389a5 Mon Sep 17 00:00:00 2001
-From: Michael Klein <michael@fossekall.de>
-Date: Sun, 4 May 2025 19:29:16 +0200
-Subject: [PATCH] net: phy: realtek: Add support for PHY LEDs on RTL8211E
-
-Like the RTL8211F, the RTL8211E PHY supports up to three LEDs.
-Add netdev trigger support for them, too.
-
-Signed-off-by: Michael Klein <michael@fossekall.de>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250504172916.243185-7-michael@fossekall.de
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek/realtek_main.c | 125 +++++++++++++++++++++++--
- 1 file changed, 119 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -40,6 +40,20 @@
- #define RTL821x_PAGE_SELECT                   0x1f
- #define RTL821x_SET_EXT_PAGE                  0x07
-+/* RTL8211E extension page 44/0x2c */
-+#define RTL8211E_LEDCR_EXT_PAGE                       0x2c
-+#define RTL8211E_LEDCR1                               0x1a
-+#define RTL8211E_LEDCR1_ACT_TXRX              BIT(4)
-+#define RTL8211E_LEDCR1_MASK                  BIT(4)
-+#define RTL8211E_LEDCR1_SHIFT                 1
-+
-+#define RTL8211E_LEDCR2                               0x1c
-+#define RTL8211E_LEDCR2_LINK_1000             BIT(2)
-+#define RTL8211E_LEDCR2_LINK_100              BIT(1)
-+#define RTL8211E_LEDCR2_LINK_10                       BIT(0)
-+#define RTL8211E_LEDCR2_MASK                  GENMASK(2, 0)
-+#define RTL8211E_LEDCR2_SHIFT                 4
-+
- /* RTL8211E extension page 164/0xa4 */
- #define RTL8211E_RGMII_EXT_PAGE                       0xa4
- #define RTL8211E_RGMII_DELAY                  0x1c
-@@ -145,7 +159,8 @@
- #define RTL_8221B_VN_CG                               0x001cc84a
- #define RTL_8251B                             0x001cc862
--#define RTL8211F_LED_COUNT                    3
-+/* RTL8211E and RTL8211F support up to three LEDs */
-+#define RTL8211x_LED_COUNT                    3
- MODULE_DESCRIPTION("Realtek PHY driver");
- MODULE_AUTHOR("Johnson Leung");
-@@ -169,6 +184,21 @@ static int rtl821x_write_page(struct phy
-       return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
- }
-+static int rtl821x_read_ext_page(struct phy_device *phydev, u16 ext_page,
-+                               u32 regnum)
-+{
-+      int oldpage, ret = 0;
-+
-+      oldpage = phy_select_page(phydev, RTL821x_SET_EXT_PAGE);
-+      if (oldpage >= 0) {
-+              ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, ext_page);
-+              if (ret == 0)
-+                      ret = __phy_read(phydev, regnum);
-+      }
-+
-+      return phy_restore_page(phydev, oldpage, ret);
-+}
-+
- static int rtl821x_modify_ext_page(struct phy_device *phydev, u16 ext_page,
-                                  u32 regnum, u16 mask, u16 set)
- {
-@@ -608,7 +638,7 @@ static int rtl821x_resume(struct phy_dev
-       return 0;
- }
--static int rtl8211f_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-                                       unsigned long rules)
- {
-       const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) |
-@@ -627,9 +657,11 @@ static int rtl8211f_led_hw_is_supported(
-        *      rates and Active indication always at all three 10+100+1000
-        *      link rates.
-        * This code currently uses mode B only.
-+       *
-+       * RTL8211E PHY LED has one mode, which works like RTL8211F mode B.
-        */
--      if (index >= RTL8211F_LED_COUNT)
-+      if (index >= RTL8211x_LED_COUNT)
-               return -EINVAL;
-       /* Filter out any other unsupported triggers. */
-@@ -648,7 +680,7 @@ static int rtl8211f_led_hw_control_get(s
- {
-       int val;
--      if (index >= RTL8211F_LED_COUNT)
-+      if (index >= RTL8211x_LED_COUNT)
-               return -EINVAL;
-       val = phy_read_paged(phydev, 0xd04, RTL8211F_LEDCR);
-@@ -681,7 +713,7 @@ static int rtl8211f_led_hw_control_set(s
-       const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
-       u16 reg = 0;
--      if (index >= RTL8211F_LED_COUNT)
-+      if (index >= RTL8211x_LED_COUNT)
-               return -EINVAL;
-       if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-@@ -704,6 +736,84 @@ static int rtl8211f_led_hw_control_set(s
-       return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
- }
-+static int rtl8211e_led_hw_control_get(struct phy_device *phydev, u8 index,
-+                                     unsigned long *rules)
-+{
-+      int ret;
-+      u16 cr1, cr2;
-+
-+      if (index >= RTL8211x_LED_COUNT)
-+              return -EINVAL;
-+
-+      ret = rtl821x_read_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE,
-+                                  RTL8211E_LEDCR1);
-+      if (ret < 0)
-+              return ret;
-+
-+      cr1 = ret >> RTL8211E_LEDCR1_SHIFT * index;
-+      if (cr1 & RTL8211E_LEDCR1_ACT_TXRX) {
-+              __set_bit(TRIGGER_NETDEV_RX, rules);
-+              __set_bit(TRIGGER_NETDEV_TX, rules);
-+      }
-+
-+      ret = rtl821x_read_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE,
-+                                  RTL8211E_LEDCR2);
-+      if (ret < 0)
-+              return ret;
-+
-+      cr2 = ret >> RTL8211E_LEDCR2_SHIFT * index;
-+      if (cr2 & RTL8211E_LEDCR2_LINK_10)
-+              __set_bit(TRIGGER_NETDEV_LINK_10, rules);
-+
-+      if (cr2 & RTL8211E_LEDCR2_LINK_100)
-+              __set_bit(TRIGGER_NETDEV_LINK_100, rules);
-+
-+      if (cr2 & RTL8211E_LEDCR2_LINK_1000)
-+              __set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+
-+      return ret;
-+}
-+
-+static int rtl8211e_led_hw_control_set(struct phy_device *phydev, u8 index,
-+                                     unsigned long rules)
-+{
-+      const u16 cr1mask =
-+              RTL8211E_LEDCR1_MASK << (RTL8211E_LEDCR1_SHIFT * index);
-+      const u16 cr2mask =
-+              RTL8211E_LEDCR2_MASK << (RTL8211E_LEDCR2_SHIFT * index);
-+      u16 cr1 = 0, cr2 = 0;
-+      int ret;
-+
-+      if (index >= RTL8211x_LED_COUNT)
-+              return -EINVAL;
-+
-+      if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
-+          test_bit(TRIGGER_NETDEV_TX, &rules)) {
-+              cr1 |= RTL8211E_LEDCR1_ACT_TXRX;
-+      }
-+
-+      cr1 <<= RTL8211E_LEDCR1_SHIFT * index;
-+      ret = rtl821x_modify_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE,
-+                                    RTL8211E_LEDCR1, cr1mask, cr1);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+              cr2 |= RTL8211E_LEDCR2_LINK_10;
-+
-+      if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+              cr2 |= RTL8211E_LEDCR2_LINK_100;
-+
-+      if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+              cr2 |= RTL8211E_LEDCR2_LINK_1000;
-+
-+      cr2 <<= RTL8211E_LEDCR2_SHIFT * index;
-+      ret = rtl821x_modify_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE,
-+                                    RTL8211E_LEDCR2, cr2mask, cr2);
-+
-+      return ret;
-+}
-+
- static int rtl8211e_config_init(struct phy_device *phydev)
- {
-       u16 val;
-@@ -1479,6 +1589,9 @@ static struct phy_driver realtek_drvs[]
-               .resume         = genphy_resume,
-               .read_page      = rtl821x_read_page,
-               .write_page     = rtl821x_write_page,
-+              .led_hw_is_supported = rtl8211x_led_hw_is_supported,
-+              .led_hw_control_get = rtl8211e_led_hw_control_get,
-+              .led_hw_control_set = rtl8211e_led_hw_control_set,
-       }, {
-               PHY_ID_MATCH_EXACT(0x001cc916),
-               .name           = "RTL8211F Gigabit Ethernet",
-@@ -1494,7 +1607,7 @@ static struct phy_driver realtek_drvs[]
-               .read_page      = rtl821x_read_page,
-               .write_page     = rtl821x_write_page,
-               .flags          = PHY_ALWAYS_CALL_SUSPEND,
--              .led_hw_is_supported = rtl8211f_led_hw_is_supported,
-+              .led_hw_is_supported = rtl8211x_led_hw_is_supported,
-               .led_hw_control_get = rtl8211f_led_hw_control_get,
-               .led_hw_control_set = rtl8211f_led_hw_control_set,
-       }, {
diff --git a/target/linux/generic/backport-6.18/781-27-v6.16-net-phy-realtek-add-RTL8127-internal-PHY.patch b/target/linux/generic/backport-6.18/781-27-v6.16-net-phy-realtek-add-RTL8127-internal-PHY.patch
deleted file mode 100644 (file)
index 04c631d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 83d9623161283f5f6883ee3fdb88ef2177b8a5f1 Mon Sep 17 00:00:00 2001
-From: ChunHao Lin <hau@realtek.com>
-Date: Fri, 16 May 2025 13:56:22 +0800
-Subject: [PATCH] net: phy: realtek: add RTL8127-internal PHY
-
-RTL8127-internal PHY is RTL8261C which is a integrated 10Gbps PHY with ID
-0x001cc890. It follows the code path of RTL8125/RTL8126 internal NBase-T
-PHY.
-
-Signed-off-by: ChunHao Lin <hau@realtek.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250516055622.3772-1-hau@realtek.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -158,6 +158,7 @@
- #define RTL_8221B_VB_CG                               0x001cc849
- #define RTL_8221B_VN_CG                               0x001cc84a
- #define RTL_8251B                             0x001cc862
-+#define RTL_8261C                             0x001cc890
- /* RTL8211E and RTL8211F support up to three LEDs */
- #define RTL8211x_LED_COUNT                    3
-@@ -1370,6 +1371,7 @@ static int rtl_internal_nbaset_match_phy
-       case RTL_GENERIC_PHYID:
-       case RTL_8221B:
-       case RTL_8251B:
-+      case RTL_8261C:
-       case 0x001cc841:
-               break;
-       default:
diff --git a/target/linux/generic/backport-6.18/781-28-v6.18-net-phy-realtek-convert-RTL8226-CG-to-c45-only.patch b/target/linux/generic/backport-6.18/781-28-v6.18-net-phy-realtek-convert-RTL8226-CG-to-c45-only.patch
deleted file mode 100644 (file)
index 43f2c7b..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-From 34167f1a024d2c5abae0b0325a6d0b8257160f86 Mon Sep 17 00:00:00 2001
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-Date: Wed, 13 Aug 2025 01:44:07 -0400
-Subject: net: phy: realtek: convert RTL8226-CG to c45 only
-
-Short: Convert the RTL8226-CG to c45 so it can be used in its
-Realtek based ecosystems.
-
-Long: The RTL8226-CG can be mainly found on devices of the
-Realtek Otto switch platform. Devices like the Zyxel XGS1210-12
-are based on it. These implement a hardware based phy polling
-in the background to update SoC status registers.
-
-The hardware provides 4 smi busses where phys are attached to.
-For each bus one can decide if it is polled in c45 or c22 mode.
-See https://svanheule.net/realtek/longan/register/smi_glb_ctrl
-With this setting the register access will be limited by the
-hardware. This is very complex (including caching and special
-c45-over-c22 handling). But basically it boils down to "enable
-protocol x and SoC will disable register access via protocol y".
-
-Mainline already gained support for the rtl9300 mdio driver
-in commit 24e31e474769 ("net: mdio: Add RTL9300 MDIO driver").
-
-It covers the basic features, but a lot effort is still needed
-to understand hardware properly. So it runs a simple setup by
-selecting the proper bus mode during startup.
-
-       /* Put the interfaces into C45 mode if required */
-       glb_ctrl_mask = GENMASK(19, 16);
-       for (i = 0; i < MAX_SMI_BUSSES; i++)
-               if (priv->smi_bus_is_c45[i])
-                       glb_ctrl_val |= GLB_CTRL_INTF_SEL(i);
-       ...
-       err = regmap_update_bits(regmap, SMI_GLB_CTRL,
-                                glb_ctrl_mask, glb_ctrl_val);
-
-To avoid complex coding later on, it limits access by only
-providing either c22 or c45:
-
-       bus->name = "Realtek Switch MDIO Bus";
-       if (priv->smi_bus_is_c45[mdio_bus]) {
-               bus->read_c45 = rtl9300_mdio_read_c45;
-               bus->write_c45 =  rtl9300_mdio_write_c45;
-       } else {
-               bus->read = rtl9300_mdio_read_c22;
-               bus->write = rtl9300_mdio_write_c22;
-       }
-
-Because of these limitations the existing RTL8226 phy driver
-is not working at all on Realtek switches. Convert the driver
-to c45-only.
-
-Luckily the RTL8226 seems to support proper MDIO_PMA_EXTABLE
-flags. So standard function genphy_c45_pma_read_abilities() can
-call genphy_c45_pma_read_ext_abilities() and 10/100/1000 is
-populated right. Thus conversion is straight forward.
-
-Outputs before - REMARK: For this a "hacked" bus was used that
-toggles the mode for each c22/c45 access. But that is slow and
-produces unstable data in the SoC status registers).
-
-Settings for lan9:
-        Supported ports: [ TP MII ]
-        Supported link modes:   10baseT/Half 10baseT/Full
-                                100baseT/Half 100baseT/Full
-                                1000baseT/Full
-                                2500baseT/Full
-        Supported pause frame use: Symmetric Receive-only
-        Supports auto-negotiation: Yes
-        Supported FEC modes: Not reported
-        Advertised link modes:  10baseT/Half 10baseT/Full
-                                100baseT/Half 100baseT/Full
-                                1000baseT/Full
-                                2500baseT/Full
-        Advertised pause frame use: Symmetric Receive-only
-        Advertised auto-negotiation: Yes
-        Advertised FEC modes: Not reported
-        Speed: Unknown!
-        Duplex: Unknown! (255)
-        Port: Twisted Pair
-        PHYAD: 24
-        Transceiver: external
-        Auto-negotiation: on
-        MDI-X: Unknown
-        Supports Wake-on: d
-        Wake-on: d
-        Link detected: no
-
-Outputs with this commit:
-
-Settings for lan9:
-        Supported ports: [ TP ]
-        Supported link modes:   10baseT/Half 10baseT/Full
-                                100baseT/Half 100baseT/Full
-                                1000baseT/Full
-                                2500baseT/Full
-        Supported pause frame use: Symmetric Receive-only
-        Supports auto-negotiation: Yes
-        Supported FEC modes: Not reported
-        Advertised link modes:  10baseT/Half 10baseT/Full
-                                100baseT/Half 100baseT/Full
-                                1000baseT/Full
-                                2500baseT/Full
-        Advertised pause frame use: Symmetric Receive-only
-        Advertised auto-negotiation: Yes
-        Advertised FEC modes: Not reported
-        Speed: Unknown!
-        Duplex: Unknown! (255)
-        Port: Twisted Pair
-        PHYAD: 24
-        Transceiver: external
-        Auto-negotiation: on
-        MDI-X: Unknown
-        Supports Wake-on: d
-        Wake-on: d
-        Link detected: no
-
-Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Link: https://patch.msgid.link/20250813054407.1108285-1-markus.stockhausen@gmx.de
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 28 +++++++++++++++++++++-------
- 1 file changed, 21 insertions(+), 7 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1274,6 +1274,21 @@ static int rtl822x_c45_read_status(struc
-       return 0;
- }
-+static int rtl822x_c45_soft_reset(struct phy_device *phydev)
-+{
-+      int ret, val;
-+
-+      ret = phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1,
-+                           MDIO_CTRL1_RESET, MDIO_CTRL1_RESET);
-+      if (ret < 0)
-+              return ret;
-+
-+      return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PMAPMD,
-+                                       MDIO_CTRL1, val,
-+                                       !(val & MDIO_CTRL1_RESET),
-+                                       5000, 100000, true);
-+}
-+
- static int rtl822xb_c45_read_status(struct phy_device *phydev)
- {
-       int ret;
-@@ -1660,13 +1675,12 @@ static struct phy_driver realtek_drvs[]
-       }, {
-               PHY_ID_MATCH_EXACT(0x001cc838),
-               .name           = "RTL8226-CG 2.5Gbps PHY",
--              .get_features   = rtl822x_get_features,
--              .config_aneg    = rtl822x_config_aneg,
--              .read_status    = rtl822x_read_status,
--              .suspend        = genphy_suspend,
--              .resume         = rtlgen_resume,
--              .read_page      = rtl821x_read_page,
--              .write_page     = rtl821x_write_page,
-+              .soft_reset     = rtl822x_c45_soft_reset,
-+              .get_features   = rtl822x_c45_get_features,
-+              .config_aneg    = rtl822x_c45_config_aneg,
-+              .read_status    = rtl822x_c45_read_status,
-+              .suspend        = genphy_c45_pma_suspend,
-+              .resume         = rtlgen_c45_resume,
-       }, {
-               PHY_ID_MATCH_EXACT(0x001cc848),
-               .name           = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
diff --git a/target/linux/generic/backport-6.18/781-29-v6.18-net-phy-realtek-enable-serdes-option-mode-for-RTL8226-CG.patch b/target/linux/generic/backport-6.18/781-29-v6.18-net-phy-realtek-enable-serdes-option-mode-for-RTL8226-CG.patch
deleted file mode 100644 (file)
index 9ffb260..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-From 3a752e67800106a5c42d802d67e06c60aa71d07b Mon Sep 17 00:00:00 2001
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-Date: Fri, 15 Aug 2025 04:20:09 -0400
-Subject: net: phy: realtek: enable serdes option mode for RTL8226-CG
-
-The RTL8226-CG can make use of the serdes option mode feature to
-dynamically switch between SGMII and 2500base-X. From what is
-known the setup sequence is much simpler with no magic values.
-
-Convert the exiting config_init() into a helper that configures
-the PHY depending on generation 1 or 2. Call the helper from two
-separated new config_init() functions.
-
-Finally convert the phy_driver specs of the RTL8226-CG to make
-use of the new configuration and switch over to the extended
-read_status() function to dynamically change the interface
-according to the serdes mode.
-
-Remark! The logic could be simpler if the serdes mode could be
-set before all other generation 2 magic values. Due to missing
-RTL8221B test hardware the mmd command order was kept.
-
-Tested on Zyxel XGS1210-12.
-
-Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Link: https://patch.msgid.link/20250815082009.3678865-1-markus.stockhausen@gmx.de
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 26 ++++++++++++++++++++------
- 1 file changed, 20 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1032,7 +1032,7 @@ static int rtl822x_probe(struct phy_devi
-       return 0;
- }
--static int rtl822xb_config_init(struct phy_device *phydev)
-+static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1)
- {
-       bool has_2500, has_sgmii;
-       u16 mode;
-@@ -1067,15 +1067,18 @@ static int rtl822xb_config_init(struct p
-       /* the following sequence with magic numbers sets up the SerDes
-        * option mode
-        */
--      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
--      if (ret < 0)
--              return ret;
-+
-+      if (!gen1) {
-+              ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
-+              if (ret < 0)
-+                      return ret;
-+      }
-       ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1,
-                                    RTL822X_VND1_SERDES_OPTION,
-                                    RTL822X_VND1_SERDES_OPTION_MODE_MASK,
-                                    mode);
--      if (ret < 0)
-+      if (gen1 || ret < 0)
-               return ret;
-       ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
-@@ -1089,6 +1092,16 @@ static int rtl822xb_config_init(struct p
-       return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
- }
-+static int rtl822x_config_init(struct phy_device *phydev)
-+{
-+      return rtl822x_set_serdes_option_mode(phydev, true);
-+}
-+
-+static int rtl822xb_config_init(struct phy_device *phydev)
-+{
-+      return rtl822x_set_serdes_option_mode(phydev, false);
-+}
-+
- static int rtl822xb_get_rate_matching(struct phy_device *phydev,
-                                     phy_interface_t iface)
- {
-@@ -1678,7 +1691,8 @@ static struct phy_driver realtek_drvs[]
-               .soft_reset     = rtl822x_c45_soft_reset,
-               .get_features   = rtl822x_c45_get_features,
-               .config_aneg    = rtl822x_c45_config_aneg,
--              .read_status    = rtl822x_c45_read_status,
-+              .config_init    = rtl822x_config_init,
-+              .read_status    = rtl822xb_c45_read_status,
-               .suspend        = genphy_c45_pma_suspend,
-               .resume         = rtlgen_c45_resume,
-       }, {
diff --git a/target/linux/generic/backport-6.18/782-01-v6.16-net-phy-pass-PHY-driver-to-.match_phy_device-OP.patch b/target/linux/generic/backport-6.18/782-01-v6.16-net-phy-pass-PHY-driver-to-.match_phy_device-OP.patch
deleted file mode 100644 (file)
index c22231e..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-From 31afd6bc55cc0093c3e5b0a368319e423d4de8ea Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 17 May 2025 22:13:45 +0200
-Subject: [PATCH] net: phy: pass PHY driver to .match_phy_device OP
-
-Pass PHY driver pointer to .match_phy_device OP in addition to phydev.
-Having access to the PHY driver struct might be useful to check the
-PHY ID of the driver is being matched for in case the PHY ID scanned in
-the phydev is not consistent.
-
-A scenario for this is a PHY that change PHY ID after a firmware is
-loaded, in such case, the PHY ID stored in PHY device struct is not
-valid anymore and PHY will manually scan the ID in the match_phy_device
-function.
-
-Having the PHY driver info is also useful for those PHY driver that
-implement multiple simple .match_phy_device OP to match specific MMD PHY
-ID. With this extra info if the parsing logic is the same, the matching
-function can be generalized by using the phy_id in the PHY driver
-instead of hardcoding.
-
-Rust wrapper callback is updated to align to the new match_phy_device
-arguments.
-
-Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Benno Lossin <lossin@kernel.org> # for Rust
-Reviewed-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
-Link: https://patch.msgid.link/20250517201353.5137-2-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/bcm87xx.c              |  6 ++++--
- drivers/net/phy/icplus.c               |  6 ++++--
- drivers/net/phy/marvell10g.c           | 12 ++++++++----
- drivers/net/phy/micrel.c               |  6 ++++--
- drivers/net/phy/nxp-c45-tja11xx.c      | 12 ++++++++----
- drivers/net/phy/nxp-tja11xx.c          |  6 ++++--
- drivers/net/phy/phy_device.c           |  2 +-
- drivers/net/phy/realtek/realtek_main.c | 27 +++++++++++++++++---------
- drivers/net/phy/teranetics.c           |  3 ++-
- include/linux/phy.h                    |  3 ++-
- rust/kernel/net/phy.rs                 |  1 +
- 11 files changed, 56 insertions(+), 28 deletions(-)
-
---- a/drivers/net/phy/bcm87xx.c
-+++ b/drivers/net/phy/bcm87xx.c
-@@ -185,12 +185,14 @@ static irqreturn_t bcm87xx_handle_interr
-       return IRQ_HANDLED;
- }
--static int bcm8706_match_phy_device(struct phy_device *phydev)
-+static int bcm8706_match_phy_device(struct phy_device *phydev,
-+                                  const struct phy_driver *phydrv)
- {
-       return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706;
- }
--static int bcm8727_match_phy_device(struct phy_device *phydev)
-+static int bcm8727_match_phy_device(struct phy_device *phydev,
-+                                  const struct phy_driver *phydrv)
- {
-       return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727;
- }
---- a/drivers/net/phy/icplus.c
-+++ b/drivers/net/phy/icplus.c
-@@ -520,12 +520,14 @@ static int ip101a_g_match_phy_device(str
-       return ip101a == !ret;
- }
--static int ip101a_match_phy_device(struct phy_device *phydev)
-+static int ip101a_match_phy_device(struct phy_device *phydev,
-+                                 const struct phy_driver *phydrv)
- {
-       return ip101a_g_match_phy_device(phydev, true);
- }
--static int ip101g_match_phy_device(struct phy_device *phydev)
-+static int ip101g_match_phy_device(struct phy_device *phydev,
-+                                 const struct phy_driver *phydrv)
- {
-       return ip101a_g_match_phy_device(phydev, false);
- }
---- a/drivers/net/phy/marvell10g.c
-+++ b/drivers/net/phy/marvell10g.c
-@@ -1284,7 +1284,8 @@ static int mv3310_get_number_of_ports(st
-       return ret + 1;
- }
--static int mv3310_match_phy_device(struct phy_device *phydev)
-+static int mv3310_match_phy_device(struct phy_device *phydev,
-+                                 const struct phy_driver *phydrv)
- {
-       if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
-            MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310)
-@@ -1293,7 +1294,8 @@ static int mv3310_match_phy_device(struc
-       return mv3310_get_number_of_ports(phydev) == 1;
- }
--static int mv3340_match_phy_device(struct phy_device *phydev)
-+static int mv3340_match_phy_device(struct phy_device *phydev,
-+                                 const struct phy_driver *phydrv)
- {
-       if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
-            MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310)
-@@ -1317,12 +1319,14 @@ static int mv211x_match_phy_device(struc
-       return !!(val & MDIO_PCS_SPEED_5G) == has_5g;
- }
--static int mv2110_match_phy_device(struct phy_device *phydev)
-+static int mv2110_match_phy_device(struct phy_device *phydev,
-+                                 const struct phy_driver *phydrv)
- {
-       return mv211x_match_phy_device(phydev, true);
- }
--static int mv2111_match_phy_device(struct phy_device *phydev)
-+static int mv2111_match_phy_device(struct phy_device *phydev,
-+                                 const struct phy_driver *phydrv)
- {
-       return mv211x_match_phy_device(phydev, false);
- }
---- a/drivers/net/phy/micrel.c
-+++ b/drivers/net/phy/micrel.c
-@@ -768,7 +768,8 @@ static int ksz8051_ksz8795_match_phy_dev
-               return !ret;
- }
--static int ksz8051_match_phy_device(struct phy_device *phydev)
-+static int ksz8051_match_phy_device(struct phy_device *phydev,
-+                                  const struct phy_driver *phydrv)
- {
-       return ksz8051_ksz8795_match_phy_device(phydev, true);
- }
-@@ -888,7 +889,8 @@ static int ksz8061_config_init(struct ph
-       return kszphy_config_init(phydev);
- }
--static int ksz8795_match_phy_device(struct phy_device *phydev)
-+static int ksz8795_match_phy_device(struct phy_device *phydev,
-+                                  const struct phy_driver *phydrv)
- {
-       return ksz8051_ksz8795_match_phy_device(phydev, false);
- }
---- a/drivers/net/phy/nxp-c45-tja11xx.c
-+++ b/drivers/net/phy/nxp-c45-tja11xx.c
-@@ -1944,13 +1944,15 @@ static int nxp_c45_macsec_ability(struct
-       return macsec_ability;
- }
--static int tja1103_match_phy_device(struct phy_device *phydev)
-+static int tja1103_match_phy_device(struct phy_device *phydev,
-+                                  const struct phy_driver *phydrv)
- {
-       return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) &&
-              !nxp_c45_macsec_ability(phydev);
- }
--static int tja1104_match_phy_device(struct phy_device *phydev)
-+static int tja1104_match_phy_device(struct phy_device *phydev,
-+                                  const struct phy_driver *phydrv)
- {
-       return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) &&
-              nxp_c45_macsec_ability(phydev);
---- a/drivers/net/phy/nxp-tja11xx.c
-+++ b/drivers/net/phy/nxp-tja11xx.c
-@@ -646,12 +646,14 @@ static int tja1102_match_phy_device(stru
-       return !ret;
- }
--static int tja1102_p0_match_phy_device(struct phy_device *phydev)
-+static int tja1102_p0_match_phy_device(struct phy_device *phydev,
-+                                     const struct phy_driver *phydrv)
- {
-       return tja1102_match_phy_device(phydev, true);
- }
--static int tja1102_p1_match_phy_device(struct phy_device *phydev)
-+static int tja1102_p1_match_phy_device(struct phy_device *phydev,
-+                                     const struct phy_driver *phydrv)
- {
-       return tja1102_match_phy_device(phydev, false);
- }
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -600,7 +600,7 @@ static int phy_bus_match(struct device *
-               return 0;
-       if (phydrv->match_phy_device)
--              return phydrv->match_phy_device(phydev);
-+              return phydrv->match_phy_device(phydev, phydrv);
-       if (phydev->is_c45) {
-               for (i = 1; i < num_ids; i++) {
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -1343,13 +1343,15 @@ static bool rtlgen_supports_mmd(struct p
-       return val > 0;
- }
--static int rtlgen_match_phy_device(struct phy_device *phydev)
-+static int rtlgen_match_phy_device(struct phy_device *phydev,
-+                                 const struct phy_driver *phydrv)
- {
-       return phydev->phy_id == RTL_GENERIC_PHYID &&
-              !rtlgen_supports_2_5gbps(phydev);
- }
--static int rtl8226_match_phy_device(struct phy_device *phydev)
-+static int rtl8226_match_phy_device(struct phy_device *phydev,
-+                                  const struct phy_driver *phydrv)
- {
-       return phydev->phy_id == RTL_GENERIC_PHYID &&
-              rtlgen_supports_2_5gbps(phydev) &&
-@@ -1365,32 +1367,38 @@ static int rtlgen_is_c45_match(struct ph
-               return !is_c45 && (id == phydev->phy_id);
- }
--static int rtl8221b_match_phy_device(struct phy_device *phydev)
-+static int rtl8221b_match_phy_device(struct phy_device *phydev,
-+                                   const struct phy_driver *phydrv)
- {
-       return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
- }
--static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
-+static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev,
-+                                             const struct phy_driver *phydrv)
- {
-       return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
- }
--static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
-+static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev,
-+                                             const struct phy_driver *phydrv)
- {
-       return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
- }
--static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
-+static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev,
-+                                             const struct phy_driver *phydrv)
- {
-       return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
- }
--static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
-+static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev,
-+                                             const struct phy_driver *phydrv)
- {
-       return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
- }
--static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev)
-+static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev,
-+                                              const struct phy_driver *phydrv)
- {
-       if (phydev->is_c45)
-               return false;
-@@ -1409,7 +1417,8 @@ static int rtl_internal_nbaset_match_phy
-       return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev);
- }
--static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
-+static int rtl8251b_c45_match_phy_device(struct phy_device *phydev,
-+                                       const struct phy_driver *phydrv)
- {
-       return rtlgen_is_c45_match(phydev, RTL_8251B, true);
- }
---- a/drivers/net/phy/teranetics.c
-+++ b/drivers/net/phy/teranetics.c
-@@ -67,7 +67,8 @@ static int teranetics_read_status(struct
-       return 0;
- }
--static int teranetics_match_phy_device(struct phy_device *phydev)
-+static int teranetics_match_phy_device(struct phy_device *phydev,
-+                                     const struct phy_driver *phydrv)
- {
-       return phydev->c45_ids.device_ids[3] == PHY_ID_TN2020;
- }
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1045,7 +1045,8 @@ struct phy_driver {
-        * driver for the given phydev.  If NULL, matching is based on
-        * phy_id and phy_id_mask.
-        */
--      int (*match_phy_device)(struct phy_device *phydev);
-+      int (*match_phy_device)(struct phy_device *phydev,
-+                              const struct phy_driver *phydrv);
-       /**
-        * @set_wol: Some devices (e.g. qnap TS-119P II) require PHY
---- a/rust/kernel/net/phy.rs
-+++ b/rust/kernel/net/phy.rs
-@@ -421,6 +421,7 @@ impl<T: Driver> Adapter<T> {
-     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
-     unsafe extern "C" fn match_phy_device_callback(
-         phydev: *mut bindings::phy_device,
-+        _phydrv: *const bindings::phy_driver,
-     ) -> crate::ffi::c_int {
-         // SAFETY: This callback is called only in contexts
-         // where we hold `phy_device->lock`, so the accessors on
diff --git a/target/linux/generic/backport-6.18/782-04-v6.16-net-phy-introduce-genphy_match_phy_device.patch b/target/linux/generic/backport-6.18/782-04-v6.16-net-phy-introduce-genphy_match_phy_device.patch
deleted file mode 100644 (file)
index fed9d3c..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-From d6c45707ac84c2d9f274ece1cea4dddb97996bde Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 17 May 2025 22:13:48 +0200
-Subject: [PATCH 4/5] net: phy: introduce genphy_match_phy_device()
-
-Introduce new API, genphy_match_phy_device(), to provide a way to check
-to match a PHY driver for a PHY device based on the info stored in the
-PHY device struct.
-
-The function generalize the logic used in phy_bus_match() to check the
-PHY ID whether if C45 or C22 ID should be used for matching.
-
-This is useful for custom .match_phy_device function that wants to use
-the generic logic under some condition. (example a PHY is already setup
-and provide the correct PHY ID)
-
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://patch.msgid.link/20250517201353.5137-5-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/phy_device.c | 52 +++++++++++++++++++++++++-----------
- include/linux/phy.h          |  3 +++
- 2 files changed, 40 insertions(+), 15 deletions(-)
-
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -589,20 +589,26 @@ static int phy_scan_fixups(struct phy_de
-       return 0;
- }
--static int phy_bus_match(struct device *dev, const struct device_driver *drv)
-+/**
-+ * genphy_match_phy_device - match a PHY device with a PHY driver
-+ * @phydev: target phy_device struct
-+ * @phydrv: target phy_driver struct
-+ *
-+ * Description: Checks whether the given PHY device matches the specified
-+ * PHY driver. For Clause 45 PHYs, iterates over the available device
-+ * identifiers and compares them against the driver's expected PHY ID,
-+ * applying the provided mask. For Clause 22 PHYs, a direct ID comparison
-+ * is performed.
-+ *
-+ * Return: 1 if the PHY device matches the driver, 0 otherwise.
-+ */
-+int genphy_match_phy_device(struct phy_device *phydev,
-+                          const struct phy_driver *phydrv)
- {
--      struct phy_device *phydev = to_phy_device(dev);
--      const struct phy_driver *phydrv = to_phy_driver(drv);
--      const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
--      int i;
--
--      if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY))
--              return 0;
--
--      if (phydrv->match_phy_device)
--              return phydrv->match_phy_device(phydev, phydrv);
--
-       if (phydev->is_c45) {
-+              const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
-+              int i;
-+
-               for (i = 1; i < num_ids; i++) {
-                       if (phydev->c45_ids.device_ids[i] == 0xffffffff)
-                               continue;
-@@ -611,11 +617,27 @@ static int phy_bus_match(struct device *
-                                          phydrv->phy_id, phydrv->phy_id_mask))
-                               return 1;
-               }
-+
-               return 0;
--      } else {
--              return phy_id_compare(phydev->phy_id, phydrv->phy_id,
--                                    phydrv->phy_id_mask);
-       }
-+
-+      return phy_id_compare(phydev->phy_id, phydrv->phy_id,
-+                            phydrv->phy_id_mask);
-+}
-+EXPORT_SYMBOL_GPL(genphy_match_phy_device);
-+
-+static int phy_bus_match(struct device *dev, const struct device_driver *drv)
-+{
-+      struct phy_device *phydev = to_phy_device(dev);
-+      const struct phy_driver *phydrv = to_phy_driver(drv);
-+
-+      if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY))
-+              return 0;
-+
-+      if (phydrv->match_phy_device)
-+              return phydrv->match_phy_device(phydev, phydrv);
-+
-+      return genphy_match_phy_device(phydev, phydrv);
- }
- static ssize_t
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1963,6 +1963,9 @@ char *phy_attached_info_irq(struct phy_d
-       __malloc;
- void phy_attached_info(struct phy_device *phydev);
-+int genphy_match_phy_device(struct phy_device *phydev,
-+                          const struct phy_driver *phydrv);
-+
- /* Clause 22 PHY */
- int genphy_read_abilities(struct phy_device *phydev);
- int genphy_setup_forced(struct phy_device *phydev);
diff --git a/target/linux/generic/backport-6.18/782-05-v6.16-net-phy-Add-support-for-Aeonsemi-AS21xxx-PHYs.patch b/target/linux/generic/backport-6.18/782-05-v6.16-net-phy-Add-support-for-Aeonsemi-AS21xxx-PHYs.patch
deleted file mode 100644 (file)
index f1bcb35..0000000
+++ /dev/null
@@ -1,1180 +0,0 @@
-From 830877d89edcd834e4b4d0fcc021ff619d89505e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 17 May 2025 22:13:49 +0200
-Subject: [PATCH 5/5] net: phy: Add support for Aeonsemi AS21xxx PHYs
-
-Add support for Aeonsemi AS21xxx 10G C45 PHYs. These PHYs integrate
-an IPC to setup some configuration and require special handling to
-sync with the parity bit. The parity bit is a way the IPC use to
-follow correct order of command sent.
-
-Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1,
-AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1,
-AS21210PB1 that all register with the PHY ID 0x7500 0x7510
-before the firmware is loaded.
-
-They all support up to 5 LEDs with various HW mode supported.
-
-While implementing it was found some strange coincidence with using the
-same logic for implementing C22 in MMD regs in Broadcom PHYs.
-
-For reference here the AS21xxx PHY name logic:
-
-AS21x1xxB1
-    ^ ^^
-    | |J: Supports SyncE/PTP
-    | |P: No SyncE/PTP support
-    | 1: Supports 2nd Serdes
-    | 2: Not 2nd Serdes support
-    0: 10G, 5G, 2.5G
-    5: 5G, 2.5G
-    2: 2.5G
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://patch.msgid.link/20250517201353.5137-6-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- MAINTAINERS               |    6 +
- drivers/net/phy/Kconfig   |   12 +
- drivers/net/phy/Makefile  |    1 +
- drivers/net/phy/as21xxx.c | 1087 +++++++++++++++++++++++++++++++++++++
- 4 files changed, 1106 insertions(+)
- create mode 100644 drivers/net/phy/as21xxx.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -637,6 +637,12 @@ F:        drivers/iio/accel/adxl380.h
- F:    drivers/iio/accel/adxl380_i2c.c
- F:    drivers/iio/accel/adxl380_spi.c
-+AEONSEMI PHY DRIVER
-+M:    Christian Marangi <ansuelsmth@gmail.com>
-+L:    netdev@vger.kernel.org
-+S:    Maintained
-+F:    drivers/net/phy/as21xxx.c
-+
- AF8133J THREE-AXIS MAGNETOMETER DRIVER
- M:    Ondřej Jirman <megi@xff.cz>
- S:    Maintained
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -79,6 +79,18 @@ config SFP
- comment "MII PHY device drivers"
-+config AS21XXX_PHY
-+      tristate "Aeonsemi AS21xxx PHYs"
-+      help
-+        Currently supports the Aeonsemi AS21xxx PHY.
-+
-+        These are C45 PHYs 10G that require all a generic firmware.
-+
-+        Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1,
-+        AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1,
-+        AS21210PB1 that all register with the PHY ID 0x7500 0x7500
-+        before the firmware is loaded.
-+
- config AIR_EN8811H_PHY
-       tristate "Airoha EN8811H 2.5 Gigabit PHY"
-       help
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -39,6 +39,7 @@ obj-$(CONFIG_AIR_EN8811H_PHY)   += air_e
- obj-$(CONFIG_AMD_PHY)         += amd.o
- obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o
- obj-$(CONFIG_AQUANTIA_PHY)    += aquantia/
-+obj-$(CONFIG_AS21XXX_PHY)     += as21xxx.o
- ifdef CONFIG_AX88796B_RUST_PHY
-   obj-$(CONFIG_AX88796B_PHY)  += ax88796b_rust.o
- else
---- /dev/null
-+++ b/drivers/net/phy/as21xxx.c
-@@ -0,0 +1,1087 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Aeonsemi AS21XXxX PHY Driver
-+ *
-+ * Author: Christian Marangi <ansuelsmth@gmail.com>
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/firmware.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/phy.h>
-+
-+#define VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR 0x3
-+#define VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR 0x4
-+
-+#define VEND1_GLB_REG_CPU_CTRL                0xe
-+#define   VEND1_GLB_CPU_CTRL_MASK     GENMASK(4, 0)
-+#define   VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK GENMASK(12, 8)
-+#define   VEND1_GLB_CPU_CTRL_LED_POLARITY(_n) FIELD_PREP(VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK, \
-+                                                       BIT(_n))
-+
-+#define VEND1_FW_START_ADDR           0x100
-+
-+#define VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD 0x101
-+#define VEND1_GLB_REG_MDIO_INDIRECT_LOAD 0x102
-+
-+#define VEND1_GLB_REG_MDIO_INDIRECT_STATUS 0x103
-+
-+#define VEND1_PTP_CLK                 0x142
-+#define   VEND1_PTP_CLK_EN            BIT(6)
-+
-+/* 5 LED at step of 0x20
-+ * FE: Fast-Ethernet (10/100)
-+ * GE: Gigabit-Ethernet (1000)
-+ * NG: New-Generation (2500/5000/10000)
-+ */
-+#define VEND1_LED_REG(_n)             (0x1800 + ((_n) * 0x10))
-+#define   VEND1_LED_REG_A_EVENT               GENMASK(15, 11)
-+#define VEND1_LED_CONF                        0x1881
-+#define   VEND1_LED_CONFG_BLINK               GENMASK(7, 0)
-+
-+#define VEND1_SPEED_STATUS            0x4002
-+#define   VEND1_SPEED_MASK            GENMASK(7, 0)
-+#define   VEND1_SPEED_10000           FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x3)
-+#define   VEND1_SPEED_5000            FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x5)
-+#define   VEND1_SPEED_2500            FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x9)
-+#define   VEND1_SPEED_1000            FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x10)
-+#define   VEND1_SPEED_100             FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x20)
-+#define   VEND1_SPEED_10              FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x0)
-+
-+#define VEND1_IPC_CMD                 0x5801
-+#define   AEON_IPC_CMD_PARITY         BIT(15)
-+#define   AEON_IPC_CMD_SIZE           GENMASK(10, 6)
-+#define   AEON_IPC_CMD_OPCODE         GENMASK(5, 0)
-+
-+#define IPC_CMD_NOOP                  0x0  /* Do nothing */
-+#define IPC_CMD_INFO                  0x1  /* Get Firmware Version */
-+#define IPC_CMD_SYS_CPU                       0x2  /* SYS_CPU */
-+#define IPC_CMD_BULK_DATA             0xa  /* Pass bulk data in ipc registers. */
-+#define IPC_CMD_BULK_WRITE            0xc  /* Write bulk data to memory */
-+#define IPC_CMD_CFG_PARAM             0x1a /* Write config parameters to memory */
-+#define IPC_CMD_NG_TESTMODE           0x1b /* Set NG test mode and tone */
-+#define IPC_CMD_TEMP_MON              0x15 /* Temperature monitoring function */
-+#define IPC_CMD_SET_LED                       0x23 /* Set led */
-+
-+#define VEND1_IPC_STS                 0x5802
-+#define   AEON_IPC_STS_PARITY         BIT(15)
-+#define   AEON_IPC_STS_SIZE           GENMASK(14, 10)
-+#define   AEON_IPC_STS_OPCODE         GENMASK(9, 4)
-+#define   AEON_IPC_STS_STATUS         GENMASK(3, 0)
-+#define   AEON_IPC_STS_STATUS_RCVD    FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x1)
-+#define   AEON_IPC_STS_STATUS_PROCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x2)
-+#define   AEON_IPC_STS_STATUS_SUCCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x4)
-+#define   AEON_IPC_STS_STATUS_ERROR   FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x8)
-+#define   AEON_IPC_STS_STATUS_BUSY    FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xe)
-+#define   AEON_IPC_STS_STATUS_READY   FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xf)
-+
-+#define VEND1_IPC_DATA0                       0x5808
-+#define VEND1_IPC_DATA1                       0x5809
-+#define VEND1_IPC_DATA2                       0x580a
-+#define VEND1_IPC_DATA3                       0x580b
-+#define VEND1_IPC_DATA4                       0x580c
-+#define VEND1_IPC_DATA5                       0x580d
-+#define VEND1_IPC_DATA6                       0x580e
-+#define VEND1_IPC_DATA7                       0x580f
-+#define VEND1_IPC_DATA(_n)            (VEND1_IPC_DATA0 + (_n))
-+
-+/* Sub command of CMD_INFO */
-+#define IPC_INFO_VERSION              0x1
-+
-+/* Sub command of CMD_SYS_CPU */
-+#define IPC_SYS_CPU_REBOOT            0x3
-+#define IPC_SYS_CPU_IMAGE_OFST                0x4
-+#define IPC_SYS_CPU_IMAGE_CHECK               0x5
-+#define IPC_SYS_CPU_PHY_ENABLE                0x6
-+
-+/* Sub command of CMD_CFG_PARAM */
-+#define IPC_CFG_PARAM_DIRECT          0x4
-+
-+/* CFG DIRECT sub command */
-+#define IPC_CFG_PARAM_DIRECT_NG_PHYCTRL       0x1
-+#define IPC_CFG_PARAM_DIRECT_CU_AN    0x2
-+#define IPC_CFG_PARAM_DIRECT_SDS_PCS  0x3
-+#define IPC_CFG_PARAM_DIRECT_AUTO_EEE 0x4
-+#define IPC_CFG_PARAM_DIRECT_SDS_PMA  0x5
-+#define IPC_CFG_PARAM_DIRECT_DPC_RA   0x6
-+#define IPC_CFG_PARAM_DIRECT_DPC_PKT_CHK 0x7
-+#define IPC_CFG_PARAM_DIRECT_DPC_SDS_WAIT_ETH 0x8
-+#define IPC_CFG_PARAM_DIRECT_WDT      0x9
-+#define IPC_CFG_PARAM_DIRECT_SDS_RESTART_AN 0x10
-+#define IPC_CFG_PARAM_DIRECT_TEMP_MON 0x11
-+#define IPC_CFG_PARAM_DIRECT_WOL      0x12
-+
-+/* Sub command of CMD_TEMP_MON */
-+#define IPC_CMD_TEMP_MON_GET          0x4
-+
-+#define AS21XXX_MDIO_AN_C22           0xffe0
-+
-+#define PHY_ID_AS21XXX                        0x75009410
-+/* AS21xxx ID Legend
-+ * AS21x1xxB1
-+ *     ^ ^^
-+ *     | |J: Supports SyncE/PTP
-+ *     | |P: No SyncE/PTP support
-+ *     | 1: Supports 2nd Serdes
-+ *     | 2: Not 2nd Serdes support
-+ *     0: 10G, 5G, 2.5G
-+ *     5: 5G, 2.5G
-+ *     2: 2.5G
-+ */
-+#define PHY_ID_AS21011JB1             0x75009402
-+#define PHY_ID_AS21011PB1             0x75009412
-+#define PHY_ID_AS21010JB1             0x75009422
-+#define PHY_ID_AS21010PB1             0x75009432
-+#define PHY_ID_AS21511JB1             0x75009442
-+#define PHY_ID_AS21511PB1             0x75009452
-+#define PHY_ID_AS21510JB1             0x75009462
-+#define PHY_ID_AS21510PB1             0x75009472
-+#define PHY_ID_AS21210JB1             0x75009482
-+#define PHY_ID_AS21210PB1             0x75009492
-+#define PHY_VENDOR_AEONSEMI           0x75009400
-+
-+#define AEON_MAX_LEDS                 5
-+#define AEON_IPC_DELAY                        10000
-+#define AEON_IPC_TIMEOUT              (AEON_IPC_DELAY * 100)
-+#define AEON_IPC_DATA_NUM_REGISTERS   8
-+#define AEON_IPC_DATA_MAX             (AEON_IPC_DATA_NUM_REGISTERS * sizeof(u16))
-+
-+#define AEON_BOOT_ADDR                        0x1000
-+#define AEON_CPU_BOOT_ADDR            0x2000
-+#define AEON_CPU_CTRL_FW_LOAD         (BIT(4) | BIT(2) | BIT(1) | BIT(0))
-+#define AEON_CPU_CTRL_FW_START                BIT(0)
-+
-+enum as21xxx_led_event {
-+      VEND1_LED_REG_A_EVENT_ON_10 = 0x0,
-+      VEND1_LED_REG_A_EVENT_ON_100,
-+      VEND1_LED_REG_A_EVENT_ON_1000,
-+      VEND1_LED_REG_A_EVENT_ON_2500,
-+      VEND1_LED_REG_A_EVENT_ON_5000,
-+      VEND1_LED_REG_A_EVENT_ON_10000,
-+      VEND1_LED_REG_A_EVENT_ON_FE_GE,
-+      VEND1_LED_REG_A_EVENT_ON_NG,
-+      VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX,
-+      VEND1_LED_REG_A_EVENT_ON_COLLISION,
-+      VEND1_LED_REG_A_EVENT_BLINK_TX,
-+      VEND1_LED_REG_A_EVENT_BLINK_RX,
-+      VEND1_LED_REG_A_EVENT_BLINK_ACT,
-+      VEND1_LED_REG_A_EVENT_ON_LINK,
-+      VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT,
-+      VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX,
-+      VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT,
-+      VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT,
-+      VEND1_LED_REG_A_EVENT_ON_NG_BLINK_FE_GE,
-+      VEND1_LED_REG_A_EVENT_ON_FD_BLINK_COLLISION,
-+      VEND1_LED_REG_A_EVENT_ON,
-+      VEND1_LED_REG_A_EVENT_OFF,
-+};
-+
-+struct as21xxx_led_pattern_info {
-+      unsigned int pattern;
-+      u16 val;
-+};
-+
-+struct as21xxx_priv {
-+      bool parity_status;
-+      /* Protect concurrent IPC access */
-+      struct mutex ipc_lock;
-+};
-+
-+static struct as21xxx_led_pattern_info as21xxx_led_supported_pattern[] = {
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_10),
-+              .val = VEND1_LED_REG_A_EVENT_ON_10
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_100),
-+              .val = VEND1_LED_REG_A_EVENT_ON_100
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_1000),
-+              .val = VEND1_LED_REG_A_EVENT_ON_1000
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_2500),
-+              .val = VEND1_LED_REG_A_EVENT_ON_2500
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_5000),
-+              .val = VEND1_LED_REG_A_EVENT_ON_5000
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_10000),
-+              .val = VEND1_LED_REG_A_EVENT_ON_10000
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK),
-+              .val = VEND1_LED_REG_A_EVENT_ON_LINK
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_10) |
-+                         BIT(TRIGGER_NETDEV_LINK_100) |
-+                         BIT(TRIGGER_NETDEV_LINK_1000),
-+              .val = VEND1_LED_REG_A_EVENT_ON_FE_GE
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_2500) |
-+                         BIT(TRIGGER_NETDEV_LINK_5000) |
-+                         BIT(TRIGGER_NETDEV_LINK_10000),
-+              .val = VEND1_LED_REG_A_EVENT_ON_NG
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_FULL_DUPLEX),
-+              .val = VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_TX),
-+              .val = VEND1_LED_REG_A_EVENT_BLINK_TX
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_RX),
-+              .val = VEND1_LED_REG_A_EVENT_BLINK_RX
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_TX) |
-+                         BIT(TRIGGER_NETDEV_RX),
-+              .val = VEND1_LED_REG_A_EVENT_BLINK_ACT
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_10) |
-+                         BIT(TRIGGER_NETDEV_LINK_100) |
-+                         BIT(TRIGGER_NETDEV_LINK_1000) |
-+                         BIT(TRIGGER_NETDEV_LINK_2500) |
-+                         BIT(TRIGGER_NETDEV_LINK_5000) |
-+                         BIT(TRIGGER_NETDEV_LINK_10000),
-+              .val = VEND1_LED_REG_A_EVENT_ON_LINK
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_10) |
-+                         BIT(TRIGGER_NETDEV_LINK_100) |
-+                         BIT(TRIGGER_NETDEV_LINK_1000) |
-+                         BIT(TRIGGER_NETDEV_LINK_2500) |
-+                         BIT(TRIGGER_NETDEV_LINK_5000) |
-+                         BIT(TRIGGER_NETDEV_LINK_10000) |
-+                         BIT(TRIGGER_NETDEV_TX) |
-+                         BIT(TRIGGER_NETDEV_RX),
-+              .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_10) |
-+                         BIT(TRIGGER_NETDEV_LINK_100) |
-+                         BIT(TRIGGER_NETDEV_LINK_1000) |
-+                         BIT(TRIGGER_NETDEV_LINK_2500) |
-+                         BIT(TRIGGER_NETDEV_LINK_5000) |
-+                         BIT(TRIGGER_NETDEV_LINK_10000) |
-+                         BIT(TRIGGER_NETDEV_RX),
-+              .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_10) |
-+                         BIT(TRIGGER_NETDEV_LINK_100) |
-+                         BIT(TRIGGER_NETDEV_LINK_1000) |
-+                         BIT(TRIGGER_NETDEV_TX) |
-+                         BIT(TRIGGER_NETDEV_RX),
-+              .val = VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT
-+      },
-+      {
-+              .pattern = BIT(TRIGGER_NETDEV_LINK_2500) |
-+                         BIT(TRIGGER_NETDEV_LINK_5000) |
-+                         BIT(TRIGGER_NETDEV_LINK_10000) |
-+                         BIT(TRIGGER_NETDEV_TX) |
-+                         BIT(TRIGGER_NETDEV_RX),
-+              .val = VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT
-+      }
-+};
-+
-+static int aeon_firmware_boot(struct phy_device *phydev, const u8 *data,
-+                            size_t size)
-+{
-+      int i, ret;
-+      u16 val;
-+
-+      ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL,
-+                           VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_LOAD);
-+      if (ret)
-+              return ret;
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_FW_START_ADDR,
-+                          AEON_BOOT_ADDR);
-+      if (ret)
-+              return ret;
-+
-+      ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                           VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD,
-+                           0x3ffc, 0xc000);
-+      if (ret)
-+              return ret;
-+
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
-+                         VEND1_GLB_REG_MDIO_INDIRECT_STATUS);
-+      if (val > 1) {
-+              phydev_err(phydev, "wrong origin mdio_indirect_status: %x\n", val);
-+              return -EINVAL;
-+      }
-+
-+      /* Firmware is always aligned to u16 */
-+      for (i = 0; i < size; i += 2) {
-+              val = data[i + 1] << 8 | data[i];
-+
-+              ret = phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+                                  VEND1_GLB_REG_MDIO_INDIRECT_LOAD, val);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+                          VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR,
-+                          lower_16_bits(AEON_CPU_BOOT_ADDR));
-+      if (ret)
-+              return ret;
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1,
-+                          VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR,
-+                          upper_16_bits(AEON_CPU_BOOT_ADDR));
-+      if (ret)
-+              return ret;
-+
-+      return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL,
-+                            VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_START);
-+}
-+
-+static int aeon_firmware_load(struct phy_device *phydev)
-+{
-+      struct device *dev = &phydev->mdio.dev;
-+      const struct firmware *fw;
-+      const char *fw_name;
-+      int ret;
-+
-+      ret = of_property_read_string(dev->of_node, "firmware-name",
-+                                    &fw_name);
-+      if (ret)
-+              return ret;
-+
-+      ret = request_firmware(&fw, fw_name, dev);
-+      if (ret) {
-+              phydev_err(phydev, "failed to find FW file %s (%d)\n",
-+                         fw_name, ret);
-+              return ret;
-+      }
-+
-+      ret = aeon_firmware_boot(phydev, fw->data, fw->size);
-+
-+      release_firmware(fw);
-+
-+      return ret;
-+}
-+
-+static bool aeon_ipc_ready(u16 val, bool parity_status)
-+{
-+      u16 status;
-+
-+      if (FIELD_GET(AEON_IPC_STS_PARITY, val) != parity_status)
-+              return false;
-+
-+      status = val & AEON_IPC_STS_STATUS;
-+
-+      return status != AEON_IPC_STS_STATUS_RCVD &&
-+             status != AEON_IPC_STS_STATUS_PROCESS &&
-+             status != AEON_IPC_STS_STATUS_BUSY;
-+}
-+
-+static int aeon_ipc_wait_cmd(struct phy_device *phydev, bool parity_status)
-+{
-+      u16 val;
-+
-+      /* Exit condition logic:
-+       * - Wait for parity bit equal
-+       * - Wait for status success, error OR ready
-+       */
-+      return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS, val,
-+                                       aeon_ipc_ready(val, parity_status),
-+                                       AEON_IPC_DELAY, AEON_IPC_TIMEOUT, false);
-+}
-+
-+static int aeon_ipc_send_cmd(struct phy_device *phydev,
-+                           struct as21xxx_priv *priv,
-+                           u16 cmd, u16 *ret_sts)
-+{
-+      bool curr_parity;
-+      int ret;
-+
-+      /* The IPC sync by using a single parity bit.
-+       * Each CMD have alternately this bit set or clear
-+       * to understand correct flow and packet order.
-+       */
-+      curr_parity = priv->parity_status;
-+      if (priv->parity_status)
-+              cmd |= AEON_IPC_CMD_PARITY;
-+
-+      /* Always update parity for next packet */
-+      priv->parity_status = !priv->parity_status;
-+
-+      ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_CMD, cmd);
-+      if (ret)
-+              return ret;
-+
-+      /* Wait for packet to be processed */
-+      usleep_range(AEON_IPC_DELAY, AEON_IPC_DELAY + 5000);
-+
-+      /* With no ret_sts, ignore waiting for packet completion
-+       * (ipc parity bit sync)
-+       */
-+      if (!ret_sts)
-+              return 0;
-+
-+      ret = aeon_ipc_wait_cmd(phydev, curr_parity);
-+      if (ret)
-+              return ret;
-+
-+      ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS);
-+      if (ret < 0)
-+              return ret;
-+
-+      *ret_sts = ret;
-+      if ((*ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_SUCCESS)
-+              return -EINVAL;
-+
-+      return 0;
-+}
-+
-+/* If data is NULL, return 0 or negative error.
-+ * If data not NULL, return number of Bytes received from IPC or
-+ * a negative error.
-+ */
-+static int aeon_ipc_send_msg(struct phy_device *phydev,
-+                           u16 opcode, u16 *data, unsigned int data_len,
-+                           u16 *ret_data)
-+{
-+      struct as21xxx_priv *priv = phydev->priv;
-+      unsigned int ret_size;
-+      u16 cmd, ret_sts;
-+      int ret;
-+      int i;
-+
-+      /* IPC have a max of 8 register to transfer data,
-+       * make sure we never exceed this.
-+       */
-+      if (data_len > AEON_IPC_DATA_MAX)
-+              return -EINVAL;
-+
-+      for (i = 0; i < data_len / sizeof(u16); i++)
-+              phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i),
-+                            data[i]);
-+
-+      cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, data_len) |
-+            FIELD_PREP(AEON_IPC_CMD_OPCODE, opcode);
-+
-+      mutex_lock(&priv->ipc_lock);
-+
-+      ret = aeon_ipc_send_cmd(phydev, priv, cmd, &ret_sts);
-+      if (ret) {
-+              phydev_err(phydev, "failed to send ipc msg for %x: %d\n",
-+                         opcode, ret);
-+              goto out;
-+      }
-+
-+      if (!data)
-+              goto out;
-+
-+      if ((ret_sts & AEON_IPC_STS_STATUS) == AEON_IPC_STS_STATUS_ERROR) {
-+              ret = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* Prevent IPC from stack smashing the kernel.
-+       * We can't trust IPC to return a good value and we always
-+       * preallocate space for 16 Bytes.
-+       */
-+      ret_size = FIELD_GET(AEON_IPC_STS_SIZE, ret_sts);
-+      if (ret_size > AEON_IPC_DATA_MAX) {
-+              ret = -EINVAL;
-+              goto out;
-+      }
-+
-+      /* Read data from IPC data register for ret_size value from IPC */
-+      for (i = 0; i < DIV_ROUND_UP(ret_size, sizeof(u16)); i++) {
-+              ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i));
-+              if (ret < 0)
-+                      goto out;
-+
-+              ret_data[i] = ret;
-+      }
-+
-+      ret = ret_size;
-+
-+out:
-+      mutex_unlock(&priv->ipc_lock);
-+
-+      return ret;
-+}
-+
-+static int aeon_ipc_noop(struct phy_device *phydev,
-+                       struct as21xxx_priv *priv, u16 *ret_sts)
-+{
-+      u16 cmd;
-+
-+      cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, 0) |
-+            FIELD_PREP(AEON_IPC_CMD_OPCODE, IPC_CMD_NOOP);
-+
-+      return aeon_ipc_send_cmd(phydev, priv, cmd, ret_sts);
-+}
-+
-+/* Logic to sync parity bit with IPC.
-+ * We send 2 NOP cmd with same partity and we wait for IPC
-+ * to handle the packet only for the second one. This way
-+ * we make sure we are sync for every next cmd.
-+ */
-+static int aeon_ipc_sync_parity(struct phy_device *phydev,
-+                              struct as21xxx_priv *priv)
-+{
-+      u16 ret_sts;
-+      int ret;
-+
-+      mutex_lock(&priv->ipc_lock);
-+
-+      /* Send NOP with no parity */
-+      aeon_ipc_noop(phydev, priv, NULL);
-+
-+      /* Reset packet parity */
-+      priv->parity_status = false;
-+
-+      /* Send second NOP with no parity */
-+      ret = aeon_ipc_noop(phydev, priv, &ret_sts);
-+
-+      mutex_unlock(&priv->ipc_lock);
-+
-+      /* We expect to return -EINVAL */
-+      if (ret != -EINVAL)
-+              return ret;
-+
-+      if ((ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_READY) {
-+              phydev_err(phydev, "Invalid IPC status on sync parity: %x\n",
-+                         ret_sts);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int aeon_ipc_get_fw_version(struct phy_device *phydev)
-+{
-+      u16 ret_data[AEON_IPC_DATA_NUM_REGISTERS], data[1];
-+      char fw_version[AEON_IPC_DATA_MAX + 1];
-+      int ret;
-+
-+      data[0] = IPC_INFO_VERSION;
-+
-+      ret = aeon_ipc_send_msg(phydev, IPC_CMD_INFO, data,
-+                              sizeof(data), ret_data);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Make sure FW version is NULL terminated */
-+      memcpy(fw_version, ret_data, ret);
-+      fw_version[ret] = '\0';
-+
-+      phydev_info(phydev, "Firmware Version: %s\n", fw_version);
-+
-+      return 0;
-+}
-+
-+static int aeon_dpc_ra_enable(struct phy_device *phydev)
-+{
-+      u16 data[2];
-+
-+      data[0] = IPC_CFG_PARAM_DIRECT;
-+      data[1] = IPC_CFG_PARAM_DIRECT_DPC_RA;
-+
-+      return aeon_ipc_send_msg(phydev, IPC_CMD_CFG_PARAM, data,
-+                               sizeof(data), NULL);
-+}
-+
-+static int as21xxx_probe(struct phy_device *phydev)
-+{
-+      struct as21xxx_priv *priv;
-+      int ret;
-+
-+      priv = devm_kzalloc(&phydev->mdio.dev,
-+                          sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+      phydev->priv = priv;
-+
-+      ret = devm_mutex_init(&phydev->mdio.dev,
-+                            &priv->ipc_lock);
-+      if (ret)
-+              return ret;
-+
-+      ret = aeon_ipc_sync_parity(phydev, priv);
-+      if (ret)
-+              return ret;
-+
-+      ret = aeon_ipc_get_fw_version(phydev);
-+      if (ret)
-+              return ret;
-+
-+      /* Enable PTP clk if not already Enabled */
-+      ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CLK,
-+                             VEND1_PTP_CLK_EN);
-+      if (ret)
-+              return ret;
-+
-+      return aeon_dpc_ra_enable(phydev);
-+}
-+
-+static int as21xxx_read_link(struct phy_device *phydev, int *bmcr)
-+{
-+      int status;
-+
-+      /* Normal C22 BMCR report inconsistent data, use
-+       * the mapped C22 in C45 to have more consistent link info.
-+       */
-+      *bmcr = phy_read_mmd(phydev, MDIO_MMD_AN,
-+                           AS21XXX_MDIO_AN_C22 + MII_BMCR);
-+      if (*bmcr < 0)
-+              return *bmcr;
-+
-+      /* Autoneg is being started, therefore disregard current
-+       * link status and report link as down.
-+       */
-+      if (*bmcr & BMCR_ANRESTART) {
-+              phydev->link = 0;
-+              return 0;
-+      }
-+
-+      status = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
-+      if (status < 0)
-+              return status;
-+
-+      phydev->link = !!(status & MDIO_STAT1_LSTATUS);
-+
-+      return 0;
-+}
-+
-+static int as21xxx_read_c22_lpa(struct phy_device *phydev)
-+{
-+      int lpagb;
-+
-+      /* MII_STAT1000 are only filled in the mapped C22
-+       * in C45, use that to fill lpagb values and check.
-+       */
-+      lpagb = phy_read_mmd(phydev, MDIO_MMD_AN,
-+                           AS21XXX_MDIO_AN_C22 + MII_STAT1000);
-+      if (lpagb < 0)
-+              return lpagb;
-+
-+      if (lpagb & LPA_1000MSFAIL) {
-+              int adv = phy_read_mmd(phydev, MDIO_MMD_AN,
-+                                     AS21XXX_MDIO_AN_C22 + MII_CTRL1000);
-+
-+              if (adv < 0)
-+                      return adv;
-+
-+              if (adv & CTL1000_ENABLE_MASTER)
-+                      phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n");
-+              else
-+                      phydev_err(phydev, "Master/Slave resolution failed\n");
-+              return -ENOLINK;
-+      }
-+
-+      mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
-+                                      lpagb);
-+
-+      return 0;
-+}
-+
-+static int as21xxx_read_status(struct phy_device *phydev)
-+{
-+      int bmcr, old_link = phydev->link;
-+      int ret;
-+
-+      ret = as21xxx_read_link(phydev, &bmcr);
-+      if (ret)
-+              return ret;
-+
-+      /* why bother the PHY if nothing can have changed */
-+      if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
-+              return 0;
-+
-+      phydev->speed = SPEED_UNKNOWN;
-+      phydev->duplex = DUPLEX_UNKNOWN;
-+      phydev->pause = 0;
-+      phydev->asym_pause = 0;
-+
-+      if (phydev->autoneg == AUTONEG_ENABLE) {
-+              ret = genphy_c45_read_lpa(phydev);
-+              if (ret)
-+                      return ret;
-+
-+              ret = as21xxx_read_c22_lpa(phydev);
-+              if (ret)
-+                      return ret;
-+
-+              phy_resolve_aneg_linkmode(phydev);
-+      } else {
-+              int speed;
-+
-+              linkmode_zero(phydev->lp_advertising);
-+
-+              speed = phy_read_mmd(phydev, MDIO_MMD_VEND1,
-+                                   VEND1_SPEED_STATUS);
-+              if (speed < 0)
-+                      return speed;
-+
-+              switch (speed & VEND1_SPEED_STATUS) {
-+              case VEND1_SPEED_10000:
-+                      phydev->speed = SPEED_10000;
-+                      phydev->duplex = DUPLEX_FULL;
-+                      break;
-+              case VEND1_SPEED_5000:
-+                      phydev->speed = SPEED_5000;
-+                      phydev->duplex = DUPLEX_FULL;
-+                      break;
-+              case VEND1_SPEED_2500:
-+                      phydev->speed = SPEED_2500;
-+                      phydev->duplex = DUPLEX_FULL;
-+                      break;
-+              case VEND1_SPEED_1000:
-+                      phydev->speed = SPEED_1000;
-+                      if (bmcr & BMCR_FULLDPLX)
-+                              phydev->duplex = DUPLEX_FULL;
-+                      else
-+                              phydev->duplex = DUPLEX_HALF;
-+                      break;
-+              case VEND1_SPEED_100:
-+                      phydev->speed = SPEED_100;
-+                      phydev->duplex = DUPLEX_FULL;
-+                      break;
-+              case VEND1_SPEED_10:
-+                      phydev->speed = SPEED_10;
-+                      phydev->duplex = DUPLEX_FULL;
-+                      break;
-+              default:
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int as21xxx_led_brightness_set(struct phy_device *phydev,
-+                                    u8 index, enum led_brightness value)
-+{
-+      u16 val = VEND1_LED_REG_A_EVENT_OFF;
-+
-+      if (index > AEON_MAX_LEDS)
-+              return -EINVAL;
-+
-+      if (value)
-+              val = VEND1_LED_REG_A_EVENT_ON;
-+
-+      return phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                            VEND1_LED_REG(index),
-+                            VEND1_LED_REG_A_EVENT,
-+                            FIELD_PREP(VEND1_LED_REG_A_EVENT, val));
-+}
-+
-+static int as21xxx_led_hw_is_supported(struct phy_device *phydev, u8 index,
-+                                     unsigned long rules)
-+{
-+      int i;
-+
-+      if (index > AEON_MAX_LEDS)
-+              return -EINVAL;
-+
-+      for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++)
-+              if (rules == as21xxx_led_supported_pattern[i].pattern)
-+                      return 0;
-+
-+      return -EOPNOTSUPP;
-+}
-+
-+static int as21xxx_led_hw_control_get(struct phy_device *phydev, u8 index,
-+                                    unsigned long *rules)
-+{
-+      int i, val;
-+
-+      if (index > AEON_MAX_LEDS)
-+              return -EINVAL;
-+
-+      val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_LED_REG(index));
-+      if (val < 0)
-+              return val;
-+
-+      val = FIELD_GET(VEND1_LED_REG_A_EVENT, val);
-+      for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++)
-+              if (val == as21xxx_led_supported_pattern[i].val) {
-+                      *rules = as21xxx_led_supported_pattern[i].pattern;
-+                      return 0;
-+              }
-+
-+      /* Should be impossible */
-+      return -EINVAL;
-+}
-+
-+static int as21xxx_led_hw_control_set(struct phy_device *phydev, u8 index,
-+                                    unsigned long rules)
-+{
-+      u16 val = 0;
-+      int i;
-+
-+      if (index > AEON_MAX_LEDS)
-+              return -EINVAL;
-+
-+      for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++)
-+              if (rules == as21xxx_led_supported_pattern[i].pattern) {
-+                      val = as21xxx_led_supported_pattern[i].val;
-+                      break;
-+              }
-+
-+      return phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                            VEND1_LED_REG(index),
-+                            VEND1_LED_REG_A_EVENT,
-+                            FIELD_PREP(VEND1_LED_REG_A_EVENT, val));
-+}
-+
-+static int as21xxx_led_polarity_set(struct phy_device *phydev, int index,
-+                                  unsigned long modes)
-+{
-+      bool led_active_low = false;
-+      u16 mask, val = 0;
-+      u32 mode;
-+
-+      if (index > AEON_MAX_LEDS)
-+              return -EINVAL;
-+
-+      for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
-+              switch (mode) {
-+              case PHY_LED_ACTIVE_LOW:
-+                      led_active_low = true;
-+                      break;
-+              case PHY_LED_ACTIVE_HIGH: /* default mode */
-+                      led_active_low = false;
-+                      break;
-+              default:
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      mask = VEND1_GLB_CPU_CTRL_LED_POLARITY(index);
-+      if (led_active_low)
-+              val = VEND1_GLB_CPU_CTRL_LED_POLARITY(index);
-+
-+      return phy_modify_mmd(phydev, MDIO_MMD_VEND1,
-+                            VEND1_GLB_REG_CPU_CTRL,
-+                            mask, val);
-+}
-+
-+static int as21xxx_match_phy_device(struct phy_device *phydev,
-+                                  const struct phy_driver *phydrv)
-+{
-+      struct as21xxx_priv *priv;
-+      u16 ret_sts;
-+      u32 phy_id;
-+      int ret;
-+
-+      /* Skip PHY that are not AS21xxx or already have firmware loaded */
-+      if (phydev->c45_ids.device_ids[MDIO_MMD_PCS] != PHY_ID_AS21XXX)
-+              return genphy_match_phy_device(phydev, phydrv);
-+
-+      /* Read PHY ID to handle firmware just loaded */
-+      ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID1);
-+      if (ret < 0)
-+              return ret;
-+      phy_id = ret << 16;
-+
-+      ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID2);
-+      if (ret < 0)
-+              return ret;
-+      phy_id |= ret;
-+
-+      /* With PHY ID not the generic AS21xxx one assume
-+       * the firmware just loaded
-+       */
-+      if (phy_id != PHY_ID_AS21XXX)
-+              return phy_id == phydrv->phy_id;
-+
-+      /* Allocate temp priv and load the firmware */
-+      priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+
-+      mutex_init(&priv->ipc_lock);
-+
-+      ret = aeon_firmware_load(phydev);
-+      if (ret)
-+              goto out;
-+
-+      /* Sync parity... */
-+      ret = aeon_ipc_sync_parity(phydev, priv);
-+      if (ret)
-+              goto out;
-+
-+      /* ...and send a third NOOP cmd to wait for firmware finish loading */
-+      ret = aeon_ipc_noop(phydev, priv, &ret_sts);
-+      if (ret)
-+              goto out;
-+
-+out:
-+      mutex_destroy(&priv->ipc_lock);
-+      kfree(priv);
-+
-+      /* Return can either be 0 or a negative error code.
-+       * Returning 0 here means THIS is NOT a suitable PHY.
-+       *
-+       * For the specific case of the generic Aeonsemi PHY ID that
-+       * needs the firmware the be loaded first to have a correct PHY ID,
-+       * this is OK as a matching PHY ID will be found right after.
-+       * This relies on the driver probe order where the first PHY driver
-+       * probed is the generic one.
-+       */
-+      return ret;
-+}
-+
-+static struct phy_driver as21xxx_drivers[] = {
-+      {
-+              /* PHY expose in C45 as 0x7500 0x9410
-+               * before firmware is loaded.
-+               * This driver entry must be attempted first to load
-+               * the firmware and thus update the ID registers.
-+               */
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21XXX),
-+              .name           = "Aeonsemi AS21xxx",
-+              .match_phy_device = as21xxx_match_phy_device,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21011JB1),
-+              .name           = "Aeonsemi AS21011JB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21011PB1),
-+              .name           = "Aeonsemi AS21011PB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21010PB1),
-+              .name           = "Aeonsemi AS21010PB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21010JB1),
-+              .name           = "Aeonsemi AS21010JB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21210PB1),
-+              .name           = "Aeonsemi AS21210PB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21510JB1),
-+              .name           = "Aeonsemi AS21510JB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21510PB1),
-+              .name           = "Aeonsemi AS21510PB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21511JB1),
-+              .name           = "Aeonsemi AS21511JB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21210JB1),
-+              .name           = "Aeonsemi AS21210JB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+      {
-+              PHY_ID_MATCH_EXACT(PHY_ID_AS21511PB1),
-+              .name           = "Aeonsemi AS21511PB1",
-+              .probe          = as21xxx_probe,
-+              .match_phy_device = as21xxx_match_phy_device,
-+              .read_status    = as21xxx_read_status,
-+              .led_brightness_set = as21xxx_led_brightness_set,
-+              .led_hw_is_supported = as21xxx_led_hw_is_supported,
-+              .led_hw_control_set = as21xxx_led_hw_control_set,
-+              .led_hw_control_get = as21xxx_led_hw_control_get,
-+              .led_polarity_set = as21xxx_led_polarity_set,
-+      },
-+};
-+module_phy_driver(as21xxx_drivers);
-+
-+static struct mdio_device_id __maybe_unused as21xxx_tbl[] = {
-+      { PHY_ID_MATCH_VENDOR(PHY_VENDOR_AEONSEMI) },
-+      { }
-+};
-+MODULE_DEVICE_TABLE(mdio, as21xxx_tbl);
-+
-+MODULE_DESCRIPTION("Aeonsemi AS21xxx PHY driver");
-+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.18/783-01-v6.18-net-dsa-Move-KS8995-to-the-DSA-subsystem.patch b/target/linux/generic/backport-6.18/783-01-v6.18-net-dsa-Move-KS8995-to-the-DSA-subsystem.patch
deleted file mode 100644 (file)
index b91c0cd..0000000
+++ /dev/null
@@ -1,1092 +0,0 @@
-From 9c370f7f92b0232fe925ca2caefb5e3126a0357d Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 13 Aug 2025 23:43:03 +0200
-Subject: [PATCH 1/4] net: dsa: Move KS8995 to the DSA subsystem
-
-By reading the datasheets for the KS8995 it is obvious that this
-is a 100 Mbit DSA switch.
-
-Let us start the refactoring by moving it to the DSA subsystem to
-preserve development history.
-
-Verified that the chip still probes the same after this patch
-provided CONFIG_HAVE_NET_DSA, CONFIG_NET_DSA and CONFIG_DSA_KS8995
-are selected.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250813-ks8995-to-dsa-v1-1-75c359ede3a5@linaro.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/Kconfig                        | 7 +++++++
- drivers/net/dsa/Makefile                       | 1 +
- drivers/net/{phy/spi_ks8995.c => dsa/ks8995.c} | 0
- drivers/net/phy/Kconfig                        | 4 ----
- drivers/net/phy/Makefile                       | 1 -
- 5 files changed, 8 insertions(+), 5 deletions(-)
- rename drivers/net/{phy/spi_ks8995.c => dsa/ks8995.c} (100%)
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -100,6 +100,13 @@ config NET_DSA_RZN1_A5PSW
-         This driver supports the A5PSW switch, which is embedded in Renesas
-         RZ/N1 SoC.
-+config NET_DSA_KS8995
-+      tristate "Micrel KS8995 family 5-ports 10/100 Ethernet switches"
-+      depends on SPI
-+      help
-+        This driver supports the Micrel KS8995 family of 10/100 Mbit ethernet
-+        switches, managed over SPI.
-+
- config NET_DSA_SMSC_LAN9303
-       tristate
-       select NET_DSA_TAG_LAN9303
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -5,6 +5,7 @@ obj-$(CONFIG_NET_DSA_LOOP)     += dsa_loop.o
- ifdef CONFIG_NET_DSA_LOOP
- obj-$(CONFIG_FIXED_PHY)               += dsa_loop_bdinfo.o
- endif
-+obj-$(CONFIG_NET_DSA_KS8995)  += ks8995.o
- obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
- obj-$(CONFIG_NET_DSA_MT7530)  += mt7530.o
- obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -443,7 +443,3 @@ config XILINX_GMII2RGMII
-         Ethernet physical media devices and the Gigabit Ethernet controller.
- endif # PHYLIB
--
--config MICREL_KS8995MA
--      tristate "Micrel KS8995MA 5-ports 10/100 managed Ethernet switch"
--      depends on SPI
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -77,7 +77,6 @@ obj-$(CONFIG_MARVELL_88X2222_PHY)    += mar
- obj-$(CONFIG_MAXLINEAR_GPHY)  += mxl-gpy.o
- obj-y                         += mediatek/
- obj-$(CONFIG_MESON_GXL_PHY)   += meson-gxl.o
--obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
- obj-$(CONFIG_MICREL_PHY)      += micrel.o
- obj-$(CONFIG_MICROCHIP_PHY)   += microchip.o
- obj-$(CONFIG_MICROCHIP_T1_PHY)        += microchip_t1.o
---- /dev/null
-+++ b/drivers/net/dsa/ks8995.c
-@@ -0,0 +1,506 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * SPI driver for Micrel/Kendin KS8995M and KSZ8864RMN ethernet switches
-+ *
-+ * Copyright (C) 2008 Gabor Juhos <juhosg at openwrt.org>
-+ *
-+ * This file was based on: drivers/spi/at25.c
-+ *     Copyright (C) 2006 David Brownell
-+ */
-+
-+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-+
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/gpio/consumer.h>
-+#include <linux/of.h>
-+
-+#include <linux/spi/spi.h>
-+
-+#define DRV_VERSION           "0.1.1"
-+#define DRV_DESC              "Micrel KS8995 Ethernet switch SPI driver"
-+
-+/* ------------------------------------------------------------------------ */
-+
-+#define KS8995_REG_ID0                0x00    /* Chip ID0 */
-+#define KS8995_REG_ID1                0x01    /* Chip ID1 */
-+
-+#define KS8995_REG_GC0                0x02    /* Global Control 0 */
-+#define KS8995_REG_GC1                0x03    /* Global Control 1 */
-+#define KS8995_REG_GC2                0x04    /* Global Control 2 */
-+#define KS8995_REG_GC3                0x05    /* Global Control 3 */
-+#define KS8995_REG_GC4                0x06    /* Global Control 4 */
-+#define KS8995_REG_GC5                0x07    /* Global Control 5 */
-+#define KS8995_REG_GC6                0x08    /* Global Control 6 */
-+#define KS8995_REG_GC7                0x09    /* Global Control 7 */
-+#define KS8995_REG_GC8                0x0a    /* Global Control 8 */
-+#define KS8995_REG_GC9                0x0b    /* Global Control 9 */
-+
-+#define KS8995_REG_PC(p, r)   ((0x10 * p) + r)         /* Port Control */
-+#define KS8995_REG_PS(p, r)   ((0x10 * p) + r + 0xe)  /* Port Status */
-+
-+#define KS8995_REG_TPC0               0x60    /* TOS Priority Control 0 */
-+#define KS8995_REG_TPC1               0x61    /* TOS Priority Control 1 */
-+#define KS8995_REG_TPC2               0x62    /* TOS Priority Control 2 */
-+#define KS8995_REG_TPC3               0x63    /* TOS Priority Control 3 */
-+#define KS8995_REG_TPC4               0x64    /* TOS Priority Control 4 */
-+#define KS8995_REG_TPC5               0x65    /* TOS Priority Control 5 */
-+#define KS8995_REG_TPC6               0x66    /* TOS Priority Control 6 */
-+#define KS8995_REG_TPC7               0x67    /* TOS Priority Control 7 */
-+
-+#define KS8995_REG_MAC0               0x68    /* MAC address 0 */
-+#define KS8995_REG_MAC1               0x69    /* MAC address 1 */
-+#define KS8995_REG_MAC2               0x6a    /* MAC address 2 */
-+#define KS8995_REG_MAC3               0x6b    /* MAC address 3 */
-+#define KS8995_REG_MAC4               0x6c    /* MAC address 4 */
-+#define KS8995_REG_MAC5               0x6d    /* MAC address 5 */
-+
-+#define KS8995_REG_IAC0               0x6e    /* Indirect Access Control 0 */
-+#define KS8995_REG_IAC1               0x6f    /* Indirect Access Control 0 */
-+#define KS8995_REG_IAD7               0x70    /* Indirect Access Data 7 */
-+#define KS8995_REG_IAD6               0x71    /* Indirect Access Data 6 */
-+#define KS8995_REG_IAD5               0x72    /* Indirect Access Data 5 */
-+#define KS8995_REG_IAD4               0x73    /* Indirect Access Data 4 */
-+#define KS8995_REG_IAD3               0x74    /* Indirect Access Data 3 */
-+#define KS8995_REG_IAD2               0x75    /* Indirect Access Data 2 */
-+#define KS8995_REG_IAD1               0x76    /* Indirect Access Data 1 */
-+#define KS8995_REG_IAD0               0x77    /* Indirect Access Data 0 */
-+
-+#define KSZ8864_REG_ID1               0xfe    /* Chip ID in bit 7 */
-+
-+#define KS8995_REGS_SIZE      0x80
-+#define KSZ8864_REGS_SIZE     0x100
-+#define KSZ8795_REGS_SIZE     0x100
-+
-+#define ID1_CHIPID_M          0xf
-+#define ID1_CHIPID_S          4
-+#define ID1_REVISION_M                0x7
-+#define ID1_REVISION_S                1
-+#define ID1_START_SW          1       /* start the switch */
-+
-+#define FAMILY_KS8995         0x95
-+#define FAMILY_KSZ8795                0x87
-+#define CHIPID_M              0
-+#define KS8995_CHIP_ID                0x00
-+#define KSZ8864_CHIP_ID               0x01
-+#define KSZ8795_CHIP_ID               0x09
-+
-+#define KS8995_CMD_WRITE      0x02U
-+#define KS8995_CMD_READ               0x03U
-+
-+#define KS8995_RESET_DELAY    10 /* usec */
-+
-+enum ks8995_chip_variant {
-+      ks8995,
-+      ksz8864,
-+      ksz8795,
-+      max_variant
-+};
-+
-+struct ks8995_chip_params {
-+      char *name;
-+      int family_id;
-+      int chip_id;
-+      int regs_size;
-+      int addr_width;
-+      int addr_shift;
-+};
-+
-+static const struct ks8995_chip_params ks8995_chip[] = {
-+      [ks8995] = {
-+              .name = "KS8995MA",
-+              .family_id = FAMILY_KS8995,
-+              .chip_id = KS8995_CHIP_ID,
-+              .regs_size = KS8995_REGS_SIZE,
-+              .addr_width = 8,
-+              .addr_shift = 0,
-+      },
-+      [ksz8864] = {
-+              .name = "KSZ8864RMN",
-+              .family_id = FAMILY_KS8995,
-+              .chip_id = KSZ8864_CHIP_ID,
-+              .regs_size = KSZ8864_REGS_SIZE,
-+              .addr_width = 8,
-+              .addr_shift = 0,
-+      },
-+      [ksz8795] = {
-+              .name = "KSZ8795CLX",
-+              .family_id = FAMILY_KSZ8795,
-+              .chip_id = KSZ8795_CHIP_ID,
-+              .regs_size = KSZ8795_REGS_SIZE,
-+              .addr_width = 12,
-+              .addr_shift = 1,
-+      },
-+};
-+
-+struct ks8995_switch {
-+      struct spi_device       *spi;
-+      struct mutex            lock;
-+      struct gpio_desc        *reset_gpio;
-+      struct bin_attribute    regs_attr;
-+      const struct ks8995_chip_params *chip;
-+      int                     revision_id;
-+};
-+
-+static const struct spi_device_id ks8995_id[] = {
-+      {"ks8995", ks8995},
-+      {"ksz8864", ksz8864},
-+      {"ksz8795", ksz8795},
-+      { }
-+};
-+MODULE_DEVICE_TABLE(spi, ks8995_id);
-+
-+static const struct of_device_id ks8895_spi_of_match[] = {
-+      { .compatible = "micrel,ks8995" },
-+      { .compatible = "micrel,ksz8864" },
-+      { .compatible = "micrel,ksz8795" },
-+      { },
-+};
-+MODULE_DEVICE_TABLE(of, ks8895_spi_of_match);
-+
-+static inline u8 get_chip_id(u8 val)
-+{
-+      return (val >> ID1_CHIPID_S) & ID1_CHIPID_M;
-+}
-+
-+static inline u8 get_chip_rev(u8 val)
-+{
-+      return (val >> ID1_REVISION_S) & ID1_REVISION_M;
-+}
-+
-+/* create_spi_cmd - create a chip specific SPI command header
-+ * @ks: pointer to switch instance
-+ * @cmd: SPI command for switch
-+ * @address: register address for command
-+ *
-+ * Different chip families use different bit pattern to address the switches
-+ * registers:
-+ *
-+ * KS8995: 8bit command + 8bit address
-+ * KSZ8795: 3bit command + 12bit address + 1bit TR (?)
-+ */
-+static inline __be16 create_spi_cmd(struct ks8995_switch *ks, int cmd,
-+                                  unsigned address)
-+{
-+      u16 result = cmd;
-+
-+      /* make room for address (incl. address shift) */
-+      result <<= ks->chip->addr_width + ks->chip->addr_shift;
-+      /* add address */
-+      result |= address << ks->chip->addr_shift;
-+      /* SPI protocol needs big endian */
-+      return cpu_to_be16(result);
-+}
-+/* ------------------------------------------------------------------------ */
-+static int ks8995_read(struct ks8995_switch *ks, char *buf,
-+               unsigned offset, size_t count)
-+{
-+      __be16 cmd;
-+      struct spi_transfer t[2];
-+      struct spi_message m;
-+      int err;
-+
-+      cmd = create_spi_cmd(ks, KS8995_CMD_READ, offset);
-+      spi_message_init(&m);
-+
-+      memset(&t, 0, sizeof(t));
-+
-+      t[0].tx_buf = &cmd;
-+      t[0].len = sizeof(cmd);
-+      spi_message_add_tail(&t[0], &m);
-+
-+      t[1].rx_buf = buf;
-+      t[1].len = count;
-+      spi_message_add_tail(&t[1], &m);
-+
-+      mutex_lock(&ks->lock);
-+      err = spi_sync(ks->spi, &m);
-+      mutex_unlock(&ks->lock);
-+
-+      return err ? err : count;
-+}
-+
-+static int ks8995_write(struct ks8995_switch *ks, char *buf,
-+               unsigned offset, size_t count)
-+{
-+      __be16 cmd;
-+      struct spi_transfer t[2];
-+      struct spi_message m;
-+      int err;
-+
-+      cmd = create_spi_cmd(ks, KS8995_CMD_WRITE, offset);
-+      spi_message_init(&m);
-+
-+      memset(&t, 0, sizeof(t));
-+
-+      t[0].tx_buf = &cmd;
-+      t[0].len = sizeof(cmd);
-+      spi_message_add_tail(&t[0], &m);
-+
-+      t[1].tx_buf = buf;
-+      t[1].len = count;
-+      spi_message_add_tail(&t[1], &m);
-+
-+      mutex_lock(&ks->lock);
-+      err = spi_sync(ks->spi, &m);
-+      mutex_unlock(&ks->lock);
-+
-+      return err ? err : count;
-+}
-+
-+static inline int ks8995_read_reg(struct ks8995_switch *ks, u8 addr, u8 *buf)
-+{
-+      return ks8995_read(ks, buf, addr, 1) != 1;
-+}
-+
-+static inline int ks8995_write_reg(struct ks8995_switch *ks, u8 addr, u8 val)
-+{
-+      char buf = val;
-+
-+      return ks8995_write(ks, &buf, addr, 1) != 1;
-+}
-+
-+/* ------------------------------------------------------------------------ */
-+
-+static int ks8995_stop(struct ks8995_switch *ks)
-+{
-+      return ks8995_write_reg(ks, KS8995_REG_ID1, 0);
-+}
-+
-+static int ks8995_start(struct ks8995_switch *ks)
-+{
-+      return ks8995_write_reg(ks, KS8995_REG_ID1, 1);
-+}
-+
-+static int ks8995_reset(struct ks8995_switch *ks)
-+{
-+      int err;
-+
-+      err = ks8995_stop(ks);
-+      if (err)
-+              return err;
-+
-+      udelay(KS8995_RESET_DELAY);
-+
-+      return ks8995_start(ks);
-+}
-+
-+static ssize_t ks8995_registers_read(struct file *filp, struct kobject *kobj,
-+      struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
-+{
-+      struct device *dev;
-+      struct ks8995_switch *ks8995;
-+
-+      dev = kobj_to_dev(kobj);
-+      ks8995 = dev_get_drvdata(dev);
-+
-+      return ks8995_read(ks8995, buf, off, count);
-+}
-+
-+static ssize_t ks8995_registers_write(struct file *filp, struct kobject *kobj,
-+      struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
-+{
-+      struct device *dev;
-+      struct ks8995_switch *ks8995;
-+
-+      dev = kobj_to_dev(kobj);
-+      ks8995 = dev_get_drvdata(dev);
-+
-+      return ks8995_write(ks8995, buf, off, count);
-+}
-+
-+/* ks8995_get_revision - get chip revision
-+ * @ks: pointer to switch instance
-+ *
-+ * Verify chip family and id and get chip revision.
-+ */
-+static int ks8995_get_revision(struct ks8995_switch *ks)
-+{
-+      int err;
-+      u8 id0, id1, ksz8864_id;
-+
-+      /* read family id */
-+      err = ks8995_read_reg(ks, KS8995_REG_ID0, &id0);
-+      if (err) {
-+              err = -EIO;
-+              goto err_out;
-+      }
-+
-+      /* verify family id */
-+      if (id0 != ks->chip->family_id) {
-+              dev_err(&ks->spi->dev, "chip family id mismatch: expected 0x%02x but 0x%02x read\n",
-+                      ks->chip->family_id, id0);
-+              err = -ENODEV;
-+              goto err_out;
-+      }
-+
-+      switch (ks->chip->family_id) {
-+      case FAMILY_KS8995:
-+              /* try reading chip id at CHIP ID1 */
-+              err = ks8995_read_reg(ks, KS8995_REG_ID1, &id1);
-+              if (err) {
-+                      err = -EIO;
-+                      goto err_out;
-+              }
-+
-+              /* verify chip id */
-+              if ((get_chip_id(id1) == CHIPID_M) &&
-+                  (get_chip_id(id1) == ks->chip->chip_id)) {
-+                      /* KS8995MA */
-+                      ks->revision_id = get_chip_rev(id1);
-+              } else if (get_chip_id(id1) != CHIPID_M) {
-+                      /* KSZ8864RMN */
-+                      err = ks8995_read_reg(ks, KS8995_REG_ID1, &ksz8864_id);
-+                      if (err) {
-+                              err = -EIO;
-+                              goto err_out;
-+                      }
-+
-+                      if ((ksz8864_id & 0x80) &&
-+                          (ks->chip->chip_id == KSZ8864_CHIP_ID)) {
-+                              ks->revision_id = get_chip_rev(id1);
-+                      }
-+
-+              } else {
-+                      dev_err(&ks->spi->dev, "unsupported chip id for KS8995 family: 0x%02x\n",
-+                              id1);
-+                      err = -ENODEV;
-+              }
-+              break;
-+      case FAMILY_KSZ8795:
-+              /* try reading chip id at CHIP ID1 */
-+              err = ks8995_read_reg(ks, KS8995_REG_ID1, &id1);
-+              if (err) {
-+                      err = -EIO;
-+                      goto err_out;
-+              }
-+
-+              if (get_chip_id(id1) == ks->chip->chip_id) {
-+                      ks->revision_id = get_chip_rev(id1);
-+              } else {
-+                      dev_err(&ks->spi->dev, "unsupported chip id for KSZ8795 family: 0x%02x\n",
-+                              id1);
-+                      err = -ENODEV;
-+              }
-+              break;
-+      default:
-+              dev_err(&ks->spi->dev, "unsupported family id: 0x%02x\n", id0);
-+              err = -ENODEV;
-+              break;
-+      }
-+err_out:
-+      return err;
-+}
-+
-+static const struct bin_attribute ks8995_registers_attr = {
-+      .attr = {
-+              .name   = "registers",
-+              .mode   = 0600,
-+      },
-+      .size   = KS8995_REGS_SIZE,
-+      .read   = ks8995_registers_read,
-+      .write  = ks8995_registers_write,
-+};
-+
-+/* ------------------------------------------------------------------------ */
-+static int ks8995_probe(struct spi_device *spi)
-+{
-+      struct ks8995_switch *ks;
-+      int err;
-+      int variant = spi_get_device_id(spi)->driver_data;
-+
-+      if (variant >= max_variant) {
-+              dev_err(&spi->dev, "bad chip variant %d\n", variant);
-+              return -ENODEV;
-+      }
-+
-+      ks = devm_kzalloc(&spi->dev, sizeof(*ks), GFP_KERNEL);
-+      if (!ks)
-+              return -ENOMEM;
-+
-+      mutex_init(&ks->lock);
-+      ks->spi = spi;
-+      ks->chip = &ks8995_chip[variant];
-+
-+      ks->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
-+                                               GPIOD_OUT_HIGH);
-+      err = PTR_ERR_OR_ZERO(ks->reset_gpio);
-+      if (err) {
-+              dev_err(&spi->dev,
-+                      "failed to get reset gpio: %d\n", err);
-+              return err;
-+      }
-+
-+      err = gpiod_set_consumer_name(ks->reset_gpio, "switch-reset");
-+      if (err)
-+              return err;
-+
-+      /* de-assert switch reset */
-+      /* FIXME: this likely requires a delay */
-+      gpiod_set_value_cansleep(ks->reset_gpio, 0);
-+
-+      spi_set_drvdata(spi, ks);
-+
-+      spi->mode = SPI_MODE_0;
-+      spi->bits_per_word = 8;
-+      err = spi_setup(spi);
-+      if (err) {
-+              dev_err(&spi->dev, "spi_setup failed, err=%d\n", err);
-+              return err;
-+      }
-+
-+      err = ks8995_get_revision(ks);
-+      if (err)
-+              return err;
-+
-+      memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr));
-+      ks->regs_attr.size = ks->chip->regs_size;
-+
-+      err = ks8995_reset(ks);
-+      if (err)
-+              return err;
-+
-+      sysfs_attr_init(&ks->regs_attr.attr);
-+      err = sysfs_create_bin_file(&spi->dev.kobj, &ks->regs_attr);
-+      if (err) {
-+              dev_err(&spi->dev, "unable to create sysfs file, err=%d\n",
-+                                  err);
-+              return err;
-+      }
-+
-+      dev_info(&spi->dev, "%s device found, Chip ID:%x, Revision:%x\n",
-+               ks->chip->name, ks->chip->chip_id, ks->revision_id);
-+
-+      return 0;
-+}
-+
-+static void ks8995_remove(struct spi_device *spi)
-+{
-+      struct ks8995_switch *ks = spi_get_drvdata(spi);
-+
-+      sysfs_remove_bin_file(&spi->dev.kobj, &ks->regs_attr);
-+
-+      /* assert reset */
-+      gpiod_set_value_cansleep(ks->reset_gpio, 1);
-+}
-+
-+/* ------------------------------------------------------------------------ */
-+static struct spi_driver ks8995_driver = {
-+      .driver = {
-+              .name       = "spi-ks8995",
-+              .of_match_table = ks8895_spi_of_match,
-+      },
-+      .probe    = ks8995_probe,
-+      .remove   = ks8995_remove,
-+      .id_table = ks8995_id,
-+};
-+
-+module_spi_driver(ks8995_driver);
-+
-+MODULE_DESCRIPTION(DRV_DESC);
-+MODULE_VERSION(DRV_VERSION);
-+MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/net/phy/spi_ks8995.c
-+++ /dev/null
-@@ -1,506 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/*
-- * SPI driver for Micrel/Kendin KS8995M and KSZ8864RMN ethernet switches
-- *
-- * Copyright (C) 2008 Gabor Juhos <juhosg at openwrt.org>
-- *
-- * This file was based on: drivers/spi/at25.c
-- *     Copyright (C) 2006 David Brownell
-- */
--
--#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
--
--#include <linux/types.h>
--#include <linux/kernel.h>
--#include <linux/module.h>
--#include <linux/delay.h>
--#include <linux/device.h>
--#include <linux/gpio/consumer.h>
--#include <linux/of.h>
--
--#include <linux/spi/spi.h>
--
--#define DRV_VERSION           "0.1.1"
--#define DRV_DESC              "Micrel KS8995 Ethernet switch SPI driver"
--
--/* ------------------------------------------------------------------------ */
--
--#define KS8995_REG_ID0                0x00    /* Chip ID0 */
--#define KS8995_REG_ID1                0x01    /* Chip ID1 */
--
--#define KS8995_REG_GC0                0x02    /* Global Control 0 */
--#define KS8995_REG_GC1                0x03    /* Global Control 1 */
--#define KS8995_REG_GC2                0x04    /* Global Control 2 */
--#define KS8995_REG_GC3                0x05    /* Global Control 3 */
--#define KS8995_REG_GC4                0x06    /* Global Control 4 */
--#define KS8995_REG_GC5                0x07    /* Global Control 5 */
--#define KS8995_REG_GC6                0x08    /* Global Control 6 */
--#define KS8995_REG_GC7                0x09    /* Global Control 7 */
--#define KS8995_REG_GC8                0x0a    /* Global Control 8 */
--#define KS8995_REG_GC9                0x0b    /* Global Control 9 */
--
--#define KS8995_REG_PC(p, r)   ((0x10 * p) + r)         /* Port Control */
--#define KS8995_REG_PS(p, r)   ((0x10 * p) + r + 0xe)  /* Port Status */
--
--#define KS8995_REG_TPC0               0x60    /* TOS Priority Control 0 */
--#define KS8995_REG_TPC1               0x61    /* TOS Priority Control 1 */
--#define KS8995_REG_TPC2               0x62    /* TOS Priority Control 2 */
--#define KS8995_REG_TPC3               0x63    /* TOS Priority Control 3 */
--#define KS8995_REG_TPC4               0x64    /* TOS Priority Control 4 */
--#define KS8995_REG_TPC5               0x65    /* TOS Priority Control 5 */
--#define KS8995_REG_TPC6               0x66    /* TOS Priority Control 6 */
--#define KS8995_REG_TPC7               0x67    /* TOS Priority Control 7 */
--
--#define KS8995_REG_MAC0               0x68    /* MAC address 0 */
--#define KS8995_REG_MAC1               0x69    /* MAC address 1 */
--#define KS8995_REG_MAC2               0x6a    /* MAC address 2 */
--#define KS8995_REG_MAC3               0x6b    /* MAC address 3 */
--#define KS8995_REG_MAC4               0x6c    /* MAC address 4 */
--#define KS8995_REG_MAC5               0x6d    /* MAC address 5 */
--
--#define KS8995_REG_IAC0               0x6e    /* Indirect Access Control 0 */
--#define KS8995_REG_IAC1               0x6f    /* Indirect Access Control 0 */
--#define KS8995_REG_IAD7               0x70    /* Indirect Access Data 7 */
--#define KS8995_REG_IAD6               0x71    /* Indirect Access Data 6 */
--#define KS8995_REG_IAD5               0x72    /* Indirect Access Data 5 */
--#define KS8995_REG_IAD4               0x73    /* Indirect Access Data 4 */
--#define KS8995_REG_IAD3               0x74    /* Indirect Access Data 3 */
--#define KS8995_REG_IAD2               0x75    /* Indirect Access Data 2 */
--#define KS8995_REG_IAD1               0x76    /* Indirect Access Data 1 */
--#define KS8995_REG_IAD0               0x77    /* Indirect Access Data 0 */
--
--#define KSZ8864_REG_ID1               0xfe    /* Chip ID in bit 7 */
--
--#define KS8995_REGS_SIZE      0x80
--#define KSZ8864_REGS_SIZE     0x100
--#define KSZ8795_REGS_SIZE     0x100
--
--#define ID1_CHIPID_M          0xf
--#define ID1_CHIPID_S          4
--#define ID1_REVISION_M                0x7
--#define ID1_REVISION_S                1
--#define ID1_START_SW          1       /* start the switch */
--
--#define FAMILY_KS8995         0x95
--#define FAMILY_KSZ8795                0x87
--#define CHIPID_M              0
--#define KS8995_CHIP_ID                0x00
--#define KSZ8864_CHIP_ID               0x01
--#define KSZ8795_CHIP_ID               0x09
--
--#define KS8995_CMD_WRITE      0x02U
--#define KS8995_CMD_READ               0x03U
--
--#define KS8995_RESET_DELAY    10 /* usec */
--
--enum ks8995_chip_variant {
--      ks8995,
--      ksz8864,
--      ksz8795,
--      max_variant
--};
--
--struct ks8995_chip_params {
--      char *name;
--      int family_id;
--      int chip_id;
--      int regs_size;
--      int addr_width;
--      int addr_shift;
--};
--
--static const struct ks8995_chip_params ks8995_chip[] = {
--      [ks8995] = {
--              .name = "KS8995MA",
--              .family_id = FAMILY_KS8995,
--              .chip_id = KS8995_CHIP_ID,
--              .regs_size = KS8995_REGS_SIZE,
--              .addr_width = 8,
--              .addr_shift = 0,
--      },
--      [ksz8864] = {
--              .name = "KSZ8864RMN",
--              .family_id = FAMILY_KS8995,
--              .chip_id = KSZ8864_CHIP_ID,
--              .regs_size = KSZ8864_REGS_SIZE,
--              .addr_width = 8,
--              .addr_shift = 0,
--      },
--      [ksz8795] = {
--              .name = "KSZ8795CLX",
--              .family_id = FAMILY_KSZ8795,
--              .chip_id = KSZ8795_CHIP_ID,
--              .regs_size = KSZ8795_REGS_SIZE,
--              .addr_width = 12,
--              .addr_shift = 1,
--      },
--};
--
--struct ks8995_switch {
--      struct spi_device       *spi;
--      struct mutex            lock;
--      struct gpio_desc        *reset_gpio;
--      struct bin_attribute    regs_attr;
--      const struct ks8995_chip_params *chip;
--      int                     revision_id;
--};
--
--static const struct spi_device_id ks8995_id[] = {
--      {"ks8995", ks8995},
--      {"ksz8864", ksz8864},
--      {"ksz8795", ksz8795},
--      { }
--};
--MODULE_DEVICE_TABLE(spi, ks8995_id);
--
--static const struct of_device_id ks8895_spi_of_match[] = {
--      { .compatible = "micrel,ks8995" },
--      { .compatible = "micrel,ksz8864" },
--      { .compatible = "micrel,ksz8795" },
--      { },
--};
--MODULE_DEVICE_TABLE(of, ks8895_spi_of_match);
--
--static inline u8 get_chip_id(u8 val)
--{
--      return (val >> ID1_CHIPID_S) & ID1_CHIPID_M;
--}
--
--static inline u8 get_chip_rev(u8 val)
--{
--      return (val >> ID1_REVISION_S) & ID1_REVISION_M;
--}
--
--/* create_spi_cmd - create a chip specific SPI command header
-- * @ks: pointer to switch instance
-- * @cmd: SPI command for switch
-- * @address: register address for command
-- *
-- * Different chip families use different bit pattern to address the switches
-- * registers:
-- *
-- * KS8995: 8bit command + 8bit address
-- * KSZ8795: 3bit command + 12bit address + 1bit TR (?)
-- */
--static inline __be16 create_spi_cmd(struct ks8995_switch *ks, int cmd,
--                                  unsigned address)
--{
--      u16 result = cmd;
--
--      /* make room for address (incl. address shift) */
--      result <<= ks->chip->addr_width + ks->chip->addr_shift;
--      /* add address */
--      result |= address << ks->chip->addr_shift;
--      /* SPI protocol needs big endian */
--      return cpu_to_be16(result);
--}
--/* ------------------------------------------------------------------------ */
--static int ks8995_read(struct ks8995_switch *ks, char *buf,
--               unsigned offset, size_t count)
--{
--      __be16 cmd;
--      struct spi_transfer t[2];
--      struct spi_message m;
--      int err;
--
--      cmd = create_spi_cmd(ks, KS8995_CMD_READ, offset);
--      spi_message_init(&m);
--
--      memset(&t, 0, sizeof(t));
--
--      t[0].tx_buf = &cmd;
--      t[0].len = sizeof(cmd);
--      spi_message_add_tail(&t[0], &m);
--
--      t[1].rx_buf = buf;
--      t[1].len = count;
--      spi_message_add_tail(&t[1], &m);
--
--      mutex_lock(&ks->lock);
--      err = spi_sync(ks->spi, &m);
--      mutex_unlock(&ks->lock);
--
--      return err ? err : count;
--}
--
--static int ks8995_write(struct ks8995_switch *ks, char *buf,
--               unsigned offset, size_t count)
--{
--      __be16 cmd;
--      struct spi_transfer t[2];
--      struct spi_message m;
--      int err;
--
--      cmd = create_spi_cmd(ks, KS8995_CMD_WRITE, offset);
--      spi_message_init(&m);
--
--      memset(&t, 0, sizeof(t));
--
--      t[0].tx_buf = &cmd;
--      t[0].len = sizeof(cmd);
--      spi_message_add_tail(&t[0], &m);
--
--      t[1].tx_buf = buf;
--      t[1].len = count;
--      spi_message_add_tail(&t[1], &m);
--
--      mutex_lock(&ks->lock);
--      err = spi_sync(ks->spi, &m);
--      mutex_unlock(&ks->lock);
--
--      return err ? err : count;
--}
--
--static inline int ks8995_read_reg(struct ks8995_switch *ks, u8 addr, u8 *buf)
--{
--      return ks8995_read(ks, buf, addr, 1) != 1;
--}
--
--static inline int ks8995_write_reg(struct ks8995_switch *ks, u8 addr, u8 val)
--{
--      char buf = val;
--
--      return ks8995_write(ks, &buf, addr, 1) != 1;
--}
--
--/* ------------------------------------------------------------------------ */
--
--static int ks8995_stop(struct ks8995_switch *ks)
--{
--      return ks8995_write_reg(ks, KS8995_REG_ID1, 0);
--}
--
--static int ks8995_start(struct ks8995_switch *ks)
--{
--      return ks8995_write_reg(ks, KS8995_REG_ID1, 1);
--}
--
--static int ks8995_reset(struct ks8995_switch *ks)
--{
--      int err;
--
--      err = ks8995_stop(ks);
--      if (err)
--              return err;
--
--      udelay(KS8995_RESET_DELAY);
--
--      return ks8995_start(ks);
--}
--
--static ssize_t ks8995_registers_read(struct file *filp, struct kobject *kobj,
--      struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
--{
--      struct device *dev;
--      struct ks8995_switch *ks8995;
--
--      dev = kobj_to_dev(kobj);
--      ks8995 = dev_get_drvdata(dev);
--
--      return ks8995_read(ks8995, buf, off, count);
--}
--
--static ssize_t ks8995_registers_write(struct file *filp, struct kobject *kobj,
--      struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
--{
--      struct device *dev;
--      struct ks8995_switch *ks8995;
--
--      dev = kobj_to_dev(kobj);
--      ks8995 = dev_get_drvdata(dev);
--
--      return ks8995_write(ks8995, buf, off, count);
--}
--
--/* ks8995_get_revision - get chip revision
-- * @ks: pointer to switch instance
-- *
-- * Verify chip family and id and get chip revision.
-- */
--static int ks8995_get_revision(struct ks8995_switch *ks)
--{
--      int err;
--      u8 id0, id1, ksz8864_id;
--
--      /* read family id */
--      err = ks8995_read_reg(ks, KS8995_REG_ID0, &id0);
--      if (err) {
--              err = -EIO;
--              goto err_out;
--      }
--
--      /* verify family id */
--      if (id0 != ks->chip->family_id) {
--              dev_err(&ks->spi->dev, "chip family id mismatch: expected 0x%02x but 0x%02x read\n",
--                      ks->chip->family_id, id0);
--              err = -ENODEV;
--              goto err_out;
--      }
--
--      switch (ks->chip->family_id) {
--      case FAMILY_KS8995:
--              /* try reading chip id at CHIP ID1 */
--              err = ks8995_read_reg(ks, KS8995_REG_ID1, &id1);
--              if (err) {
--                      err = -EIO;
--                      goto err_out;
--              }
--
--              /* verify chip id */
--              if ((get_chip_id(id1) == CHIPID_M) &&
--                  (get_chip_id(id1) == ks->chip->chip_id)) {
--                      /* KS8995MA */
--                      ks->revision_id = get_chip_rev(id1);
--              } else if (get_chip_id(id1) != CHIPID_M) {
--                      /* KSZ8864RMN */
--                      err = ks8995_read_reg(ks, KS8995_REG_ID1, &ksz8864_id);
--                      if (err) {
--                              err = -EIO;
--                              goto err_out;
--                      }
--
--                      if ((ksz8864_id & 0x80) &&
--                          (ks->chip->chip_id == KSZ8864_CHIP_ID)) {
--                              ks->revision_id = get_chip_rev(id1);
--                      }
--
--              } else {
--                      dev_err(&ks->spi->dev, "unsupported chip id for KS8995 family: 0x%02x\n",
--                              id1);
--                      err = -ENODEV;
--              }
--              break;
--      case FAMILY_KSZ8795:
--              /* try reading chip id at CHIP ID1 */
--              err = ks8995_read_reg(ks, KS8995_REG_ID1, &id1);
--              if (err) {
--                      err = -EIO;
--                      goto err_out;
--              }
--
--              if (get_chip_id(id1) == ks->chip->chip_id) {
--                      ks->revision_id = get_chip_rev(id1);
--              } else {
--                      dev_err(&ks->spi->dev, "unsupported chip id for KSZ8795 family: 0x%02x\n",
--                              id1);
--                      err = -ENODEV;
--              }
--              break;
--      default:
--              dev_err(&ks->spi->dev, "unsupported family id: 0x%02x\n", id0);
--              err = -ENODEV;
--              break;
--      }
--err_out:
--      return err;
--}
--
--static const struct bin_attribute ks8995_registers_attr = {
--      .attr = {
--              .name   = "registers",
--              .mode   = 0600,
--      },
--      .size   = KS8995_REGS_SIZE,
--      .read   = ks8995_registers_read,
--      .write  = ks8995_registers_write,
--};
--
--/* ------------------------------------------------------------------------ */
--static int ks8995_probe(struct spi_device *spi)
--{
--      struct ks8995_switch *ks;
--      int err;
--      int variant = spi_get_device_id(spi)->driver_data;
--
--      if (variant >= max_variant) {
--              dev_err(&spi->dev, "bad chip variant %d\n", variant);
--              return -ENODEV;
--      }
--
--      ks = devm_kzalloc(&spi->dev, sizeof(*ks), GFP_KERNEL);
--      if (!ks)
--              return -ENOMEM;
--
--      mutex_init(&ks->lock);
--      ks->spi = spi;
--      ks->chip = &ks8995_chip[variant];
--
--      ks->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
--                                               GPIOD_OUT_HIGH);
--      err = PTR_ERR_OR_ZERO(ks->reset_gpio);
--      if (err) {
--              dev_err(&spi->dev,
--                      "failed to get reset gpio: %d\n", err);
--              return err;
--      }
--
--      err = gpiod_set_consumer_name(ks->reset_gpio, "switch-reset");
--      if (err)
--              return err;
--
--      /* de-assert switch reset */
--      /* FIXME: this likely requires a delay */
--      gpiod_set_value_cansleep(ks->reset_gpio, 0);
--
--      spi_set_drvdata(spi, ks);
--
--      spi->mode = SPI_MODE_0;
--      spi->bits_per_word = 8;
--      err = spi_setup(spi);
--      if (err) {
--              dev_err(&spi->dev, "spi_setup failed, err=%d\n", err);
--              return err;
--      }
--
--      err = ks8995_get_revision(ks);
--      if (err)
--              return err;
--
--      memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr));
--      ks->regs_attr.size = ks->chip->regs_size;
--
--      err = ks8995_reset(ks);
--      if (err)
--              return err;
--
--      sysfs_attr_init(&ks->regs_attr.attr);
--      err = sysfs_create_bin_file(&spi->dev.kobj, &ks->regs_attr);
--      if (err) {
--              dev_err(&spi->dev, "unable to create sysfs file, err=%d\n",
--                                  err);
--              return err;
--      }
--
--      dev_info(&spi->dev, "%s device found, Chip ID:%x, Revision:%x\n",
--               ks->chip->name, ks->chip->chip_id, ks->revision_id);
--
--      return 0;
--}
--
--static void ks8995_remove(struct spi_device *spi)
--{
--      struct ks8995_switch *ks = spi_get_drvdata(spi);
--
--      sysfs_remove_bin_file(&spi->dev.kobj, &ks->regs_attr);
--
--      /* assert reset */
--      gpiod_set_value_cansleep(ks->reset_gpio, 1);
--}
--
--/* ------------------------------------------------------------------------ */
--static struct spi_driver ks8995_driver = {
--      .driver = {
--              .name       = "spi-ks8995",
--              .of_match_table = ks8895_spi_of_match,
--      },
--      .probe    = ks8995_probe,
--      .remove   = ks8995_remove,
--      .id_table = ks8995_id,
--};
--
--module_spi_driver(ks8995_driver);
--
--MODULE_DESCRIPTION(DRV_DESC);
--MODULE_VERSION(DRV_VERSION);
--MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
--MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/backport-6.18/783-02-v6.18-net-dsa-ks8995-Add-proper-RESET-delay.patch b/target/linux/generic/backport-6.18/783-02-v6.18-net-dsa-ks8995-Add-proper-RESET-delay.patch
deleted file mode 100644 (file)
index 3b0b731..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From 7367bfc8b34d7ad5b0c06e19fe24533db22ed8ea Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 13 Aug 2025 23:43:04 +0200
-Subject: [PATCH 2/4] net: dsa: ks8995: Add proper RESET delay
-
-According to the datasheet we need to wait 100us before accessing
-any registers in the KS8995 after a reset de-assertion.
-
-Add this delay, if and only if we obtained a GPIO descriptor,
-otherwise it is just a pointless delay.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250813-ks8995-to-dsa-v1-2-75c359ede3a5@linaro.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/ks8995.c | 12 +++++++++---
- 1 file changed, 9 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/ks8995.c
-+++ b/drivers/net/dsa/ks8995.c
-@@ -438,9 +438,15 @@ static int ks8995_probe(struct spi_devic
-       if (err)
-               return err;
--      /* de-assert switch reset */
--      /* FIXME: this likely requires a delay */
--      gpiod_set_value_cansleep(ks->reset_gpio, 0);
-+      if (ks->reset_gpio) {
-+              /*
-+               * If a reset line was obtained, wait for 100us after
-+               * de-asserting RESET before accessing any registers, see
-+               * the KS8995MA datasheet, page 44.
-+               */
-+              gpiod_set_value_cansleep(ks->reset_gpio, 0);
-+              udelay(100);
-+      }
-       spi_set_drvdata(spi, ks);
diff --git a/target/linux/generic/backport-6.18/783-03-v6.18-net-dsa-ks8995-Delete-sysfs-register-access.patch b/target/linux/generic/backport-6.18/783-03-v6.18-net-dsa-ks8995-Delete-sysfs-register-access.patch
deleted file mode 100644 (file)
index 78b9141..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-From 0e8d3f3623a45f69b6641ff9921ecd0c5afaa4ca Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 13 Aug 2025 23:43:05 +0200
-Subject: [PATCH 3/4] net: dsa: ks8995: Delete sysfs register access
-
-There is some sysfs file to read and write registers randomly
-in the ks8995 driver.
-
-The contemporary way to achieve the same thing is to implement
-regmap abstractions, if needed. Delete this and implement
-regmap later if we want to be able to inspect individual registers.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250813-ks8995-to-dsa-v1-3-75c359ede3a5@linaro.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/ks8995.c | 48 ----------------------------------------
- 1 file changed, 48 deletions(-)
-
---- a/drivers/net/dsa/ks8995.c
-+++ b/drivers/net/dsa/ks8995.c
-@@ -140,7 +140,6 @@ struct ks8995_switch {
-       struct spi_device       *spi;
-       struct mutex            lock;
-       struct gpio_desc        *reset_gpio;
--      struct bin_attribute    regs_attr;
-       const struct ks8995_chip_params *chip;
-       int                     revision_id;
- };
-@@ -288,30 +287,6 @@ static int ks8995_reset(struct ks8995_sw
-       return ks8995_start(ks);
- }
--static ssize_t ks8995_registers_read(struct file *filp, struct kobject *kobj,
--      struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
--{
--      struct device *dev;
--      struct ks8995_switch *ks8995;
--
--      dev = kobj_to_dev(kobj);
--      ks8995 = dev_get_drvdata(dev);
--
--      return ks8995_read(ks8995, buf, off, count);
--}
--
--static ssize_t ks8995_registers_write(struct file *filp, struct kobject *kobj,
--      struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
--{
--      struct device *dev;
--      struct ks8995_switch *ks8995;
--
--      dev = kobj_to_dev(kobj);
--      ks8995 = dev_get_drvdata(dev);
--
--      return ks8995_write(ks8995, buf, off, count);
--}
--
- /* ks8995_get_revision - get chip revision
-  * @ks: pointer to switch instance
-  *
-@@ -395,16 +370,6 @@ err_out:
-       return err;
- }
--static const struct bin_attribute ks8995_registers_attr = {
--      .attr = {
--              .name   = "registers",
--              .mode   = 0600,
--      },
--      .size   = KS8995_REGS_SIZE,
--      .read   = ks8995_registers_read,
--      .write  = ks8995_registers_write,
--};
--
- /* ------------------------------------------------------------------------ */
- static int ks8995_probe(struct spi_device *spi)
- {
-@@ -462,21 +427,10 @@ static int ks8995_probe(struct spi_devic
-       if (err)
-               return err;
--      memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr));
--      ks->regs_attr.size = ks->chip->regs_size;
--
-       err = ks8995_reset(ks);
-       if (err)
-               return err;
--      sysfs_attr_init(&ks->regs_attr.attr);
--      err = sysfs_create_bin_file(&spi->dev.kobj, &ks->regs_attr);
--      if (err) {
--              dev_err(&spi->dev, "unable to create sysfs file, err=%d\n",
--                                  err);
--              return err;
--      }
--
-       dev_info(&spi->dev, "%s device found, Chip ID:%x, Revision:%x\n",
-                ks->chip->name, ks->chip->chip_id, ks->revision_id);
-@@ -487,8 +441,6 @@ static void ks8995_remove(struct spi_dev
- {
-       struct ks8995_switch *ks = spi_get_drvdata(spi);
--      sysfs_remove_bin_file(&spi->dev.kobj, &ks->regs_attr);
--
-       /* assert reset */
-       gpiod_set_value_cansleep(ks->reset_gpio, 1);
- }
diff --git a/target/linux/generic/backport-6.18/783-04-v6.18-net-dsa-ks8995-Add-basic-switch-set-up.patch b/target/linux/generic/backport-6.18/783-04-v6.18-net-dsa-ks8995-Add-basic-switch-set-up.patch
deleted file mode 100644 (file)
index 3454e11..0000000
+++ /dev/null
@@ -1,546 +0,0 @@
-From 4b486b63e07313e1e3807f9d5e6636aa564e0fbc Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 13 Aug 2025 23:43:06 +0200
-Subject: [PATCH 4/4] net: dsa: ks8995: Add basic switch set-up
-
-We start to extend the KS8995 driver by simply registering it
-as a DSA device and implementing a few switch callbacks for
-STP set-up and such to begin with.
-
-No special tags or other advanced stuff: we use DSA_TAG_NONE
-and rely on the default set-up in the switch with the special
-DSA tags turned off. This makes the switch wire up properly
-to all its PHY's and simple bridge traffic works properly.
-
-After this the bridge DT bindings are respected, ports and their
-PHYs get connected to the switch and react appropriately through
-the phylib when cables are plugged in etc.
-
-Tested like this in a hacky OpenWrt image:
-
-Bring up conduit interface manually:
-ixp4xx_eth c8009000.ethernet eth0: eth0: link up,
-  speed 100 Mb/s, full duplex
-
-spi-ks8995 spi0.0: enable port 0
-spi-ks8995 spi0.0: set KS8995_REG_PC2 for port 0 to 06
-spi-ks8995 spi0.0 lan1: configuring for phy/mii link mode
-spi-ks8995 spi0.0 lan1: Link is Up - 100Mbps/Full - flow control rx/tx
-
-PING 169.254.1.1 (169.254.1.1): 56 data bytes
-64 bytes from 169.254.1.1: seq=0 ttl=64 time=1.629 ms
-64 bytes from 169.254.1.1: seq=1 ttl=64 time=0.951 ms
-
-I also tested SSH from the device to the host and it works fine.
-
-It also works fine to ping the device from the host and to SSH
-into the device from the host.
-
-This brings the ks8995 driver to a reasonable state where it can
-be used from the current device tree bindings and the existing
-device trees in the kernel.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250813-ks8995-to-dsa-v1-4-75c359ede3a5@linaro.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/Kconfig  |   1 +
- drivers/net/dsa/ks8995.c | 398 ++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 396 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -103,6 +103,7 @@ config NET_DSA_RZN1_A5PSW
- config NET_DSA_KS8995
-       tristate "Micrel KS8995 family 5-ports 10/100 Ethernet switches"
-       depends on SPI
-+      select NET_DSA_TAG_NONE
-       help
-         This driver supports the Micrel KS8995 family of 10/100 Mbit ethernet
-         switches, managed over SPI.
---- a/drivers/net/dsa/ks8995.c
-+++ b/drivers/net/dsa/ks8995.c
-@@ -3,6 +3,7 @@
-  * SPI driver for Micrel/Kendin KS8995M and KSZ8864RMN ethernet switches
-  *
-  * Copyright (C) 2008 Gabor Juhos <juhosg at openwrt.org>
-+ * Copyright (C) 2025 Linus Walleij <linus.walleij@linaro.org>
-  *
-  * This file was based on: drivers/spi/at25.c
-  *     Copyright (C) 2006 David Brownell
-@@ -10,6 +11,9 @@
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-+#include <linux/bits.h>
-+#include <linux/if_bridge.h>
-+#include <linux/if_vlan.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
-@@ -17,8 +21,8 @@
- #include <linux/device.h>
- #include <linux/gpio/consumer.h>
- #include <linux/of.h>
--
- #include <linux/spi/spi.h>
-+#include <net/dsa.h>
- #define DRV_VERSION           "0.1.1"
- #define DRV_DESC              "Micrel KS8995 Ethernet switch SPI driver"
-@@ -29,18 +33,59 @@
- #define KS8995_REG_ID1                0x01    /* Chip ID1 */
- #define KS8995_REG_GC0                0x02    /* Global Control 0 */
-+
-+#define KS8995_GC0_P5_PHY     BIT(3)  /* Port 5 PHY enabled */
-+
- #define KS8995_REG_GC1                0x03    /* Global Control 1 */
- #define KS8995_REG_GC2                0x04    /* Global Control 2 */
-+
-+#define KS8995_GC2_HUGE               BIT(2)  /* Huge packet support */
-+#define KS8995_GC2_LEGAL      BIT(1)  /* Legal size override */
-+
- #define KS8995_REG_GC3                0x05    /* Global Control 3 */
- #define KS8995_REG_GC4                0x06    /* Global Control 4 */
-+
-+#define KS8995_GC4_10BT               BIT(4)  /* Force switch to 10Mbit */
-+#define KS8995_GC4_MII_FLOW   BIT(5)  /* MII full-duplex flow control enable */
-+#define KS8995_GC4_MII_HD     BIT(6)  /* MII half-duplex mode enable */
-+
- #define KS8995_REG_GC5                0x07    /* Global Control 5 */
- #define KS8995_REG_GC6                0x08    /* Global Control 6 */
- #define KS8995_REG_GC7                0x09    /* Global Control 7 */
- #define KS8995_REG_GC8                0x0a    /* Global Control 8 */
- #define KS8995_REG_GC9                0x0b    /* Global Control 9 */
--#define KS8995_REG_PC(p, r)   ((0x10 * p) + r)         /* Port Control */
--#define KS8995_REG_PS(p, r)   ((0x10 * p) + r + 0xe)  /* Port Status */
-+#define KS8995_GC9_SPECIAL    BIT(0)  /* Special tagging mode (DSA) */
-+
-+/* In DSA the ports 1-4 are numbered 0-3 and the CPU port is port 4 */
-+#define KS8995_REG_PC(p, r)   (0x10 + (0x10 * (p)) + (r)) /* Port Control */
-+#define KS8995_REG_PS(p, r)   (0x1e + (0x10 * (p)) + (r)) /* Port Status */
-+
-+#define KS8995_REG_PC0                0x00    /* Port Control 0 */
-+#define KS8995_REG_PC1                0x01    /* Port Control 1 */
-+#define KS8995_REG_PC2                0x02    /* Port Control 2 */
-+#define KS8995_REG_PC3                0x03    /* Port Control 3 */
-+#define KS8995_REG_PC4                0x04    /* Port Control 4 */
-+#define KS8995_REG_PC5                0x05    /* Port Control 5 */
-+#define KS8995_REG_PC6                0x06    /* Port Control 6 */
-+#define KS8995_REG_PC7                0x07    /* Port Control 7 */
-+#define KS8995_REG_PC8                0x08    /* Port Control 8 */
-+#define KS8995_REG_PC9                0x09    /* Port Control 9 */
-+#define KS8995_REG_PC10               0x0a    /* Port Control 10 */
-+#define KS8995_REG_PC11               0x0b    /* Port Control 11 */
-+#define KS8995_REG_PC12               0x0c    /* Port Control 12 */
-+#define KS8995_REG_PC13               0x0d    /* Port Control 13 */
-+
-+#define KS8995_PC0_TAG_INS    BIT(2)  /* Enable tag insertion on port */
-+#define KS8995_PC0_TAG_REM    BIT(1)  /* Enable tag removal on port */
-+#define KS8995_PC0_PRIO_EN    BIT(0)  /* Enable priority handling */
-+
-+#define KS8995_PC2_TXEN               BIT(2)  /* Enable TX on port */
-+#define KS8995_PC2_RXEN               BIT(1)  /* Enable RX on port */
-+#define KS8995_PC2_LEARN_DIS  BIT(0)  /* Disable learning on port */
-+
-+#define KS8995_PC13_TXDIS     BIT(6)  /* Disable transmitter */
-+#define KS8995_PC13_PWDN      BIT(3)  /* Power down */
- #define KS8995_REG_TPC0               0x60    /* TOS Priority Control 0 */
- #define KS8995_REG_TPC1               0x61    /* TOS Priority Control 1 */
-@@ -91,6 +136,8 @@
- #define KS8995_CMD_WRITE      0x02U
- #define KS8995_CMD_READ               0x03U
-+#define KS8995_CPU_PORT               4
-+#define KS8995_NUM_PORTS      5 /* 5 ports including the CPU port */
- #define KS8995_RESET_DELAY    10 /* usec */
- enum ks8995_chip_variant {
-@@ -138,10 +185,13 @@ static const struct ks8995_chip_params k
- struct ks8995_switch {
-       struct spi_device       *spi;
-+      struct device           *dev;
-+      struct dsa_switch       *ds;
-       struct mutex            lock;
-       struct gpio_desc        *reset_gpio;
-       const struct ks8995_chip_params *chip;
-       int                     revision_id;
-+      unsigned int max_mtu[KS8995_NUM_PORTS];
- };
- static const struct spi_device_id ks8995_id[] = {
-@@ -370,6 +420,327 @@ err_out:
-       return err;
- }
-+static int ks8995_check_config(struct ks8995_switch *ks)
-+{
-+      int ret;
-+      u8 val;
-+
-+      ret = ks8995_read_reg(ks, KS8995_REG_GC0, &val);
-+      if (ret) {
-+              dev_err(ks->dev, "failed to read KS8995_REG_GC0\n");
-+              return ret;
-+      }
-+
-+      dev_dbg(ks->dev, "port 5 PHY %senabled\n",
-+              (val & KS8995_GC0_P5_PHY) ? "" : "not ");
-+
-+      val |= KS8995_GC0_P5_PHY;
-+      ret = ks8995_write_reg(ks, KS8995_REG_GC0, val);
-+      if (ret)
-+              dev_err(ks->dev, "failed to set KS8995_REG_GC0\n");
-+
-+      dev_dbg(ks->dev, "set KS8995_REG_GC0 to 0x%02x\n", val);
-+
-+      return 0;
-+}
-+
-+static void
-+ks8995_mac_config(struct phylink_config *config, unsigned int mode,
-+                const struct phylink_link_state *state)
-+{
-+}
-+
-+static void
-+ks8995_mac_link_up(struct phylink_config *config, struct phy_device *phydev,
-+                 unsigned int mode, phy_interface_t interface,
-+                 int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+      struct dsa_port *dp = dsa_phylink_to_port(config);
-+      struct ks8995_switch *ks = dp->ds->priv;
-+      int port = dp->index;
-+      int ret;
-+      u8 val;
-+
-+      /* Allow forcing the mode on the fixed CPU port, no autonegotiation.
-+       * We assume autonegotiation works on the PHY-facing ports.
-+       */
-+      if (port != KS8995_CPU_PORT)
-+              return;
-+
-+      dev_dbg(ks->dev, "MAC link up on CPU port (%d)\n", port);
-+
-+      ret = ks8995_read_reg(ks, KS8995_REG_GC4, &val);
-+      if (ret) {
-+              dev_err(ks->dev, "failed to read KS8995_REG_GC4\n");
-+              return;
-+      }
-+
-+      /* Conjure port config */
-+      switch (speed) {
-+      case SPEED_10:
-+              dev_dbg(ks->dev, "set switch MII to 100Mbit mode\n");
-+              val |= KS8995_GC4_10BT;
-+              break;
-+      case SPEED_100:
-+      default:
-+              dev_dbg(ks->dev, "set switch MII to 100Mbit mode\n");
-+              val &= ~KS8995_GC4_10BT;
-+              break;
-+      }
-+
-+      if (duplex == DUPLEX_HALF) {
-+              dev_dbg(ks->dev, "set switch MII to half duplex\n");
-+              val |= KS8995_GC4_MII_HD;
-+      } else {
-+              dev_dbg(ks->dev, "set switch MII to full duplex\n");
-+              val &= ~KS8995_GC4_MII_HD;
-+      }
-+
-+      dev_dbg(ks->dev, "set KS8995_REG_GC4 to %02x\n", val);
-+
-+      /* Enable the CPU port */
-+      ret = ks8995_write_reg(ks, KS8995_REG_GC4, val);
-+      if (ret)
-+              dev_err(ks->dev, "failed to set KS8995_REG_GC4\n");
-+}
-+
-+static void
-+ks8995_mac_link_down(struct phylink_config *config, unsigned int mode,
-+                   phy_interface_t interface)
-+{
-+      struct dsa_port *dp = dsa_phylink_to_port(config);
-+      struct ks8995_switch *ks = dp->ds->priv;
-+      int port = dp->index;
-+
-+      if (port != KS8995_CPU_PORT)
-+              return;
-+
-+      dev_dbg(ks->dev, "MAC link down on CPU port (%d)\n", port);
-+
-+      /* Disable the CPU port */
-+}
-+
-+static const struct phylink_mac_ops ks8995_phylink_mac_ops = {
-+      .mac_config = ks8995_mac_config,
-+      .mac_link_up = ks8995_mac_link_up,
-+      .mac_link_down = ks8995_mac_link_down,
-+};
-+
-+static enum
-+dsa_tag_protocol ks8995_get_tag_protocol(struct dsa_switch *ds,
-+                                       int port,
-+                                       enum dsa_tag_protocol mp)
-+{
-+      /* This switch actually uses the 6 byte KS8995 protocol */
-+      return DSA_TAG_PROTO_NONE;
-+}
-+
-+static int ks8995_setup(struct dsa_switch *ds)
-+{
-+      return 0;
-+}
-+
-+static int ks8995_port_enable(struct dsa_switch *ds, int port,
-+                            struct phy_device *phy)
-+{
-+      struct ks8995_switch *ks = ds->priv;
-+
-+      dev_dbg(ks->dev, "enable port %d\n", port);
-+
-+      return 0;
-+}
-+
-+static void ks8995_port_disable(struct dsa_switch *ds, int port)
-+{
-+      struct ks8995_switch *ks = ds->priv;
-+
-+      dev_dbg(ks->dev, "disable port %d\n", port);
-+}
-+
-+static int ks8995_port_pre_bridge_flags(struct dsa_switch *ds, int port,
-+                                      struct switchdev_brport_flags flags,
-+                                      struct netlink_ext_ack *extack)
-+{
-+      /* We support enabling/disabling learning */
-+      if (flags.mask & ~(BR_LEARNING))
-+              return -EINVAL;
-+
-+      return 0;
-+}
-+
-+static int ks8995_port_bridge_flags(struct dsa_switch *ds, int port,
-+                                  struct switchdev_brport_flags flags,
-+                                  struct netlink_ext_ack *extack)
-+{
-+      struct ks8995_switch *ks = ds->priv;
-+      int ret;
-+      u8 val;
-+
-+      if (flags.mask & BR_LEARNING) {
-+              ret = ks8995_read_reg(ks, KS8995_REG_PC(port, KS8995_REG_PC2), &val);
-+              if (ret) {
-+                      dev_err(ks->dev, "failed to read KS8995_REG_PC2 on port %d\n", port);
-+                      return ret;
-+              }
-+
-+              if (flags.val & BR_LEARNING)
-+                      val &= ~KS8995_PC2_LEARN_DIS;
-+              else
-+                      val |= KS8995_PC2_LEARN_DIS;
-+
-+              ret = ks8995_write_reg(ks, KS8995_REG_PC(port, KS8995_REG_PC2), val);
-+              if (ret) {
-+                      dev_err(ks->dev, "failed to write KS8995_REG_PC2 on port %d\n", port);
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static void ks8995_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
-+{
-+      struct ks8995_switch *ks = ds->priv;
-+      int ret;
-+      u8 val;
-+
-+      ret = ks8995_read_reg(ks, KS8995_REG_PC(port, KS8995_REG_PC2), &val);
-+      if (ret) {
-+              dev_err(ks->dev, "failed to read KS8995_REG_PC2 on port %d\n", port);
-+              return;
-+      }
-+
-+      /* Set the bits for the different STP states in accordance with
-+       * the datasheet, pages 36-37 "Spanning tree support".
-+       */
-+      switch (state) {
-+      case BR_STATE_DISABLED:
-+      case BR_STATE_BLOCKING:
-+      case BR_STATE_LISTENING:
-+              val &= ~KS8995_PC2_TXEN;
-+              val &= ~KS8995_PC2_RXEN;
-+              val |= KS8995_PC2_LEARN_DIS;
-+              break;
-+      case BR_STATE_LEARNING:
-+              val &= ~KS8995_PC2_TXEN;
-+              val &= ~KS8995_PC2_RXEN;
-+              val &= ~KS8995_PC2_LEARN_DIS;
-+              break;
-+      case BR_STATE_FORWARDING:
-+              val |= KS8995_PC2_TXEN;
-+              val |= KS8995_PC2_RXEN;
-+              val &= ~KS8995_PC2_LEARN_DIS;
-+              break;
-+      default:
-+              dev_err(ks->dev, "unknown bridge state requested\n");
-+              return;
-+      }
-+
-+      ret = ks8995_write_reg(ks, KS8995_REG_PC(port, KS8995_REG_PC2), val);
-+      if (ret) {
-+              dev_err(ks->dev, "failed to write KS8995_REG_PC2 on port %d\n", port);
-+              return;
-+      }
-+
-+      dev_dbg(ks->dev, "set KS8995_REG_PC2 for port %d to %02x\n", port, val);
-+}
-+
-+static void ks8995_phylink_get_caps(struct dsa_switch *dsa, int port,
-+                                  struct phylink_config *config)
-+{
-+      unsigned long *interfaces = config->supported_interfaces;
-+
-+      if (port == KS8995_CPU_PORT)
-+              __set_bit(PHY_INTERFACE_MODE_MII, interfaces);
-+
-+      if (port <= 3) {
-+              /* Internal PHYs */
-+              __set_bit(PHY_INTERFACE_MODE_INTERNAL, interfaces);
-+              /* phylib default */
-+              __set_bit(PHY_INTERFACE_MODE_MII, interfaces);
-+      }
-+
-+      config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
-+}
-+
-+/* Huge packet support up to 1916 byte packages "inclusive"
-+ * which means that tags are included. If the bit is not set
-+ * it is 1536 bytes "inclusive". We present the length without
-+ * tags or ethernet headers. The setting affects all ports.
-+ */
-+static int ks8995_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
-+{
-+      struct ks8995_switch *ks = ds->priv;
-+      unsigned int max_mtu;
-+      int ret;
-+      u8 val;
-+      int i;
-+
-+      ks->max_mtu[port] = new_mtu;
-+
-+      /* Roof out the MTU for the entire switch to the greatest
-+       * common denominator: the biggest set for any one port will
-+       * be the biggest MTU for the switch.
-+       */
-+      max_mtu = ETH_DATA_LEN;
-+      for (i = 0; i < KS8995_NUM_PORTS; i++) {
-+              if (ks->max_mtu[i] > max_mtu)
-+                      max_mtu = ks->max_mtu[i];
-+      }
-+
-+      /* Translate to layer 2 size.
-+       * Add ethernet and (possible) VLAN headers, and checksum to the size.
-+       * For ETH_DATA_LEN (1500 bytes) this will add up to 1522 bytes.
-+       */
-+      max_mtu += VLAN_ETH_HLEN;
-+      max_mtu += ETH_FCS_LEN;
-+
-+      ret = ks8995_read_reg(ks, KS8995_REG_GC2, &val);
-+      if (ret) {
-+              dev_err(ks->dev, "failed to read KS8995_REG_GC2\n");
-+              return ret;
-+      }
-+
-+      if (max_mtu <= 1522) {
-+              val &= ~KS8995_GC2_HUGE;
-+              val &= ~KS8995_GC2_LEGAL;
-+      } else if (max_mtu > 1522 && max_mtu <= 1536) {
-+              /* This accepts packets up to 1536 bytes */
-+              val &= ~KS8995_GC2_HUGE;
-+              val |= KS8995_GC2_LEGAL;
-+      } else {
-+              /* This accepts packets up to 1916 bytes */
-+              val |= KS8995_GC2_HUGE;
-+              val |= KS8995_GC2_LEGAL;
-+      }
-+
-+      dev_dbg(ks->dev, "new max MTU %d bytes (inclusive)\n", max_mtu);
-+
-+      ret = ks8995_write_reg(ks, KS8995_REG_GC2, val);
-+      if (ret)
-+              dev_err(ks->dev, "failed to set KS8995_REG_GC2\n");
-+
-+      return ret;
-+}
-+
-+static int ks8995_get_max_mtu(struct dsa_switch *ds, int port)
-+{
-+      return 1916 - ETH_HLEN - ETH_FCS_LEN;
-+}
-+
-+static const struct dsa_switch_ops ks8995_ds_ops = {
-+      .get_tag_protocol = ks8995_get_tag_protocol,
-+      .setup = ks8995_setup,
-+      .port_pre_bridge_flags = ks8995_port_pre_bridge_flags,
-+      .port_bridge_flags = ks8995_port_bridge_flags,
-+      .port_enable = ks8995_port_enable,
-+      .port_disable = ks8995_port_disable,
-+      .port_stp_state_set = ks8995_port_stp_state_set,
-+      .port_change_mtu = ks8995_change_mtu,
-+      .port_max_mtu = ks8995_get_max_mtu,
-+      .phylink_get_caps = ks8995_phylink_get_caps,
-+};
-+
- /* ------------------------------------------------------------------------ */
- static int ks8995_probe(struct spi_device *spi)
- {
-@@ -388,6 +759,7 @@ static int ks8995_probe(struct spi_devic
-       mutex_init(&ks->lock);
-       ks->spi = spi;
-+      ks->dev = &spi->dev;
-       ks->chip = &ks8995_chip[variant];
-       ks->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
-@@ -434,6 +806,25 @@ static int ks8995_probe(struct spi_devic
-       dev_info(&spi->dev, "%s device found, Chip ID:%x, Revision:%x\n",
-                ks->chip->name, ks->chip->chip_id, ks->revision_id);
-+      err = ks8995_check_config(ks);
-+      if (err)
-+              return err;
-+
-+      ks->ds = devm_kzalloc(&spi->dev, sizeof(*ks->ds), GFP_KERNEL);
-+      if (!ks->ds)
-+              return -ENOMEM;
-+
-+      ks->ds->dev = &spi->dev;
-+      ks->ds->num_ports = KS8995_NUM_PORTS;
-+      ks->ds->ops = &ks8995_ds_ops;
-+      ks->ds->phylink_mac_ops = &ks8995_phylink_mac_ops;
-+      ks->ds->priv = ks;
-+
-+      err = dsa_register_switch(ks->ds);
-+      if (err)
-+              return dev_err_probe(&spi->dev, err,
-+                                   "unable to register DSA switch\n");
-+
-       return 0;
- }
-@@ -441,6 +832,7 @@ static void ks8995_remove(struct spi_dev
- {
-       struct ks8995_switch *ks = spi_get_drvdata(spi);
-+      dsa_unregister_switch(ks->ds);
-       /* assert reset */
-       gpiod_set_value_cansleep(ks->reset_gpio, 1);
- }
diff --git a/target/linux/generic/backport-6.18/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch b/target/linux/generic/backport-6.18/784-01-v6.17-net-phy-realtek-add-error-handling-to-rtl8211f_get_w.patch
deleted file mode 100644 (file)
index 5f3b119..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From a9b24b3583ae1da7dbda031f141264f2da260219 Mon Sep 17 00:00:00 2001
-From: Daniel Braunwarth <daniel.braunwarth@kuka.com>
-Date: Tue, 24 Jun 2025 16:17:33 +0200
-Subject: [PATCH] net: phy: realtek: add error handling to rtl8211f_get_wol
-
-We should check if the WOL settings was successfully read from the PHY.
-
-In case this fails we cannot just use the error code and proceed.
-
-Signed-off-by: Daniel Braunwarth <daniel.braunwarth@kuka.com>
-Reported-by: Jon Hunter <jonathanh@nvidia.com>
-Closes: https://lore.kernel.org/baaa083b-9a69-460f-ab35-2a7cb3246ffd@nvidia.com
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250624-realtek_fixes-v1-1-02a0b7c369bc@kuka.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -436,9 +436,15 @@ static irqreturn_t rtl8211f_handle_inter
- static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
- {
-+      int wol_events;
-+
-       wol->supported = WAKE_MAGIC;
--      if (phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS)
--          & RTL8211F_WOL_EVENT_MAGIC)
-+
-+      wol_events = phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
-+      if (wol_events < 0)
-+              return;
-+
-+      if (wol_events & RTL8211F_WOL_EVENT_MAGIC)
-               wol->wolopts = WAKE_MAGIC;
- }
diff --git a/target/linux/generic/backport-6.18/784-02-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch b/target/linux/generic/backport-6.18/784-02-v6.18-net-phy-realtek-Avoid-PHYCR2-access-if-PHYCR2-not-pr.patch
deleted file mode 100644 (file)
index 681b234..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From 2c67301584f2671e320236df6bbe75ae09feb4d0 Mon Sep 17 00:00:00 2001
-From: Marek Vasut <marek.vasut@mailbox.org>
-Date: Sat, 11 Oct 2025 13:02:49 +0200
-Subject: [PATCH] net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not present
-
-The driver is currently checking for PHYCR2 register presence in
-rtl8211f_config_init(), but it does so after accessing PHYCR2 to
-disable EEE. This was introduced in commit bfc17c165835 ("net:
-phy: realtek: disable PHY-mode EEE"). Move the PHYCR2 presence
-test before the EEE disablement and simplify the code.
-
-Fixes: bfc17c165835 ("net: phy: realtek: disable PHY-mode EEE")
-Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
-Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
-Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Link: https://patch.msgid.link/20251011110309.12664-1-marek.vasut@mailbox.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 23 +++++++++++------------
- 1 file changed, 11 insertions(+), 12 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -589,26 +589,25 @@ static int rtl8211f_config_init(struct p
-                       str_enabled_disabled(val_rxdly));
-       }
-+      if (!priv->has_phycr2)
-+              return 0;
-+
-       /* Disable PHY-mode EEE so LPI is passed to the MAC */
-       ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
-                              RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
-       if (ret)
-               return ret;
--      if (priv->has_phycr2) {
--              ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
--                                     RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
--                                     priv->phycr2);
--              if (ret < 0) {
--                      dev_err(dev, "clkout configuration failed: %pe\n",
--                              ERR_PTR(ret));
--                      return ret;
--              }
--
--              return genphy_soft_reset(phydev);
-+      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
-+                             RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
-+                             priv->phycr2);
-+      if (ret < 0) {
-+              dev_err(dev, "clkout configuration failed: %pe\n",
-+                      ERR_PTR(ret));
-+              return ret;
-       }
--      return 0;
-+      return genphy_soft_reset(phydev);
- }
- static int rtl821x_suspend(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.18/784-02-v6.18-net-phy-realtek-fix-RTL8211F-wake-on-lan-support.patch b/target/linux/generic/backport-6.18/784-02-v6.18-net-phy-realtek-fix-RTL8211F-wake-on-lan-support.patch
deleted file mode 100644 (file)
index b5c4f8f..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-From b826bf795564ddef6402cf2cb522ae035bd117ae Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Wed, 13 Aug 2025 11:04:45 +0100
-Subject: [PATCH] net: phy: realtek: fix RTL8211F wake-on-lan support
-
-Implement Wake-on-Lan for RTL8211F correctly. The existing
-implementation has multiple issues:
-
-1. It assumes that Wake-on-Lan can always be used, whether or not the
-   interrupt is wired, and whether or not the interrupt is capable of
-   waking the system. This breaks the ability for MAC drivers to detect
-   whether the PHY WoL is functional.
-2. switching the interrupt pin in the .set_wol() method to PMEB mode
-   immediately silences link-state interrupts, which breaks phylib
-   when interrupts are being used rather than polling mode.
-3. the code claiming to "reset WOL status" was doing nothing of the
-   sort. Bit 15 in page 0xd8a register 17 controls WoL reset, and
-   needs to be pulsed low to reset the WoL state. This bit was always
-   written as '1', resulting in no reset.
-4. not resetting WoL state results in the PMEB pin remaining asserted,
-   which in turn leads to an interrupt storm. Only resetting the WoL
-   state in .set_wol() is not sufficient.
-5. PMEB mode does not allow software detection of the wake-up event as
-   there is no status bit to indicate we received the WoL packet.
-6. across reboots of at least the Jetson Xavier NX system, the WoL
-   configuration is preserved.
-
-Fix all of these issues by essentially rewriting the support. We:
-1. clear the WoL event enable register at probe time.
-2. detect whether we can support wake-up by having a valid interrupt,
-   and the "wakeup-source" property in DT. If we can, then we mark
-   the MDIO device as wakeup capable, and associate the interrupt
-   with the wakeup source.
-3. arrange for the get_wol() and set_wol() implementations to handle
-   the case where the MDIO device has not been marked as wakeup
-   capable (thereby returning no WoL support, and refusing to enable
-   WoL support.)
-4. avoid switching to PMEB mode, instead using INTB mode with the
-   interrupt enable, reconfiguring the interrupt enables at suspend
-   time, and restoring their original state at resume time (we track
-   the state of the interrupt enable register in .config_intr()
-   register.)
-5. move WoL reset from .set_wol() to the suspend function to ensure
-   that WoL state is cleared prior to suspend. This is necessary
-   after the PME interrupt has been enabled as a second WoL packet
-   will not re-raise a previously cleared PME interrupt.
-6. when a PME interrupt (for wakeup) is asserted, pass this to the
-   PM wakeup so it knows which device woke the system.
-
-This fixes WoL support in the Realtek RTL8211F driver when used on the
-nVidia Jetson Xavier NX platform, and needs to be applied before stmmac
-patches which allow these platforms to forward the ethtool WoL commands
-to the Realtek PHY.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/E1um8Ld-008jxD-Mc@rmk-PC.armlinux.org.uk
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 172 ++++++++++++++++++++-----
- 1 file changed, 140 insertions(+), 32 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -10,6 +10,7 @@
- #include <linux/bitops.h>
- #include <linux/of.h>
- #include <linux/phy.h>
-+#include <linux/pm_wakeirq.h>
- #include <linux/netdevice.h>
- #include <linux/module.h>
- #include <linux/delay.h>
-@@ -31,6 +32,7 @@
- #define RTL821x_INER                          0x12
- #define RTL8211B_INER_INIT                    0x6400
- #define RTL8211E_INER_LINK_STATUS             BIT(10)
-+#define RTL8211F_INER_PME                     BIT(7)
- #define RTL8211F_INER_LINK_STATUS             BIT(4)
- #define RTL821x_INSR                          0x13
-@@ -96,17 +98,13 @@
- #define RTL8211F_RXCR                         0x15
- #define RTL8211F_RX_DELAY                     BIT(3)
--/* RTL8211F WOL interrupt configuration */
--#define RTL8211F_INTBCR_PAGE                  0xd40
--#define RTL8211F_INTBCR                               0x16
--#define RTL8211F_INTBCR_INTB_PMEB             BIT(5)
--
- /* RTL8211F WOL settings */
--#define RTL8211F_WOL_SETTINGS_PAGE            0xd8a
-+#define RTL8211F_WOL_PAGE             0xd8a
- #define RTL8211F_WOL_SETTINGS_EVENTS          16
- #define RTL8211F_WOL_EVENT_MAGIC              BIT(12)
--#define RTL8211F_WOL_SETTINGS_STATUS          17
--#define RTL8211F_WOL_STATUS_RESET             (BIT(15) | 0x1fff)
-+#define RTL8211F_WOL_RST_RMSQ         17
-+#define RTL8211F_WOL_RG_RSTB                  BIT(15)
-+#define RTL8211F_WOL_RMSQ                     0x1fff
- /* RTL8211F Unique phyiscal and multicast address (WOL) */
- #define RTL8211F_PHYSICAL_ADDR_PAGE           0xd8c
-@@ -172,7 +170,8 @@ struct rtl821x_priv {
-       u16 phycr2;
-       bool has_phycr2;
-       struct clk *clk;
--      u32 saved_wolopts;
-+      /* rtl8211f */
-+      u16 iner;
- };
- static int rtl821x_read_page(struct phy_device *phydev)
-@@ -255,6 +254,34 @@ static int rtl821x_probe(struct phy_devi
-       return 0;
- }
-+static int rtl8211f_probe(struct phy_device *phydev)
-+{
-+      struct device *dev = &phydev->mdio.dev;
-+      int ret;
-+
-+      ret = rtl821x_probe(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Disable all PME events */
-+      ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
-+                            RTL8211F_WOL_SETTINGS_EVENTS, 0);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Mark this PHY as wakeup capable and register the interrupt as a
-+       * wakeup IRQ if the PHY is marked as a wakeup source in firmware,
-+       * and the interrupt is valid.
-+       */
-+      if (device_property_read_bool(dev, "wakeup-source") &&
-+          phy_interrupt_is_valid(phydev)) {
-+              device_set_wakeup_capable(dev, true);
-+              devm_pm_set_wake_irq(dev, phydev->irq);
-+      }
-+
-+      return ret;
-+}
-+
- static int rtl8201_ack_interrupt(struct phy_device *phydev)
- {
-       int err;
-@@ -352,6 +379,7 @@ static int rtl8211e_config_intr(struct p
- static int rtl8211f_config_intr(struct phy_device *phydev)
- {
-+      struct rtl821x_priv *priv = phydev->priv;
-       u16 val;
-       int err;
-@@ -362,8 +390,10 @@ static int rtl8211f_config_intr(struct p
-               val = RTL8211F_INER_LINK_STATUS;
-               err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
-+              if (err == 0)
-+                      priv->iner = val;
-       } else {
--              val = 0;
-+              priv->iner = val = 0;
-               err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
-               if (err)
-                       return err;
-@@ -426,21 +456,34 @@ static irqreturn_t rtl8211f_handle_inter
-               return IRQ_NONE;
-       }
--      if (!(irq_status & RTL8211F_INER_LINK_STATUS))
--              return IRQ_NONE;
-+      if (irq_status & RTL8211F_INER_LINK_STATUS) {
-+              phy_trigger_machine(phydev);
-+              return IRQ_HANDLED;
-+      }
--      phy_trigger_machine(phydev);
-+      if (irq_status & RTL8211F_INER_PME) {
-+              pm_wakeup_event(&phydev->mdio.dev, 0);
-+              return IRQ_HANDLED;
-+      }
--      return IRQ_HANDLED;
-+      return IRQ_NONE;
- }
- static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
- {
-       int wol_events;
-+      /* If the PHY is not capable of waking the system, then WoL can not
-+       * be supported.
-+       */
-+      if (!device_can_wakeup(&dev->mdio.dev)) {
-+              wol->supported = 0;
-+              return;
-+      }
-+
-       wol->supported = WAKE_MAGIC;
--      wol_events = phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
-+      wol_events = phy_read_paged(dev, RTL8211F_WOL_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
-       if (wol_events < 0)
-               return;
-@@ -453,6 +496,9 @@ static int rtl8211f_set_wol(struct phy_d
-       const u8 *mac_addr = dev->attached_dev->dev_addr;
-       int oldpage;
-+      if (!device_can_wakeup(&dev->mdio.dev))
-+              return -EOPNOTSUPP;
-+
-       oldpage = phy_save_page(dev);
-       if (oldpage < 0)
-               goto err;
-@@ -464,25 +510,23 @@ static int rtl8211f_set_wol(struct phy_d
-               __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD1, mac_addr[3] << 8 | (mac_addr[2]));
-               __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD2, mac_addr[5] << 8 | (mac_addr[4]));
--              /* Enable magic packet matching and reset WOL status */
--              rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
-+              /* Enable magic packet matching */
-+              rtl821x_write_page(dev, RTL8211F_WOL_PAGE);
-               __phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, RTL8211F_WOL_EVENT_MAGIC);
--              __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
--
--              /* Enable the WOL interrupt */
--              rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
--              __phy_set_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
-+              /* Set the maximum packet size, and assert WoL reset */
-+              __phy_write(dev, RTL8211F_WOL_RST_RMSQ, RTL8211F_WOL_RMSQ);
-       } else {
--              /* Disable the WOL interrupt */
--              rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
--              __phy_clear_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
--
--              /* Disable magic packet matching and reset WOL status */
--              rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
-+              /* Disable magic packet matching */
-+              rtl821x_write_page(dev, RTL8211F_WOL_PAGE);
-               __phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, 0);
--              __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
-+
-+              /* Place WoL in reset */
-+              __phy_clear_bits(dev, RTL8211F_WOL_RST_RMSQ,
-+                               RTL8211F_WOL_RG_RSTB);
-       }
-+      device_set_wakeup_enable(&dev->mdio.dev, !!(wol->wolopts & WAKE_MAGIC));
-+
- err:
-       return phy_restore_page(dev, oldpage, 0);
- }
-@@ -627,6 +671,52 @@ static int rtl821x_suspend(struct phy_de
-       return ret;
- }
-+static int rtl8211f_suspend(struct phy_device *phydev)
-+{
-+      u16 wol_rst;
-+      int ret;
-+
-+      ret = rtl821x_suspend(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* If a PME event is enabled, then configure the interrupt for
-+       * PME events only, disabling link interrupt. We avoid switching
-+       * to PMEB mode as we don't have a status bit for that.
-+       */
-+      if (device_may_wakeup(&phydev->mdio.dev)) {
-+              ret = phy_write_paged(phydev, 0xa42, RTL821x_INER,
-+                                    RTL8211F_INER_PME);
-+              if (ret < 0)
-+                      goto err;
-+
-+              /* Read the INSR to clear any pending interrupt */
-+              phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
-+
-+              /* Reset the WoL to ensure that an event is picked up.
-+               * Unless we do this, even if we receive another packet,
-+               * we may not have a PME interrupt raised.
-+               */
-+              ret = phy_read_paged(phydev, RTL8211F_WOL_PAGE,
-+                                   RTL8211F_WOL_RST_RMSQ);
-+              if (ret < 0)
-+                      goto err;
-+
-+              wol_rst = ret & ~RTL8211F_WOL_RG_RSTB;
-+              ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
-+                                    RTL8211F_WOL_RST_RMSQ, wol_rst);
-+              if (ret < 0)
-+                      goto err;
-+
-+              wol_rst |= RTL8211F_WOL_RG_RSTB;
-+              ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
-+                                    RTL8211F_WOL_RST_RMSQ, wol_rst);
-+      }
-+
-+err:
-+      return ret;
-+}
-+
- static int rtl821x_resume(struct phy_device *phydev)
- {
-       struct rtl821x_priv *priv = phydev->priv;
-@@ -644,6 +734,24 @@ static int rtl821x_resume(struct phy_dev
-       return 0;
- }
-+static int rtl8211f_resume(struct phy_device *phydev)
-+{
-+      struct rtl821x_priv *priv = phydev->priv;
-+      int ret;
-+
-+      ret = rtl821x_resume(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* If the device was programmed for a PME event, restore the interrupt
-+       * enable so phylib can receive link state interrupts.
-+       */
-+      if (device_may_wakeup(&phydev->mdio.dev))
-+              ret = phy_write_paged(phydev, 0xa42, RTL821x_INER, priv->iner);
-+
-+      return ret;
-+}
-+
- static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-                                       unsigned long rules)
- {
-@@ -1639,15 +1747,15 @@ static struct phy_driver realtek_drvs[]
-       }, {
-               PHY_ID_MATCH_EXACT(0x001cc916),
-               .name           = "RTL8211F Gigabit Ethernet",
--              .probe          = rtl821x_probe,
-+              .probe          = rtl8211f_probe,
-               .config_init    = &rtl8211f_config_init,
-               .read_status    = rtlgen_read_status,
-               .config_intr    = &rtl8211f_config_intr,
-               .handle_interrupt = rtl8211f_handle_interrupt,
-               .set_wol        = rtl8211f_set_wol,
-               .get_wol        = rtl8211f_get_wol,
--              .suspend        = rtl821x_suspend,
--              .resume         = rtl821x_resume,
-+              .suspend        = rtl8211f_suspend,
-+              .resume         = rtl8211f_resume,
-               .read_page      = rtl821x_read_page,
-               .write_page     = rtl821x_write_page,
-               .flags          = PHY_ALWAYS_CALL_SUSPEND,
diff --git a/target/linux/generic/backport-6.18/784-03-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch b/target/linux/generic/backport-6.18/784-03-v6.18-net-phy-realtek-fix-rtl8221b-vm-cg-name.patch
deleted file mode 100644 (file)
index ab319f0..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From ffff5c8fc2af2218a3332b3d5b97654599d50cde Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Thu, 16 Oct 2025 21:22:52 +0200
-Subject: [PATCH] net: phy: realtek: fix rtl8221b-vm-cg name
-
-When splitting the RTL8221B-VM-CG into C22 and C45 variants, the name was
-accidentally changed to RTL8221B-VN-CG. This patch brings back the previous
-part number.
-
-Fixes: ad5ce743a6b0 ("net: phy: realtek: Add driver instances for rtl8221b via Clause 45")
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://patch.msgid.link/20251016192325.2306757-1-olek2@wp.pl
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -154,7 +154,7 @@
- #define RTL_8211FVD_PHYID                     0x001cc878
- #define RTL_8221B                             0x001cc840
- #define RTL_8221B_VB_CG                               0x001cc849
--#define RTL_8221B_VN_CG                               0x001cc84a
-+#define RTL_8221B_VM_CG                               0x001cc84a
- #define RTL_8251B                             0x001cc862
- #define RTL_8261C                             0x001cc890
-@@ -1498,16 +1498,16 @@ static int rtl8221b_vb_cg_c45_match_phy_
-       return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
- }
--static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev,
-+static int rtl8221b_vm_cg_c22_match_phy_device(struct phy_device *phydev,
-                                              const struct phy_driver *phydrv)
- {
--      return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
-+      return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, false);
- }
--static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev,
-+static int rtl8221b_vm_cg_c45_match_phy_device(struct phy_device *phydev,
-                                              const struct phy_driver *phydrv)
- {
--      return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
-+      return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, true);
- }
- static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev,
-@@ -1854,7 +1854,7 @@ static struct phy_driver realtek_drvs[]
-               .suspend        = genphy_c45_pma_suspend,
-               .resume         = rtlgen_c45_resume,
-       }, {
--              .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
-+              .match_phy_device = rtl8221b_vm_cg_c22_match_phy_device,
-               .name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
-               .probe          = rtl822x_probe,
-               .get_features   = rtl822x_get_features,
-@@ -1867,8 +1867,8 @@ static struct phy_driver realtek_drvs[]
-               .read_page      = rtl821x_read_page,
-               .write_page     = rtl821x_write_page,
-       }, {
--              .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
--              .name           = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
-+              .match_phy_device = rtl8221b_vm_cg_c45_match_phy_device,
-+              .name           = "RTL8221B-VM-CG 2.5Gbps PHY (C45)",
-               .probe          = rtl822x_probe,
-               .config_init    = rtl822xb_config_init,
-               .get_rate_matching = rtl822xb_get_rate_matching,
diff --git a/target/linux/generic/backport-6.18/784-03-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch b/target/linux/generic/backport-6.18/784-03-v6.18-net-phy-realtek-support-for-TRIGGER_NETDEV_LINK-on-R.patch
deleted file mode 100644 (file)
index dc8d247..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-From f63f21e82ecafd288b100ea161247820bf1e92c4 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Mon, 25 Aug 2025 23:09:49 +0200
-Subject: [PATCH] net: phy: realtek: support for TRIGGER_NETDEV_LINK on
- RTL8211E and RTL8211F
-
-This patch adds support for the TRIGGER_NETDEV_LINK trigger. It activates
-the LED when a link is established, regardless of the speed.
-
-Tested on Orange Pi PC2 with RTL8211E PHY.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250825211059.143231-1-olek2@wp.pl
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 39 +++++++++++++++++++++-----
- 1 file changed, 32 insertions(+), 7 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -755,7 +755,8 @@ static int rtl8211f_resume(struct phy_de
- static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
-                                       unsigned long rules)
- {
--      const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) |
-+      const unsigned long mask = BIT(TRIGGER_NETDEV_LINK) |
-+                                 BIT(TRIGGER_NETDEV_LINK_10) |
-                                  BIT(TRIGGER_NETDEV_LINK_100) |
-                                  BIT(TRIGGER_NETDEV_LINK_1000) |
-                                  BIT(TRIGGER_NETDEV_RX) |
-@@ -813,6 +814,12 @@ static int rtl8211f_led_hw_control_get(s
-       if (val & RTL8211F_LEDCR_LINK_1000)
-               __set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+      if ((val & RTL8211F_LEDCR_LINK_10) &&
-+          (val & RTL8211F_LEDCR_LINK_100) &&
-+          (val & RTL8211F_LEDCR_LINK_1000)) {
-+              __set_bit(TRIGGER_NETDEV_LINK, rules);
-+      }
-+
-       if (val & RTL8211F_LEDCR_ACT_TXRX) {
-               __set_bit(TRIGGER_NETDEV_RX, rules);
-               __set_bit(TRIGGER_NETDEV_TX, rules);
-@@ -830,14 +837,20 @@ static int rtl8211f_led_hw_control_set(s
-       if (index >= RTL8211x_LED_COUNT)
-               return -EINVAL;
--      if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+      if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
-+          test_bit(TRIGGER_NETDEV_LINK_10, &rules)) {
-               reg |= RTL8211F_LEDCR_LINK_10;
-+      }
--      if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+      if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
-+          test_bit(TRIGGER_NETDEV_LINK_100, &rules)) {
-               reg |= RTL8211F_LEDCR_LINK_100;
-+      }
--      if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+      if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
-+          test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) {
-               reg |= RTL8211F_LEDCR_LINK_1000;
-+      }
-       if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
-           test_bit(TRIGGER_NETDEV_TX, &rules)) {
-@@ -885,6 +898,12 @@ static int rtl8211e_led_hw_control_get(s
-       if (cr2 & RTL8211E_LEDCR2_LINK_1000)
-               __set_bit(TRIGGER_NETDEV_LINK_1000, rules);
-+      if ((cr2 & RTL8211E_LEDCR2_LINK_10) &&
-+          (cr2 & RTL8211E_LEDCR2_LINK_100) &&
-+          (cr2 & RTL8211E_LEDCR2_LINK_1000)) {
-+              __set_bit(TRIGGER_NETDEV_LINK, rules);
-+      }
-+
-       return ret;
- }
-@@ -912,14 +931,20 @@ static int rtl8211e_led_hw_control_set(s
-       if (ret < 0)
-               return ret;
--      if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
-+      if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
-+          test_bit(TRIGGER_NETDEV_LINK_10, &rules)) {
-               cr2 |= RTL8211E_LEDCR2_LINK_10;
-+      }
--      if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
-+      if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
-+          test_bit(TRIGGER_NETDEV_LINK_100, &rules)) {
-               cr2 |= RTL8211E_LEDCR2_LINK_100;
-+      }
--      if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
-+      if (test_bit(TRIGGER_NETDEV_LINK, &rules) ||
-+          test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) {
-               cr2 |= RTL8211E_LEDCR2_LINK_1000;
-+      }
-       cr2 <<= RTL8211E_LEDCR2_SHIFT * index;
-       ret = rtl821x_modify_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE,
diff --git a/target/linux/generic/backport-6.18/784-08-v6.19-net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch b/target/linux/generic/backport-6.18/784-08-v6.19-net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch
deleted file mode 100644 (file)
index 0c523ee..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-From 8e982441ba601d982dd0739972115d85ae01d99b Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 18 Nov 2025 01:40:28 +0200
-Subject: [PATCH] net: phy: realtek: create rtl8211f_config_rgmii_delay()
-
-The control flow in rtl8211f_config_init() has some pitfalls which were
-probably unintended. Specifically it has an early return:
-
-       switch (phydev->interface) {
-       ...
-       default: /* the rest of the modes imply leaving delay as is. */
-               return 0;
-       }
-
-which exits the entire config_init() function. This means it also skips
-doing things such as disabling CLKOUT or disabling PHY-mode EEE.
-
-For the RTL8211FS, which uses PHY_INTERFACE_MODE_SGMII, this might be a
-problem. However, I don't know that it is, so there is no Fixes: tag.
-The issue was observed through code inspection.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20251117234033.345679-2-vladimir.oltean@nxp.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 65 +++++++++++++++-----------
- 1 file changed, 39 insertions(+), 26 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -587,22 +587,11 @@ static int rtl8211c_config_init(struct p
-                           CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
- }
--static int rtl8211f_config_init(struct phy_device *phydev)
-+static int rtl8211f_config_rgmii_delay(struct phy_device *phydev)
- {
--      struct rtl821x_priv *priv = phydev->priv;
--      struct device *dev = &phydev->mdio.dev;
-       u16 val_txdly, val_rxdly;
-       int ret;
--      ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
--                                     RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
--                                     priv->phycr1);
--      if (ret < 0) {
--              dev_err(dev, "aldps mode  configuration failed: %pe\n",
--                      ERR_PTR(ret));
--              return ret;
--      }
--
-       switch (phydev->interface) {
-       case PHY_INTERFACE_MODE_RGMII:
-               val_txdly = 0;
-@@ -632,34 +621,58 @@ static int rtl8211f_config_init(struct p
-                                      RTL8211F_TXCR, RTL8211F_TX_DELAY,
-                                      val_txdly);
-       if (ret < 0) {
--              dev_err(dev, "Failed to update the TX delay register\n");
-+              phydev_err(phydev, "Failed to update the TX delay register: %pe\n",
-+                         ERR_PTR(ret));
-               return ret;
-       } else if (ret) {
--              dev_dbg(dev,
--                      "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
--                      str_enable_disable(val_txdly));
-+              phydev_dbg(phydev,
-+                         "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
-+                         str_enable_disable(val_txdly));
-       } else {
--              dev_dbg(dev,
--                      "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
--                      str_enabled_disabled(val_txdly));
-+              phydev_dbg(phydev,
-+                         "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
-+                         str_enabled_disabled(val_txdly));
-       }
-       ret = phy_modify_paged_changed(phydev, RTL8211F_RGMII_PAGE,
-                                      RTL8211F_RXCR, RTL8211F_RX_DELAY,
-                                      val_rxdly);
-       if (ret < 0) {
--              dev_err(dev, "Failed to update the RX delay register\n");
-+              phydev_err(phydev, "Failed to update the RX delay register: %pe\n",
-+                         ERR_PTR(ret));
-               return ret;
-       } else if (ret) {
--              dev_dbg(dev,
--                      "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
--                      str_enable_disable(val_rxdly));
-+              phydev_dbg(phydev,
-+                         "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
-+                         str_enable_disable(val_rxdly));
-       } else {
--              dev_dbg(dev,
--                      "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
--                      str_enabled_disabled(val_rxdly));
-+              phydev_dbg(phydev,
-+                         "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
-+                         str_enabled_disabled(val_rxdly));
-       }
-+      return 0;
-+}
-+
-+static int rtl8211f_config_init(struct phy_device *phydev)
-+{
-+      struct rtl821x_priv *priv = phydev->priv;
-+      struct device *dev = &phydev->mdio.dev;
-+      int ret;
-+
-+      ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
-+                                     RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
-+                                     priv->phycr1);
-+      if (ret < 0) {
-+              dev_err(dev, "aldps mode  configuration failed: %pe\n",
-+                      ERR_PTR(ret));
-+              return ret;
-+      }
-+
-+      ret = rtl8211f_config_rgmii_delay(phydev);
-+      if (ret)
-+              return ret;
-+
-       if (!priv->has_phycr2)
-               return 0;
diff --git a/target/linux/generic/backport-6.18/784-09-v6.19-net-phy-realtek-eliminate-priv-phycr2-variable.patch b/target/linux/generic/backport-6.18/784-09-v6.19-net-phy-realtek-eliminate-priv-phycr2-variable.patch
deleted file mode 100644 (file)
index 1c67961..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-From 27033d06917758d47162581da7e9de8004049dee Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 18 Nov 2025 01:40:29 +0200
-Subject: [PATCH] net: phy: realtek: eliminate priv->phycr2 variable
-
-The RTL8211F(D)(I)-VD-CG PHY also has support for disabling the CLKOUT,
-and we'd like to introduce the "realtek,clkout-disable" property for
-that.
-
-But it isn't done through the PHYCR2 register, and it becomes awkward to
-have the driver pretend that it is. So just replace the machine-level
-"u16 phycr2" variable with a logical "bool disable_clk_out", which
-scales better to the other PHY as well.
-
-The change is a complete functional equivalent. Before, if the device
-tree property was absent, priv->phycr2 would contain the RTL8211F_CLKOUT_EN
-bit as read from hardware. Now, we don't save priv->phycr2, but we just
-don't call phy_modify_paged() on it. Also, we can simply call
-phy_modify_paged() with the "set" argument to 0.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Link: https://patch.msgid.link/20251117234033.345679-3-vladimir.oltean@nxp.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 38 ++++++++++++++++----------
- 1 file changed, 23 insertions(+), 15 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -194,8 +194,8 @@ MODULE_LICENSE("GPL");
- struct rtl821x_priv {
-       u16 phycr1;
--      u16 phycr2;
-       bool has_phycr2;
-+      bool disable_clk_out;
-       struct clk *clk;
-       /* rtl8211f */
-       u16 iner;
-@@ -266,15 +266,8 @@ static int rtl821x_probe(struct phy_devi
-               priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
-       priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
--      if (priv->has_phycr2) {
--              ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2);
--              if (ret < 0)
--                      return ret;
--
--              priv->phycr2 = ret & RTL8211F_CLKOUT_EN;
--              if (of_property_read_bool(dev->of_node, "realtek,clkout-disable"))
--                      priv->phycr2 &= ~RTL8211F_CLKOUT_EN;
--      }
-+      priv->disable_clk_out = of_property_read_bool(dev->of_node,
-+                                                    "realtek,clkout-disable");
-       phydev->priv = priv;
-@@ -654,6 +647,23 @@ static int rtl8211f_config_rgmii_delay(s
-       return 0;
- }
-+static int rtl8211f_config_clk_out(struct phy_device *phydev)
-+{
-+      struct rtl821x_priv *priv = phydev->priv;
-+      int ret;
-+
-+      /* The value is preserved if the device tree property is absent */
-+      if (!priv->disable_clk_out)
-+              return 0;
-+
-+      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
-+                             RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
-+      if (ret)
-+              return ret;
-+
-+      return genphy_soft_reset(phydev);
-+}
-+
- static int rtl8211f_config_init(struct phy_device *phydev)
- {
-       struct rtl821x_priv *priv = phydev->priv;
-@@ -682,16 +692,14 @@ static int rtl8211f_config_init(struct p
-       if (ret)
-               return ret;
--      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
--                             RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
--                             priv->phycr2);
--      if (ret < 0) {
-+      ret = rtl8211f_config_clk_out(phydev);
-+      if (ret) {
-               dev_err(dev, "clkout configuration failed: %pe\n",
-                       ERR_PTR(ret));
-               return ret;
-       }
--      return genphy_soft_reset(phydev);
-+      return 0;
- }
- static int rtl821x_suspend(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.18/784-10-v6.19-net-phy-realtek-eliminate-has_phycr2-variable.patch b/target/linux/generic/backport-6.18/784-10-v6.19-net-phy-realtek-eliminate-has_phycr2-variable.patch
deleted file mode 100644 (file)
index a78cb3d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-From 910ac7bfb1af1ae4cd141ef80e03a6729213c189 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 18 Nov 2025 01:40:30 +0200
-Subject: [PATCH] net: phy: realtek: eliminate has_phycr2 variable
-
-This variable is assigned in rtl821x_probe() and used in
-rtl8211f_config_init(), which is more complex than it needs to be.
-Simply testing the same condition from rtl821x_probe() in
-rtl8211f_config_init() yields the same result (the PHY driver ID is a
-runtime invariant), but with one temporary variable less.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20251117234033.345679-4-vladimir.oltean@nxp.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -194,7 +194,6 @@ MODULE_LICENSE("GPL");
- struct rtl821x_priv {
-       u16 phycr1;
--      bool has_phycr2;
-       bool disable_clk_out;
-       struct clk *clk;
-       /* rtl8211f */
-@@ -245,7 +244,6 @@ static int rtl821x_probe(struct phy_devi
- {
-       struct device *dev = &phydev->mdio.dev;
-       struct rtl821x_priv *priv;
--      u32 phy_id = phydev->drv->phy_id;
-       int ret;
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-@@ -265,7 +263,6 @@ static int rtl821x_probe(struct phy_devi
-       if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
-               priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
--      priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
-       priv->disable_clk_out = of_property_read_bool(dev->of_node,
-                                                     "realtek,clkout-disable");
-@@ -683,7 +680,8 @@ static int rtl8211f_config_init(struct p
-       if (ret)
-               return ret;
--      if (!priv->has_phycr2)
-+      /* RTL8211FVD has no PHYCR2 register */
-+      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
-               return 0;
-       /* Disable PHY-mode EEE so LPI is passed to the MAC */
diff --git a/target/linux/generic/backport-6.18/784-11-v6.19-net-phy-realtek-allow-CLKOUT-to-be-disabled-on-RTL82.patch b/target/linux/generic/backport-6.18/784-11-v6.19-net-phy-realtek-allow-CLKOUT-to-be-disabled-on-RTL82.patch
deleted file mode 100644 (file)
index 2a3239d..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-From e1a31c41bef678afe0d99b7f0dc3711a80c68447 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 18 Nov 2025 01:40:31 +0200
-Subject: [PATCH] net: phy: realtek: allow CLKOUT to be disabled on
- RTL8211F(D)(I)-VD-CG
-
-Add CLKOUT disable support for RTL8211F(D)(I)-VD-CG. Like with other PHY
-variants, this feature might be requested by customers when the clock
-output is not used, in order to reduce electromagnetic interference (EMI).
-
-In the common driver, the CLKOUT configuration is done through PHYCR2.
-The RTL_8211FVD_PHYID is singled out as not having that register, and
-execution in rtl8211f_config_init() returns early after commit
-2c67301584f2 ("net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not
-present").
-
-But actually CLKOUT is configured through a different register for this
-PHY. Instead of pretending this is PHYCR2 (which it is not), just add
-some code for modifying this register inside the rtl8211f_disable_clk_out()
-function, and move that outside the code portion that runs only if
-PHYCR2 exists.
-
-In practice this reorders the PHYCR2 writes to disable PHY-mode EEE and
-to disable the CLKOUT for the normal RTL8211F variants, but this should
-be perfectly fine.
-
-It was not noted that RTL8211F(D)(I)-VD-CG would need a genphy_soft_reset()
-call after disabling the CLKOUT. Despite that, we do it out of caution
-and for symmetry with the other RTL8211F models.
-
-Co-developed-by: Clark Wang <xiaoning.wang@nxp.com>
-Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20251117234033.345679-5-vladimir.oltean@nxp.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 31 ++++++++++++++++++--------
- 1 file changed, 22 insertions(+), 9 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -90,6 +90,14 @@
- #define RTL8211F_LEDCR_MASK                   GENMASK(4, 0)
- #define RTL8211F_LEDCR_SHIFT                  5
-+/* RTL8211F(D)(I)-VD-CG CLKOUT configuration is specified via magic values
-+ * to undocumented register pages. The names here do not reflect the datasheet.
-+ * Unlike other PHY models, CLKOUT configuration does not go through PHYCR2.
-+ */
-+#define RTL8211FVD_CLKOUT_PAGE                        0xd05
-+#define RTL8211FVD_CLKOUT_REG                 0x11
-+#define RTL8211FVD_CLKOUT_EN                  BIT(8)
-+
- /* RTL8211F RGMII configuration */
- #define RTL8211F_RGMII_PAGE                   0xd08
-@@ -653,8 +661,13 @@ static int rtl8211f_config_clk_out(struc
-       if (!priv->disable_clk_out)
-               return 0;
--      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
--                             RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
-+      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
-+              ret = phy_modify_paged(phydev, RTL8211FVD_CLKOUT_PAGE,
-+                                     RTL8211FVD_CLKOUT_REG,
-+                                     RTL8211FVD_CLKOUT_EN, 0);
-+      else
-+              ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
-+                                     RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
-       if (ret)
-               return ret;
-@@ -680,6 +693,13 @@ static int rtl8211f_config_init(struct p
-       if (ret)
-               return ret;
-+      ret = rtl8211f_config_clk_out(phydev);
-+      if (ret) {
-+              dev_err(dev, "clkout configuration failed: %pe\n",
-+                      ERR_PTR(ret));
-+              return ret;
-+      }
-+
-       /* RTL8211FVD has no PHYCR2 register */
-       if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
-               return 0;
-@@ -690,13 +710,6 @@ static int rtl8211f_config_init(struct p
-       if (ret)
-               return ret;
--      ret = rtl8211f_config_clk_out(phydev);
--      if (ret) {
--              dev_err(dev, "clkout configuration failed: %pe\n",
--                      ERR_PTR(ret));
--              return ret;
--      }
--
-       return 0;
- }
diff --git a/target/linux/generic/backport-6.18/784-12-v6.19-net-phy-realtek-eliminate-priv-phycr1-variable.patch b/target/linux/generic/backport-6.18/784-12-v6.19-net-phy-realtek-eliminate-priv-phycr1-variable.patch
deleted file mode 100644 (file)
index a2e5abe..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-From bb78b71faf60d11a15f07e3390fcfd31e5e523bb Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 18 Nov 2025 01:40:32 +0200
-Subject: [PATCH] net: phy: realtek: eliminate priv->phycr1 variable
-
-Previous changes have replaced the machine-level priv->phycr2 with a
-high-level priv->disable_clk_out. This created a discrepancy with
-priv->phycr1 which is resolved here, for uniformity.
-
-One advantage of this new implementation is that we don't read
-priv->phycr1 in rtl821x_probe() if we're never going to modify it.
-
-We never test the positive return code from phy_modify_mmd_changed(), so
-we could just as well use phy_modify_mmd().
-
-I took the ALDPS feature description from commit d90db36a9e74 ("net:
-phy: realtek: add dt property to enable ALDPS mode") and transformed it
-into a function comment - the feature is sufficiently non-obvious to
-deserve that.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20251117234033.345679-6-vladimir.oltean@nxp.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 44 ++++++++++++++++----------
- 1 file changed, 28 insertions(+), 16 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -201,7 +201,7 @@ MODULE_AUTHOR("Johnson Leung");
- MODULE_LICENSE("GPL");
- struct rtl821x_priv {
--      u16 phycr1;
-+      bool enable_aldps;
-       bool disable_clk_out;
-       struct clk *clk;
-       /* rtl8211f */
-@@ -252,7 +252,6 @@ static int rtl821x_probe(struct phy_devi
- {
-       struct device *dev = &phydev->mdio.dev;
-       struct rtl821x_priv *priv;
--      int ret;
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-@@ -263,14 +262,8 @@ static int rtl821x_probe(struct phy_devi
-               return dev_err_probe(dev, PTR_ERR(priv->clk),
-                                    "failed to get phy clock\n");
--      ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1);
--      if (ret < 0)
--              return ret;
--
--      priv->phycr1 = ret & (RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF);
--      if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
--              priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
--
-+      priv->enable_aldps = of_property_read_bool(dev->of_node,
-+                                                 "realtek,aldps-enable");
-       priv->disable_clk_out = of_property_read_bool(dev->of_node,
-                                                     "realtek,clkout-disable");
-@@ -674,17 +667,36 @@ static int rtl8211f_config_clk_out(struc
-       return genphy_soft_reset(phydev);
- }
--static int rtl8211f_config_init(struct phy_device *phydev)
-+/* Advance Link Down Power Saving (ALDPS) mode changes crystal/clock behaviour,
-+ * which causes the RXC clock signal to stop for tens to hundreds of
-+ * milliseconds.
-+ *
-+ * Some MACs need the RXC clock to support their internal RX logic, so ALDPS is
-+ * only enabled based on an opt-in device tree property.
-+ */
-+static int rtl8211f_config_aldps(struct phy_device *phydev)
- {
-       struct rtl821x_priv *priv = phydev->priv;
-+      u16 mask = RTL8211F_ALDPS_PLL_OFF |
-+                 RTL8211F_ALDPS_ENABLE |
-+                 RTL8211F_ALDPS_XTAL_OFF;
-+
-+      /* The value is preserved if the device tree property is absent */
-+      if (!priv->enable_aldps)
-+              return 0;
-+
-+      return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
-+                              mask, mask);
-+}
-+
-+static int rtl8211f_config_init(struct phy_device *phydev)
-+{
-       struct device *dev = &phydev->mdio.dev;
-       int ret;
--      ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
--                                     RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
--                                     priv->phycr1);
--      if (ret < 0) {
--              dev_err(dev, "aldps mode  configuration failed: %pe\n",
-+      ret = rtl8211f_config_aldps(phydev);
-+      if (ret) {
-+              dev_err(dev, "aldps mode configuration failed: %pe\n",
-                       ERR_PTR(ret));
-               return ret;
-       }
diff --git a/target/linux/generic/backport-6.18/784-13-v6.19-net-phy-realtek-create-rtl8211f_config_phy_eee-helpe.patch b/target/linux/generic/backport-6.18/784-13-v6.19-net-phy-realtek-create-rtl8211f_config_phy_eee-helpe.patch
deleted file mode 100644 (file)
index 54ec217..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-From 4465ae435ddc0162d5033a543658449d53d46d08 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Tue, 18 Nov 2025 01:40:33 +0200
-Subject: [PATCH] net: phy: realtek: create rtl8211f_config_phy_eee() helper
-
-To simplify the rtl8211f_config_init() control flow and get rid of
-"early" returns for PHYs where the PHYCR2 register is absent, move the
-entire logic sub-block that deals with disabling PHY-mode EEE to a
-separate function. There, it is much more obvious what the early
-"return 0" skips, and it becomes more difficult to accidentally skip
-unintended stuff.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Link: https://patch.msgid.link/20251117234033.345679-7-vladimir.oltean@nxp.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/realtek/realtek_main.c | 23 ++++++++++++-----------
- 1 file changed, 12 insertions(+), 11 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -689,6 +689,17 @@ static int rtl8211f_config_aldps(struct
-                               mask, mask);
- }
-+static int rtl8211f_config_phy_eee(struct phy_device *phydev)
-+{
-+      /* RTL8211FVD has no PHYCR2 register */
-+      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
-+              return 0;
-+
-+      /* Disable PHY-mode EEE so LPI is passed to the MAC */
-+      return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
-+                              RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
-+}
-+
- static int rtl8211f_config_init(struct phy_device *phydev)
- {
-       struct device *dev = &phydev->mdio.dev;
-@@ -712,17 +723,7 @@ static int rtl8211f_config_init(struct p
-               return ret;
-       }
--      /* RTL8211FVD has no PHYCR2 register */
--      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
--              return 0;
--
--      /* Disable PHY-mode EEE so LPI is passed to the MAC */
--      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
--                             RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
--      if (ret)
--              return ret;
--
--      return 0;
-+      return rtl8211f_config_phy_eee(phydev);
- }
- static int rtl821x_suspend(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.18/785-v6.18-r8169-fix-RTL8127-hang-on-suspend-shutdown.patch b/target/linux/generic/backport-6.18/785-v6.18-r8169-fix-RTL8127-hang-on-suspend-shutdown.patch
deleted file mode 100644 (file)
index 269fc89..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-From ae1737e7339b513f8c2fc21b500a0fc215d155c3 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 22 Nov 2025 15:23:02 +0100
-Subject: r8169: fix RTL8127 hang on suspend/shutdown
-
-There have been reports that RTL8127 hangs on suspend and shutdown,
-partially disappearing from lspci until power-cycling.
-According to Realtek disabling PLL's when switching to D3 should be
-avoided on that chip version. Fix this by aligning disabling PLL's
-with the vendor drivers, what in addition results in PLL's not being
-disabled when switching to D3hot on other chip versions.
-
-Fixes: f24f7b2f3af9 ("r8169: add support for RTL8127A")
-Tested-by: Fabio Baltieri <fabio.baltieri@gmail.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Link: https://patch.msgid.link/d7faae7e-66bc-404a-a432-3a496600575f@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 19 ++++++++++++++-----
- 1 file changed, 14 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -1516,11 +1516,20 @@ static enum rtl_dash_type rtl_get_dash_t
- static void rtl_set_d3_pll_down(struct rtl8169_private *tp, bool enable)
- {
--      if (tp->mac_version >= RTL_GIGA_MAC_VER_25 &&
--          tp->mac_version != RTL_GIGA_MAC_VER_28 &&
--          tp->mac_version != RTL_GIGA_MAC_VER_31 &&
--          tp->mac_version != RTL_GIGA_MAC_VER_38)
--              r8169_mod_reg8_cond(tp, PMCH, D3_NO_PLL_DOWN, !enable);
-+      switch (tp->mac_version) {
-+      case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_24:
-+      case RTL_GIGA_MAC_VER_28:
-+      case RTL_GIGA_MAC_VER_31:
-+      case RTL_GIGA_MAC_VER_38:
-+              break;
-+      case RTL_GIGA_MAC_VER_80:
-+              r8169_mod_reg8_cond(tp, PMCH, D3_NO_PLL_DOWN, true);
-+              break;
-+      default:
-+              r8169_mod_reg8_cond(tp, PMCH, D3HOT_NO_PLL_DOWN, true);
-+              r8169_mod_reg8_cond(tp, PMCH, D3COLD_NO_PLL_DOWN, !enable);
-+              break;
-+      }
- }
- static void rtl_reset_packet_filter(struct rtl8169_private *tp)
diff --git a/target/linux/generic/backport-6.18/786-01-v6.18-net-phy-introduce-phy_id_compare_vendor-PHY-ID-helpe.patch b/target/linux/generic/backport-6.18/786-01-v6.18-net-phy-introduce-phy_id_compare_vendor-PHY-ID-helpe.patch
deleted file mode 100644 (file)
index a69a564..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-From 1abe21ef1adf0c5b6dbb5878c2fa4573df8d29fc Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 23 Aug 2025 15:44:28 +0200
-Subject: net: phy: introduce phy_id_compare_vendor() PHY ID helper
-
-Introduce phy_id_compare_vendor() PHY ID helper to compare a PHY ID with
-the PHY ID Vendor using the generic PHY ID Vendor mask.
-
-While at it also rework the PHY_ID_MATCH macro and move the mask to
-dedicated define so that PHY driver can make use of the mask if needed.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://patch.msgid.link/20250823134431.4854-1-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/linux/phy.h | 23 ++++++++++++++++++++---
- 1 file changed, 20 insertions(+), 3 deletions(-)
-
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -1266,9 +1266,13 @@ struct phy_driver {
- #define PHY_ANY_ID "MATCH ANY PHY"
- #define PHY_ANY_UID 0xffffffff
--#define PHY_ID_MATCH_EXACT(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 0)
--#define PHY_ID_MATCH_MODEL(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 4)
--#define PHY_ID_MATCH_VENDOR(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 10)
-+#define PHY_ID_MATCH_EXTACT_MASK GENMASK(31, 0)
-+#define PHY_ID_MATCH_MODEL_MASK GENMASK(31, 4)
-+#define PHY_ID_MATCH_VENDOR_MASK GENMASK(31, 10)
-+
-+#define PHY_ID_MATCH_EXACT(id) .phy_id = (id), .phy_id_mask = PHY_ID_MATCH_EXTACT_MASK
-+#define PHY_ID_MATCH_MODEL(id) .phy_id = (id), .phy_id_mask = PHY_ID_MATCH_MODEL_MASK
-+#define PHY_ID_MATCH_VENDOR(id) .phy_id = (id), .phy_id_mask = PHY_ID_MATCH_VENDOR_MASK
- /**
-  * phy_id_compare - compare @id1 with @id2 taking account of @mask
-@@ -1298,6 +1302,19 @@ static inline bool phy_id_compare_model(
- }
- /**
-+ * phy_id_compare_vendor - compare @id with @vendor mask
-+ * @id: PHY ID
-+ * @vendor_mask: PHY Vendor mask
-+ *
-+ * Return: true if the bits from @id match @vendor using the
-+ *       generic PHY Vendor mask.
-+ */
-+static inline bool phy_id_compare_vendor(u32 id, u32 vendor_mask)
-+{
-+      return phy_id_compare(id, vendor_mask, PHY_ID_MATCH_VENDOR_MASK);
-+}
-+
-+/**
-  * phydev_id_compare - compare @id with the PHY's Clause 22 ID
-  * @phydev: the PHY device
-  * @id: the PHY ID to be matched
diff --git a/target/linux/generic/backport-6.18/786-02-v6.18-net-phy-as21xxx-better-handle-PHY-HW-reset-on-soft-r.patch b/target/linux/generic/backport-6.18/786-02-v6.18-net-phy-as21xxx-better-handle-PHY-HW-reset-on-soft-r.patch
deleted file mode 100644 (file)
index 5b00da4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From b4d5cd20507b252c746fa6971d82ac96f3b3e5b7 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Sat, 23 Aug 2025 15:44:29 +0200
-Subject: net: phy: as21xxx: better handle PHY HW reset on soft-reboot
-
-On soft-reboot, with a reset GPIO defined for an Aeonsemi PHY, the
-special match_phy_device fails to correctly identify that the PHY
-needs to load the firmware again.
-
-This is caused by the fact that PHY ID is read BEFORE the PHY reset
-GPIO (if present) is asserted, so we can be in the scenario where the
-phydev have the previous PHY ID (with the PHY firmware loaded) but
-after reset the generic AS21xxx PHY is present in the PHY ID registers.
-
-To better handle this, skip reading the PHY ID register only for the PHY
-that are not AS21xxx (by matching for the Aeonsemi Vendor) and always
-read the PHY ID for the other case to handle both firmware already
-loaded or an HW reset.
-
-Fixes: 830877d89edc ("net: phy: Add support for Aeonsemi AS21xxx PHYs")
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Link: https://patch.msgid.link/20250823134431.4854-2-ansuelsmth@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/as21xxx.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/as21xxx.c
-+++ b/drivers/net/phy/as21xxx.c
-@@ -884,11 +884,12 @@ static int as21xxx_match_phy_device(stru
-       u32 phy_id;
-       int ret;
--      /* Skip PHY that are not AS21xxx or already have firmware loaded */
--      if (phydev->c45_ids.device_ids[MDIO_MMD_PCS] != PHY_ID_AS21XXX)
-+      /* Skip PHY that are not AS21xxx */
-+      if (!phy_id_compare_vendor(phydev->c45_ids.device_ids[MDIO_MMD_PCS],
-+                                 PHY_VENDOR_AEONSEMI))
-               return genphy_match_phy_device(phydev, phydrv);
--      /* Read PHY ID to handle firmware just loaded */
-+      /* Read PHY ID to handle firmware loaded or HW reset */
-       ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID1);
-       if (ret < 0)
-               return ret;
diff --git a/target/linux/generic/backport-6.18/787-v6.19-net-phy-RTL8211FVD-Restore-disabling-of-PHY-mode-EEE.patch b/target/linux/generic/backport-6.18/787-v6.19-net-phy-RTL8211FVD-Restore-disabling-of-PHY-mode-EEE.patch
deleted file mode 100644 (file)
index 37290c4..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From 4f0638b12451112de4138689fa679315c8d388dc Mon Sep 17 00:00:00 2001
-From: Ivan Galkin <ivan.galkin@axis.com>
-Date: Tue, 2 Dec 2025 10:07:42 +0100
-Subject: net: phy: RTL8211FVD: Restore disabling of PHY-mode EEE
-
-When support for RTL8211F(D)(I)-VD-CG was introduced in commit
-bb726b753f75 ("net: phy: realtek: add support for RTL8211F(D)(I)-VD-CG")
-the implementation assumed that this PHY model doesn't have the
-control register PHYCR2 (Page 0xa43 Address 0x19). This
-assumption was based on the differences in CLKOUT configurations
-between RTL8211FVD and the remaining RTL8211F PHYs. In the latter
-commit 2c67301584f2
-("net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not present")
-this assumption was expanded to the PHY-mode EEE.
-
-I performed tests on RTL8211FI-VD-CG and confirmed that disabling
-PHY-mode EEE works correctly and is uniform with other PHYs
-supported by the driver. To validate the correctness,
-I contacted Realtek support. Realtek confirmed that PHY-mode EEE on
-RTL8211F(D)(I)-VD-CG is configured via Page 0xa43 Address 0x19 bit 5.
-
-Moreover, Realtek informed me that the most recent datasheet
-for RTL8211F(D)(I)-VD-CG v1.1 is incomplete and the naming of
-control registers is partly inconsistent. The errata I
-received from Realtek corrects the naming as follows:
-
-| Register                | Datasheet v1.1 | Errata |
-|-------------------------|----------------|--------|
-| Page 0xa44 Address 0x11 | PHYCR2         | PHYCR3 |
-| Page 0xa43 Address 0x19 | N/A            | PHYCR2 |
-
-This information confirms that the supposedly missing control register,
-PHYCR2, exists in the RTL8211F(D)(I)-VD-CG under the same address and
-the same name. It controls widely the same configs as other PHYs from
-the RTL8211F series (e.g. PHY-mode EEE). Clock out configuration is an
-exception.
-
-Given all this information, restore disabling of the PHY-mode EEE.
-
-Fixes: 2c67301584f2 ("net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not present")
-Signed-off-by: Ivan Galkin <ivan.galkin@axis.com>
-Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Link: https://patch.msgid.link/20251202-phy_eee-v1-1-fe0bf6ab3df0@axis.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/phy/realtek/realtek_main.c | 4 ----
- 1 file changed, 4 deletions(-)
-
---- a/drivers/net/phy/realtek/realtek_main.c
-+++ b/drivers/net/phy/realtek/realtek_main.c
-@@ -691,10 +691,6 @@ static int rtl8211f_config_aldps(struct
- static int rtl8211f_config_phy_eee(struct phy_device *phydev)
- {
--      /* RTL8211FVD has no PHYCR2 register */
--      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
--              return 0;
--
-       /* Disable PHY-mode EEE so LPI is passed to the MAC */
-       return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
-                               RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
diff --git a/target/linux/generic/backport-6.18/800-v6.13-hwmon-Add-static-visibility-member-to-struct-hwmon_o.patch b/target/linux/generic/backport-6.18/800-v6.13-hwmon-Add-static-visibility-member-to-struct-hwmon_o.patch
deleted file mode 100644 (file)
index 0c9f920..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-From 79bc0af904db647979c735563299c9b0d820e432 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 10 Oct 2024 21:35:42 +0200
-Subject: [PATCH] hwmon: Add static visibility member to struct hwmon_ops
-
-Several drivers return the same static value in their is_visible
-callback, what results in code duplication. Therefore add an option
-for drivers to specify a static visibility directly.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Message-ID: <89690b81-2c73-47ae-9ae9-45c77b45ca0c@gmail.com>
-groeck: Renamed hwmon_ops_is_visible -> hwmon_is_visible
-Signed-off-by: Guenter Roeck <linux@roeck-us.net>
----
- drivers/hwmon/hwmon.c | 19 +++++++++++++++----
- include/linux/hwmon.h |  5 ++++-
- 2 files changed, 19 insertions(+), 5 deletions(-)
-
---- a/drivers/hwmon/hwmon.c
-+++ b/drivers/hwmon/hwmon.c
-@@ -145,6 +145,17 @@ static const struct class hwmon_class =
- static DEFINE_IDA(hwmon_ida);
-+static umode_t hwmon_is_visible(const struct hwmon_ops *ops,
-+                              const void *drvdata,
-+                              enum hwmon_sensor_types type,
-+                              u32 attr, int channel)
-+{
-+      if (ops->visible)
-+              return ops->visible;
-+
-+      return ops->is_visible(drvdata, type, attr, channel);
-+}
-+
- /* Thermal zone handling */
- /*
-@@ -267,8 +278,8 @@ static int hwmon_thermal_register_sensor
-                       int err;
-                       if (!(info[i]->config[j] & HWMON_T_INPUT) ||
--                          !chip->ops->is_visible(drvdata, hwmon_temp,
--                                                 hwmon_temp_input, j))
-+                          !hwmon_is_visible(chip->ops, drvdata, hwmon_temp,
-+                                            hwmon_temp_input, j))
-                               continue;
-                       err = hwmon_thermal_add_sensor(dev, j);
-@@ -506,7 +517,7 @@ static struct attribute *hwmon_genattr(c
-       const char *name;
-       bool is_string = is_string_attr(type, attr);
--      mode = ops->is_visible(drvdata, type, attr, index);
-+      mode = hwmon_is_visible(ops, drvdata, type, attr, index);
-       if (!mode)
-               return ERR_PTR(-ENOENT);
-@@ -1033,7 +1044,7 @@ hwmon_device_register_with_info(struct d
-       if (!dev || !name || !chip)
-               return ERR_PTR(-EINVAL);
--      if (!chip->ops || !chip->ops->is_visible || !chip->info)
-+      if (!chip->ops || !(chip->ops->visible || chip->ops->is_visible) || !chip->info)
-               return ERR_PTR(-EINVAL);
-       return __hwmon_device_register(dev, name, drvdata, chip, extra_groups);
---- a/include/linux/hwmon.h
-+++ b/include/linux/hwmon.h
-@@ -368,7 +368,9 @@ enum hwmon_intrusion_attributes {
- /**
-  * struct hwmon_ops - hwmon device operations
-- * @is_visible: Callback to return attribute visibility. Mandatory.
-+ * @visible:  Static visibility. If non-zero, 'is_visible' is ignored.
-+ * @is_visible: Callback to return attribute visibility. Mandatory unless
-+ *            'visible' is non-zero.
-  *            Parameters are:
-  *            @const void *drvdata:
-  *                    Pointer to driver-private data structure passed
-@@ -412,6 +414,7 @@ enum hwmon_intrusion_attributes {
-  *            The function returns 0 on success or a negative error number.
-  */
- struct hwmon_ops {
-+      umode_t visible;
-       umode_t (*is_visible)(const void *drvdata, enum hwmon_sensor_types type,
-                             u32 attr, int channel);
-       int (*read)(struct device *dev, enum hwmon_sensor_types type,
diff --git a/target/linux/generic/backport-6.18/801-01-v6.13-dt-bindings-clocks-add-binding-for-gated-fixed-clock.patch b/target/linux/generic/backport-6.18/801-01-v6.13-dt-bindings-clocks-add-binding-for-gated-fixed-clock.patch
deleted file mode 100644 (file)
index f5ab8a0..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-From a4a7cbe36623ffaabbae413c0eacf40d033db71f Mon Sep 17 00:00:00 2001
-From: Heiko Stuebner <heiko@sntech.de>
-Date: Fri, 6 Sep 2024 10:25:07 +0200
-Subject: dt-bindings: clocks: add binding for gated-fixed-clocks
-
-In contrast to fixed clocks that are described as ungateable, boards
-sometimes use additional oscillators for things like PCIe reference
-clocks, that need actual supplies to get enabled and enable-gpios to be
-toggled for them to work.
-
-This adds a binding for such oscillators that are not configurable
-themself, but need to handle supplies for them to work.
-
-In schematics they often can be seen as
-
-         ----------------
-Enable - | 100MHz,3.3V, | - VDD
-         |    3225      |
-   GND - |              | - OUT
-         ----------------
-
-or similar. The enable pin might be separate but can also just be tied
-to the vdd supply, hence it is optional in the binding.
-
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
-Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Link: https://lore.kernel.org/r/20240906082511.2963890-2-heiko@sntech.de
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/gated-fixed-clock.yaml
-@@ -0,0 +1,49 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/gated-fixed-clock.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Gated Fixed clock
-+
-+maintainers:
-+  - Heiko Stuebner <heiko@sntech.de>
-+
-+properties:
-+  compatible:
-+    const: gated-fixed-clock
-+
-+  "#clock-cells":
-+    const: 0
-+
-+  clock-frequency: true
-+
-+  clock-output-names:
-+    maxItems: 1
-+
-+  enable-gpios:
-+    description:
-+      Contains a single GPIO specifier for the GPIO that enables and disables
-+      the oscillator.
-+    maxItems: 1
-+
-+  vdd-supply:
-+    description: handle of the regulator that provides the supply voltage
-+
-+required:
-+  - compatible
-+  - "#clock-cells"
-+  - clock-frequency
-+  - vdd-supply
-+
-+additionalProperties: false
-+
-+examples:
-+  - |
-+    clock-1000000000 {
-+      compatible = "gated-fixed-clock";
-+      #clock-cells = <0>;
-+      clock-frequency = <1000000000>;
-+      vdd-supply = <&reg_vdd>;
-+    };
-+...
diff --git a/target/linux/generic/backport-6.18/801-02-v6.13-clk-clk-gpio-update-documentation-for-gpio-gate-cloc.patch b/target/linux/generic/backport-6.18/801-02-v6.13-clk-clk-gpio-update-documentation-for-gpio-gate-cloc.patch
deleted file mode 100644 (file)
index 99e41a1..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From 6cb137c7e99f8307f1f0fcccb1896f2d3b0651d3 Mon Sep 17 00:00:00 2001
-From: Heiko Stuebner <heiko@sntech.de>
-Date: Fri, 6 Sep 2024 10:25:08 +0200
-Subject: clk: clk-gpio: update documentation for gpio-gate clock
-
-The main documentation block seems to be from a time before the driver
-handled sleeping and non-sleeping gpios and with that change it seems
-updating the doc was overlooked. So do that now.
-
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
-Link: https://lore.kernel.org/r/20240906082511.2963890-3-heiko@sntech.de
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-
---- a/drivers/clk/clk-gpio.c
-+++ b/drivers/clk/clk-gpio.c
-@@ -22,8 +22,9 @@
-  * DOC: basic gpio gated clock which can be enabled and disabled
-  *      with gpio output
-  * Traits of this clock:
-- * prepare - clk_(un)prepare only ensures parent is (un)prepared
-- * enable - clk_enable and clk_disable are functional & control gpio
-+ * prepare - clk_(un)prepare are functional and control a gpio that can sleep
-+ * enable - clk_enable and clk_disable are functional & control
-+ *          non-sleeping gpio
-  * rate - inherits rate from parent.  No clk_set_rate support
-  * parent - fixed parent.  No clk_set_parent support
-  */
diff --git a/target/linux/generic/backport-6.18/801-03-v6.13-clk-clk-gpio-use-dev_err_probe-for-gpio-get-failure.patch b/target/linux/generic/backport-6.18/801-03-v6.13-clk-clk-gpio-use-dev_err_probe-for-gpio-get-failure.patch
deleted file mode 100644 (file)
index 1982bb3..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-From 36abe81d9c3fa200a57ef2363e93a2991e387e19 Mon Sep 17 00:00:00 2001
-From: Heiko Stuebner <heiko@sntech.de>
-Date: Fri, 6 Sep 2024 10:25:09 +0200
-Subject: clk: clk-gpio: use dev_err_probe for gpio-get failure
-
-This is a real driver and dev_err_probe will hide the distinction between
-EPROBE_DEFER and other errors automatically, so there is no need to
-open-code this.
-
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
-Link: https://lore.kernel.org/r/20240906082511.2963890-4-heiko@sntech.de
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-
---- a/drivers/clk/clk-gpio.c
-+++ b/drivers/clk/clk-gpio.c
-@@ -200,7 +200,6 @@ static int gpio_clk_driver_probe(struct
-       struct gpio_desc *gpiod;
-       struct clk_hw *hw;
-       bool is_mux;
--      int ret;
-       is_mux = of_device_is_compatible(node, "gpio-mux-clock");
-@@ -212,17 +211,9 @@ static int gpio_clk_driver_probe(struct
-       gpio_name = is_mux ? "select" : "enable";
-       gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW);
--      if (IS_ERR(gpiod)) {
--              ret = PTR_ERR(gpiod);
--              if (ret == -EPROBE_DEFER)
--                      pr_debug("%pOFn: %s: GPIOs not yet available, retry later\n",
--                                      node, __func__);
--              else
--                      pr_err("%pOFn: %s: Can't get '%s' named GPIO property\n",
--                                      node, __func__,
--                                      gpio_name);
--              return ret;
--      }
-+      if (IS_ERR(gpiod))
-+              return dev_err_probe(dev, PTR_ERR(gpiod),
-+                                   "Can't get '%s' named GPIO property\n", gpio_name);
-       if (is_mux)
-               hw = clk_hw_register_gpio_mux(dev, gpiod);
diff --git a/target/linux/generic/backport-6.18/801-04-v6.13-clk-clk-gpio-add-driver-for-gated-fixed-clocks.patch b/target/linux/generic/backport-6.18/801-04-v6.13-clk-clk-gpio-add-driver-for-gated-fixed-clocks.patch
deleted file mode 100644 (file)
index 44da746..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-From 4940071d962827467f7297be3b874c96186ca0b7 Mon Sep 17 00:00:00 2001
-From: Heiko Stuebner <heiko@sntech.de>
-Date: Fri, 6 Sep 2024 10:25:10 +0200
-Subject: clk: clk-gpio: add driver for gated-fixed-clocks
-
-In contrast to fixed clocks that are described as ungateable, boards
-sometimes use additional oscillators for things like PCIe reference
-clocks, that need actual supplies to get enabled and enable-gpios to be
-toggled for them to work.
-
-This adds a driver for those generic gated-fixed-clocks
-that can show up in schematics looking like
-
-         ----------------
-Enable - | 100MHz,3.3V, | - VDD
-         |    3225      |
-   GND - |              | - OUT
-         ----------------
-
-The new driver gets grouped together with the existing gpio-gate and
-gpio-mux, as it for one re-uses a lot of the gpio-gate functions
-and also in its core it's just another gpio-controlled clock, just
-with a fixed rate and a regulator-supply added in.
-
-The regulator-API provides function stubs for the !CONFIG_REGULATOR case,
-so no special handling is necessary.
-
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
-Link: https://lore.kernel.org/r/20240906082511.2963890-5-heiko@sntech.de
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-
---- a/drivers/clk/clk-gpio.c
-+++ b/drivers/clk/clk-gpio.c
-@@ -17,6 +17,7 @@
- #include <linux/device.h>
- #include <linux/of.h>
- #include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
- /**
-  * DOC: basic gpio gated clock which can be enabled and disabled
-@@ -239,3 +240,187 @@ static struct platform_driver gpio_clk_d
-       },
- };
- builtin_platform_driver(gpio_clk_driver);
-+
-+/**
-+ * DOC: gated fixed clock, controlled with a gpio output and a regulator
-+ * Traits of this clock:
-+ * prepare - clk_prepare and clk_unprepare are function & control regulator
-+ *           optionally a gpio that can sleep
-+ * enable - clk_enable and clk_disable are functional & control gpio
-+ * rate - rate is fixed and set on clock registration
-+ * parent - fixed clock is a root clock and has no parent
-+ */
-+
-+/**
-+ * struct clk_gated_fixed - Gateable fixed rate clock
-+ * @clk_gpio: instance of clk_gpio for gate-gpio
-+ * @supply:   supply regulator
-+ * @rate:     fixed rate
-+ */
-+struct clk_gated_fixed {
-+      struct clk_gpio clk_gpio;
-+      struct regulator *supply;
-+      unsigned long rate;
-+};
-+
-+#define to_clk_gated_fixed(_clk_gpio) container_of(_clk_gpio, struct clk_gated_fixed, clk_gpio)
-+
-+static unsigned long clk_gated_fixed_recalc_rate(struct clk_hw *hw,
-+                                               unsigned long parent_rate)
-+{
-+      return to_clk_gated_fixed(to_clk_gpio(hw))->rate;
-+}
-+
-+static int clk_gated_fixed_prepare(struct clk_hw *hw)
-+{
-+      struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw));
-+
-+      if (!clk->supply)
-+              return 0;
-+
-+      return regulator_enable(clk->supply);
-+}
-+
-+static void clk_gated_fixed_unprepare(struct clk_hw *hw)
-+{
-+      struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw));
-+
-+      if (!clk->supply)
-+              return;
-+
-+      regulator_disable(clk->supply);
-+}
-+
-+static int clk_gated_fixed_is_prepared(struct clk_hw *hw)
-+{
-+      struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw));
-+
-+      if (!clk->supply)
-+              return true;
-+
-+      return regulator_is_enabled(clk->supply);
-+}
-+
-+/*
-+ * Fixed gated clock with non-sleeping gpio.
-+ *
-+ * Prepare operation turns on the supply regulator
-+ * and the enable operation switches the enable-gpio.
-+ */
-+static const struct clk_ops clk_gated_fixed_ops = {
-+      .prepare = clk_gated_fixed_prepare,
-+      .unprepare = clk_gated_fixed_unprepare,
-+      .is_prepared = clk_gated_fixed_is_prepared,
-+      .enable = clk_gpio_gate_enable,
-+      .disable = clk_gpio_gate_disable,
-+      .is_enabled = clk_gpio_gate_is_enabled,
-+      .recalc_rate = clk_gated_fixed_recalc_rate,
-+};
-+
-+static int clk_sleeping_gated_fixed_prepare(struct clk_hw *hw)
-+{
-+      int ret;
-+
-+      ret = clk_gated_fixed_prepare(hw);
-+      if (ret)
-+              return ret;
-+
-+      ret = clk_sleeping_gpio_gate_prepare(hw);
-+      if (ret)
-+              clk_gated_fixed_unprepare(hw);
-+
-+      return ret;
-+}
-+
-+static void clk_sleeping_gated_fixed_unprepare(struct clk_hw *hw)
-+{
-+      clk_gated_fixed_unprepare(hw);
-+      clk_sleeping_gpio_gate_unprepare(hw);
-+}
-+
-+/*
-+ * Fixed gated clock with non-sleeping gpio.
-+ *
-+ * Enabling the supply regulator and switching the enable-gpio happens
-+ * both in the prepare step.
-+ * is_prepared only needs to check the gpio state, as toggling the
-+ * gpio is the last step when preparing.
-+ */
-+static const struct clk_ops clk_sleeping_gated_fixed_ops = {
-+      .prepare = clk_sleeping_gated_fixed_prepare,
-+      .unprepare = clk_sleeping_gated_fixed_unprepare,
-+      .is_prepared = clk_sleeping_gpio_gate_is_prepared,
-+      .recalc_rate = clk_gated_fixed_recalc_rate,
-+};
-+
-+static int clk_gated_fixed_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      struct clk_gated_fixed *clk;
-+      const struct clk_ops *ops;
-+      const char *clk_name;
-+      u32 rate;
-+      int ret;
-+
-+      clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
-+      if (!clk)
-+              return -ENOMEM;
-+
-+      ret = device_property_read_u32(dev, "clock-frequency", &rate);
-+      if (ret)
-+              return dev_err_probe(dev, ret, "Failed to get clock-frequency\n");
-+      clk->rate = rate;
-+
-+      ret = device_property_read_string(dev, "clock-output-names", &clk_name);
-+      if (ret)
-+              clk_name = fwnode_get_name(dev->fwnode);
-+
-+      clk->supply = devm_regulator_get_optional(dev, "vdd");
-+      if (IS_ERR(clk->supply)) {
-+              if (PTR_ERR(clk->supply) != -ENODEV)
-+                      return dev_err_probe(dev, PTR_ERR(clk->supply),
-+                                           "Failed to get regulator\n");
-+              clk->supply = NULL;
-+      }
-+
-+      clk->clk_gpio.gpiod = devm_gpiod_get_optional(dev, "enable",
-+                                                    GPIOD_OUT_LOW);
-+      if (IS_ERR(clk->clk_gpio.gpiod))
-+              return dev_err_probe(dev, PTR_ERR(clk->clk_gpio.gpiod),
-+                                   "Failed to get gpio\n");
-+
-+      if (gpiod_cansleep(clk->clk_gpio.gpiod))
-+              ops = &clk_sleeping_gated_fixed_ops;
-+      else
-+              ops = &clk_gated_fixed_ops;
-+
-+      clk->clk_gpio.hw.init = CLK_HW_INIT_NO_PARENT(clk_name, ops, 0);
-+
-+      /* register the clock */
-+      ret = devm_clk_hw_register(dev, &clk->clk_gpio.hw);
-+      if (ret)
-+              return dev_err_probe(dev, ret,
-+                                   "Failed to register clock\n");
-+
-+      ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
-+                                        &clk->clk_gpio.hw);
-+      if (ret)
-+              return dev_err_probe(dev, ret,
-+                                   "Failed to register clock provider\n");
-+
-+      return 0;
-+}
-+
-+static const struct of_device_id gated_fixed_clk_match_table[] = {
-+      { .compatible = "gated-fixed-clock" },
-+      { /* sentinel */ }
-+};
-+
-+static struct platform_driver gated_fixed_clk_driver = {
-+      .probe          = clk_gated_fixed_probe,
-+      .driver         = {
-+              .name   = "gated-fixed-clk",
-+              .of_match_table = gated_fixed_clk_match_table,
-+      },
-+};
-+builtin_platform_driver(gated_fixed_clk_driver);
diff --git a/target/linux/generic/backport-6.18/810-v6.14-gpio-regmap-Use-generic-request-free-ops.patch b/target/linux/generic/backport-6.18/810-v6.14-gpio-regmap-Use-generic-request-free-ops.patch
deleted file mode 100644 (file)
index d696acf..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From b0fa00fe38f673c986633c11087274deeb7ce7b0 Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Tue, 7 Jan 2025 21:16:20 +0100
-Subject: [PATCH] gpio: regmap: Use generic request/free ops
-
-Set the gpiochip request and free ops to the generic implementations.
-This way a user can provide a gpio-ranges property defined for a pinmux,
-easing muxing of gpio functions. Provided that the pin controller
-implementents the pinmux op .gpio_request_enable(), pins will
-automatically be muxed to their GPIO function when requested.
-
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-Acked-by: Michael Walle <mwalle@kernel.org>
-Link: https://lore.kernel.org/r/20250107201621.12467-1-sander@svanheule.net
-Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
----
- drivers/gpio/gpio-regmap.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/gpio/gpio-regmap.c
-+++ b/drivers/gpio/gpio-regmap.c
-@@ -276,6 +276,8 @@ struct gpio_regmap *gpio_regmap_register
-       chip->label = config->label ?: dev_name(config->parent);
-       chip->can_sleep = regmap_might_sleep(config->regmap);
-+      chip->request = gpiochip_generic_request;
-+      chip->free = gpiochip_generic_free;
-       chip->get = gpio_regmap_get;
-       if (gpio->reg_set_base && gpio->reg_clr_base)
-               chip->set = gpio_regmap_set_with_clear;
diff --git a/target/linux/generic/backport-6.18/813-v6.16-pinctrl-aw9523-fix-can_sleep-flag-for-GPIO-chip.patch b/target/linux/generic/backport-6.18/813-v6.16-pinctrl-aw9523-fix-can_sleep-flag-for-GPIO-chip.patch
deleted file mode 100644 (file)
index 97b3921..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From 5285b5ed04ab6ad40f7b654eefbccd6ae8cbf415 Mon Sep 17 00:00:00 2001
-From: Milan Krstic <milan.krstic@gmail.com>
-Date: Thu, 3 Jul 2025 14:30:39 +0000
-Subject: [PATCH] pinctrl: aw9523: fix can_sleep flag for GPIO chip
-
-The GPIO expander is connected via I2C, thus the can_sleep flag has to
-be set to true. This fixes spurious "scheduling while atomic" bugs
-in the kernel ringbuffer.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: Milan Krstic <milan.krstic@gmail.com>
-Link: https://lore.kernel.org/20250703143039.5809-1-milan.krstic@gmail.com
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-aw9523.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-aw9523.c
-+++ b/drivers/pinctrl/pinctrl-aw9523.c
-@@ -784,7 +784,7 @@ static int aw9523_init_gpiochip(struct a
-       gc->set_config = gpiochip_generic_config;
-       gc->parent = dev;
-       gc->owner = THIS_MODULE;
--      gc->can_sleep = false;
-+      gc->can_sleep = true;
-       return 0;
- }
diff --git a/target/linux/generic/backport-6.18/820-v6.15-power-supply-sysfs-remove-duplicate-nul-termination-to-fix-build-with-GCC15.patch b/target/linux/generic/backport-6.18/820-v6.15-power-supply-sysfs-remove-duplicate-nul-termination-to-fix-build-with-GCC15.patch
deleted file mode 100644 (file)
index 48f9c1c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From 77f5bb150132bbbcd6bc37ffdc80c9e140e373a4 Mon Sep 17 00:00:00 2001
-From: Kees Cook <kees@kernel.org>
-Date: Wed, 16 Apr 2025 15:27:41 -0700
-Subject: [PATCH] power: supply: sysfs: Remove duplicate NUL termination
-
-GCC 15's new -Wunterminated-string-initialization notices that one of
-the sysfs attr strings would lack the implicit trailing NUL byte during
-initialization:
-
-drivers/power/supply/power_supply_sysfs.c:183:57: warning: initializer-string for array of 'char' truncates NUL terminator but destination lacks 'nonstring' attribute (32 chars into 31 available) [-Wunterminated-string-initialization]
-  183 |         POWER_SUPPLY_ATTR(CHARGE_CONTROL_START_THRESHOLD),
-      |                                                         ^
-drivers/power/supply/power_supply_sysfs.c:36:23: note: in definition of macro '_POWER_SUPPLY_ATTR'
-   36 |         .attr_name = #_name "\0",               \
-      |                       ^~~~~
-drivers/power/supply/power_supply_sysfs.c:183:9: note: in expansion of macro 'POWER_SUPPLY_ATTR'
-  183 |         POWER_SUPPLY_ATTR(CHARGE_CONTROL_START_THRESHOLD),
-      |         ^~~~~~~~~~~~~~~~~
-
-However, the macro used was explicitly adding a trailing NUL byte (which
-is not needed). Remove this to avoid the GCC warning. No binary
-differences are seen after this change (there was always run for a NUL
-byte, it's just that the _second_ NUL byte was getting truncated).
-
-Signed-off-by: Kees Cook <kees@kernel.org>
-Link: https://lore.kernel.org/r/20250416222740.work.569-kees@kernel.org
-Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-
---- a/drivers/power/supply/power_supply_sysfs.c
-+++ b/drivers/power/supply/power_supply_sysfs.c
-@@ -33,7 +33,7 @@ struct power_supply_attr {
- [POWER_SUPPLY_PROP_ ## _name] =                       \
- {                                             \
-       .prop_name = #_name,                    \
--      .attr_name = #_name "\0",               \
-+      .attr_name = #_name,                    \
-       .text_values = _text,                   \
-       .text_values_len = _len,                \
- }
diff --git a/target/linux/generic/backport-6.18/891-v6.14-dt-bindings-leds-Add-LED1202-LED-Controller.patch b/target/linux/generic/backport-6.18/891-v6.14-dt-bindings-leds-Add-LED1202-LED-Controller.patch
deleted file mode 100644 (file)
index 9901d13..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-From 599b92fd0efa8b7c43e7f58c9dd0f7951f7cbf09 Mon Sep 17 00:00:00 2001
-From: Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
-Date: Wed, 18 Dec 2024 18:33:58 +0000
-Subject: dt-bindings: leds: Add LED1202 LED Controller
-
-The LED1202 is a 12-channel low quiescent current LED driver with:
-  * Supply range from 2.6 V to 5 V
-  * 20 mA current capability per channel
-  * 1.8 V compatible I2C control interface
-  * 8-bit analog dimming individual control
-  * 12-bit local PWM resolution
-  * 8 programmable patterns
-
-If the led node is present in the controller then the channel is
-set to active.
-
-Signed-off-by: Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20241218183401.41687-3-vicentiu.galanopulo@remote-tech.co.uk
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- .../devicetree/bindings/leds/st,led1202.yaml  | 132 ++++++++++++++++++
- 1 file changed, 132 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/leds/st,led1202.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/leds/st,led1202.yaml
-@@ -0,0 +1,132 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/leds/st,led1202.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: ST LED1202 LED controllers
-+
-+maintainers:
-+  - Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
-+
-+description: |
-+  The LED1202 is a 12-channel low quiescent current LED controller
-+  programmable via I2C; The output current can be adjusted separately
-+  for each channel by 8-bit analog and 12-bit digital dimming control.
-+  Datasheet available at
-+  https://www.st.com/en/power-management/led1202.html
-+
-+properties:
-+  compatible:
-+    const: st,led1202
-+
-+  reg:
-+    maxItems: 1
-+
-+  "#address-cells":
-+    const: 1
-+
-+  "#size-cells":
-+    const: 0
-+
-+patternProperties:
-+  "^led@[0-9a-f]$":
-+    type: object
-+    $ref: common.yaml#
-+    unevaluatedProperties: false
-+
-+    properties:
-+      reg:
-+        minimum: 0
-+        maximum: 11
-+
-+    required:
-+      - reg
-+
-+required:
-+  - compatible
-+  - reg
-+  - "#address-cells"
-+  - "#size-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+  - |
-+    #include <dt-bindings/leds/common.h>
-+
-+    i2c {
-+        #address-cells = <1>;
-+        #size-cells = <0>;
-+
-+        led-controller@58 {
-+            compatible = "st,led1202";
-+            reg = <0x58>;
-+            #address-cells = <1>;
-+            #size-cells = <0>;
-+
-+            led@0 {
-+                reg = <0x0>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_RED>;
-+                function-enumerator = <1>;
-+            };
-+
-+            led@1 {
-+                reg = <0x1>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_GREEN>;
-+                function-enumerator = <2>;
-+            };
-+
-+            led@2 {
-+                reg = <0x2>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_BLUE>;
-+                function-enumerator = <3>;
-+            };
-+
-+            led@3 {
-+                reg = <0x3>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_RED>;
-+                function-enumerator = <4>;
-+            };
-+
-+            led@4 {
-+                reg = <0x4>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_GREEN>;
-+                function-enumerator = <5>;
-+            };
-+
-+            led@5 {
-+                reg = <0x5>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_BLUE>;
-+                function-enumerator = <6>;
-+            };
-+
-+            led@6 {
-+                reg = <0x6>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_RED>;
-+                function-enumerator = <7>;
-+            };
-+
-+            led@7 {
-+                reg = <0x7>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_GREEN>;
-+                function-enumerator = <8>;
-+            };
-+
-+            led@8 {
-+                reg = <0x8>;
-+                function = LED_FUNCTION_STATUS;
-+                color = <LED_COLOR_ID_BLUE>;
-+                function-enumerator = <9>;
-+            };
-+        };
-+    };
-+...
diff --git a/target/linux/generic/backport-6.18/892-v6.14-leds-Add-LED1202-I2C-driver.patch b/target/linux/generic/backport-6.18/892-v6.14-leds-Add-LED1202-I2C-driver.patch
deleted file mode 100644 (file)
index ee2ea07..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-From 939757aafeb9c266dda37657ee5f7a73ffd35ae2 Mon Sep 17 00:00:00 2001
-From: Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
-Date: Wed, 18 Dec 2024 18:33:59 +0000
-Subject: leds: Add LED1202 I2C driver
-
-The output current can be adjusted separately for each channel by 8-bit
-analog (current sink input) and 12-bit digital (PWM) dimming control. The
-LED1202 implements 12 low-side current generators with independent dimming
-control.
-Internal volatile memory allows the user to store up to 8 different patterns,
-each pattern is a particular output configuration in terms of PWM
-duty-cycle (on 4096 steps). Analog dimming (on 256 steps) is per channel but
-common to all patterns. Each device tree LED node will have a corresponding
-entry in /sys/class/leds with the label name. The brightness property
-corresponds to the per channel analog dimming, while the patterns[1-8] to the
-PWM dimming control.
-
-Signed-off-by: Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
-Link: https://lore.kernel.org/r/20241218183401.41687-4-vicentiu.galanopulo@remote-tech.co.uk
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/Kconfig       |  10 +
- drivers/leds/Makefile      |   1 +
- drivers/leds/leds-st1202.c | 416 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 427 insertions(+)
- create mode 100644 drivers/leds/leds-st1202.c
-
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -931,6 +931,16 @@ config LEDS_LM36274
-         Say Y to enable the LM36274 LED driver for TI LMU devices.
-         This supports the LED device LM36274.
-+config LEDS_ST1202
-+      tristate "LED Support for STMicroelectronics LED1202 I2C chips"
-+      depends on LEDS_CLASS
-+      depends on I2C
-+      depends on OF
-+      select LEDS_TRIGGERS
-+      help
-+        Say Y to enable support for LEDs connected to LED1202
-+        LED driver chips accessed via the I2C bus.
-+
- config LEDS_TPS6105X
-       tristate "LED support for TI TPS6105X"
-       depends on LEDS_CLASS
---- a/drivers/leds/Makefile
-+++ b/drivers/leds/Makefile
-@@ -81,6 +81,7 @@ obj-$(CONFIG_LEDS_POWERNV)           += leds-powe
- obj-$(CONFIG_LEDS_PWM)                        += leds-pwm.o
- obj-$(CONFIG_LEDS_REGULATOR)          += leds-regulator.o
- obj-$(CONFIG_LEDS_SC27XX_BLTC)                += leds-sc27xx-bltc.o
-+obj-$(CONFIG_LEDS_ST1202)             += leds-st1202.o
- obj-$(CONFIG_LEDS_SUN50I_A100)                += leds-sun50i-a100.o
- obj-$(CONFIG_LEDS_SUNFIRE)            += leds-sunfire.o
- obj-$(CONFIG_LEDS_SYSCON)             += leds-syscon.o
---- /dev/null
-+++ b/drivers/leds/leds-st1202.c
-@@ -0,0 +1,416 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * LED driver for STMicroelectronics LED1202 chip
-+ *
-+ * Copyright (C) 2024 Remote-Tech Ltd. UK
-+ */
-+
-+#include <linux/cleanup.h>
-+#include <linux/ctype.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/gpio.h>
-+#include <linux/i2c.h>
-+#include <linux/leds.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+
-+#define ST1202_CHAN_DISABLE_ALL            0x00
-+#define ST1202_CHAN_ENABLE_HIGH            0x03
-+#define ST1202_CHAN_ENABLE_LOW             0x02
-+#define ST1202_CONFIG_REG                  0x04
-+/* PATS: Pattern sequence feature enable */
-+#define ST1202_CONFIG_REG_PATS             BIT(7)
-+/* PATSR: Pattern sequence runs (self-clear when sequence is finished) */
-+#define ST1202_CONFIG_REG_PATSR            BIT(6)
-+#define ST1202_CONFIG_REG_SHFT             BIT(3)
-+#define ST1202_DEV_ENABLE                  0x01
-+#define ST1202_DEV_ENABLE_ON               BIT(0)
-+#define ST1202_DEV_ENABLE_RESET            BIT(7)
-+#define ST1202_DEVICE_ID                   0x00
-+#define ST1202_ILED_REG0                   0x09
-+#define ST1202_MAX_LEDS                    12
-+#define ST1202_MAX_PATTERNS                8
-+#define ST1202_MILLIS_PATTERN_DUR_MAX      5660
-+#define ST1202_MILLIS_PATTERN_DUR_MIN      22
-+#define ST1202_PATTERN_DUR                 0x16
-+#define ST1202_PATTERN_PWM                 0x1E
-+#define ST1202_PATTERN_REP                 0x15
-+
-+struct st1202_led {
-+      struct fwnode_handle *fwnode;
-+      struct led_classdev led_cdev;
-+      struct st1202_chip *chip;
-+      bool is_active;
-+      int led_num;
-+};
-+
-+struct st1202_chip {
-+      struct i2c_client *client;
-+      struct mutex lock;
-+      struct st1202_led leds[ST1202_MAX_LEDS];
-+};
-+
-+static struct st1202_led *cdev_to_st1202_led(struct led_classdev *cdev)
-+{
-+      return container_of(cdev, struct st1202_led, led_cdev);
-+}
-+
-+static int st1202_read_reg(struct st1202_chip *chip, int reg, uint8_t *val)
-+{
-+      struct device *dev = &chip->client->dev;
-+      int ret;
-+
-+      ret = i2c_smbus_read_byte_data(chip->client, reg);
-+      if (ret < 0) {
-+              dev_err(dev, "Failed to read register [0x%x]: %d\n", reg, ret);
-+              return ret;
-+      }
-+
-+      *val = (uint8_t)ret;
-+      return 0;
-+}
-+
-+static int st1202_write_reg(struct st1202_chip *chip, int reg, uint8_t val)
-+{
-+      struct device *dev = &chip->client->dev;
-+      int ret;
-+
-+      ret = i2c_smbus_write_byte_data(chip->client, reg, val);
-+      if (ret != 0)
-+              dev_err(dev, "Failed to write %d to register [0x%x]: %d\n", val, reg, ret);
-+
-+      return ret;
-+}
-+
-+static uint8_t st1202_prescalar_to_miliseconds(unsigned int value)
-+{
-+      return value / ST1202_MILLIS_PATTERN_DUR_MIN - 1;
-+}
-+
-+static int st1202_pwm_pattern_write(struct st1202_chip *chip, int led_num,
-+                              int pattern, unsigned int value)
-+{
-+      u8 value_l, value_h;
-+      int ret;
-+
-+      value_l = (u8)value;
-+      value_h = (u8)(value >> 8);
-+
-+      /*
-+       *  Datasheet: Register address low = 1Eh + 2*(xh) + 18h*(yh),
-+       *  where x is the channel number (led number) in hexadecimal (x = 00h .. 0Bh)
-+       *  and y is the pattern number in hexadecimal (y = 00h .. 07h)
-+       */
-+      ret = st1202_write_reg(chip, (ST1202_PATTERN_PWM + (led_num * 2) + 0x18 * pattern),
-+                              value_l);
-+      if (ret != 0)
-+              return ret;
-+
-+      /*
-+       * Datasheet: Register address high = 1Eh + 01h + 2(xh) +18h*(yh),
-+       * where x is the channel number in hexadecimal (x = 00h .. 0Bh)
-+       * and y is the pattern number in hexadecimal (y = 00h .. 07h)
-+       */
-+      ret = st1202_write_reg(chip, (ST1202_PATTERN_PWM + 0x1 + (led_num * 2) + 0x18 * pattern),
-+                              value_h);
-+      if (ret != 0)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static int st1202_duration_pattern_write(struct st1202_chip *chip, int pattern,
-+                                      unsigned int value)
-+{
-+      return st1202_write_reg(chip, (ST1202_PATTERN_DUR + pattern),
-+                              st1202_prescalar_to_miliseconds(value));
-+}
-+
-+static void st1202_brightness_set(struct led_classdev *led_cdev,
-+                              enum led_brightness value)
-+{
-+      struct st1202_led *led = cdev_to_st1202_led(led_cdev);
-+      struct st1202_chip *chip = led->chip;
-+
-+      guard(mutex)(&chip->lock);
-+
-+      st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
-+}
-+
-+static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
-+{
-+      struct st1202_led *led = cdev_to_st1202_led(led_cdev);
-+      struct st1202_chip *chip = led->chip;
-+      u8 value = 0;
-+
-+      guard(mutex)(&chip->lock);
-+
-+      st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
-+
-+      return value;
-+}
-+
-+static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
-+{
-+      u8 chan_low, chan_high;
-+      int ret;
-+
-+      guard(mutex)(&chip->lock);
-+
-+      if (led_num <= 7) {
-+              ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_LOW, &chan_low);
-+              if (ret < 0)
-+                      return ret;
-+
-+              chan_low = active ? chan_low | BIT(led_num) : chan_low & ~BIT(led_num);
-+
-+              ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_LOW, chan_low);
-+              if (ret < 0)
-+                      return ret;
-+
-+      } else {
-+              ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_HIGH, &chan_high);
-+              if (ret < 0)
-+                      return ret;
-+
-+              chan_high = active ? chan_high | (BIT(led_num) >> 8) :
-+                                      chan_high & ~(BIT(led_num) >> 8);
-+
-+              ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_HIGH, chan_high);
-+              if (ret < 0)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int st1202_led_set(struct led_classdev *ldev, enum led_brightness value)
-+{
-+      struct st1202_led *led = cdev_to_st1202_led(ldev);
-+      struct st1202_chip *chip = led->chip;
-+
-+      return st1202_channel_set(chip, led->led_num, value == LED_OFF ? false : true);
-+}
-+
-+static int st1202_led_pattern_clear(struct led_classdev *ldev)
-+{
-+      struct st1202_led *led = cdev_to_st1202_led(ldev);
-+      struct st1202_chip *chip = led->chip;
-+      int ret;
-+
-+      guard(mutex)(&chip->lock);
-+
-+      for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) {
-+              ret = st1202_pwm_pattern_write(chip, led->led_num, patt, LED_OFF);
-+              if (ret != 0)
-+                      return ret;
-+
-+              ret = st1202_duration_pattern_write(chip, patt, ST1202_MILLIS_PATTERN_DUR_MIN);
-+              if (ret != 0)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int st1202_led_pattern_set(struct led_classdev *ldev,
-+                              struct led_pattern *pattern,
-+                              u32 len, int repeat)
-+{
-+      struct st1202_led *led = cdev_to_st1202_led(ldev);
-+      struct st1202_chip *chip = led->chip;
-+      int ret;
-+
-+      if (len > ST1202_MAX_PATTERNS)
-+              return -EINVAL;
-+
-+      guard(mutex)(&chip->lock);
-+
-+      for (int patt = 0; patt < len; patt++) {
-+              if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN ||
-+                              pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX)
-+                      return -EINVAL;
-+
-+              ret = st1202_pwm_pattern_write(chip, led->led_num, patt, pattern[patt].brightness);
-+              if (ret != 0)
-+                      return ret;
-+
-+              ret = st1202_duration_pattern_write(chip, patt, pattern[patt].delta_t);
-+              if (ret != 0)
-+                      return ret;
-+      }
-+
-+      ret = st1202_write_reg(chip, ST1202_PATTERN_REP, repeat);
-+      if (ret != 0)
-+              return ret;
-+
-+      ret = st1202_write_reg(chip, ST1202_CONFIG_REG, (ST1202_CONFIG_REG_PATSR |
-+                                                      ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_SHFT));
-+      if (ret != 0)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static int st1202_dt_init(struct st1202_chip *chip)
-+{
-+      struct device *dev = &chip->client->dev;
-+      struct st1202_led *led;
-+      int err, reg;
-+
-+      for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
-+              struct led_init_data init_data = {};
-+
-+              err = of_property_read_u32(child, "reg", &reg);
-+              if (err)
-+                      return dev_err_probe(dev, err, "Invalid register\n");
-+
-+              led = &chip->leds[reg];
-+              led->is_active = true;
-+              led->fwnode = of_fwnode_handle(child);
-+
-+              led->led_cdev.max_brightness = U8_MAX;
-+              led->led_cdev.brightness_set_blocking = st1202_led_set;
-+              led->led_cdev.pattern_set = st1202_led_pattern_set;
-+              led->led_cdev.pattern_clear = st1202_led_pattern_clear;
-+              led->led_cdev.default_trigger = "pattern";
-+
-+              init_data.fwnode = led->fwnode;
-+              init_data.devicename = "st1202";
-+              init_data.default_label = ":";
-+
-+              err = devm_led_classdev_register_ext(dev, &led->led_cdev, &init_data);
-+              if (err < 0)
-+                      return dev_err_probe(dev, err, "Failed to register LED class device\n");
-+
-+              led->led_cdev.brightness_set = st1202_brightness_set;
-+              led->led_cdev.brightness_get = st1202_brightness_get;
-+      }
-+
-+      return 0;
-+}
-+
-+static int st1202_setup(struct st1202_chip *chip)
-+{
-+      int ret;
-+
-+      guard(mutex)(&chip->lock);
-+
-+      /*
-+       * Once the supply voltage is applied, the LED1202 executes some internal checks,
-+       * afterwords it stops the oscillator and puts the internal LDO in quiescent mode.
-+       * To start the device, EN bit must be set inside the “Device Enable” register at
-+       * address 01h. As soon as EN is set, the LED1202 loads the adjustment parameters
-+       * from the internal non-volatile memory and performs an auto-calibration procedure
-+       * in order to increase the output current precision.
-+       * Such initialization lasts about 6.5 ms.
-+       */
-+
-+      /* Reset the chip during setup */
-+      ret = st1202_write_reg(chip, ST1202_DEV_ENABLE, ST1202_DEV_ENABLE_RESET);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Enable phase-shift delay feature */
-+      ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Enable the device */
-+      ret = st1202_write_reg(chip, ST1202_DEV_ENABLE, ST1202_DEV_ENABLE_ON);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Duration of initialization */
-+      usleep_range(6500, 10000);
-+
-+      /* Deactivate all LEDS (channels) and activate only the ones found in Device Tree */
-+      ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_LOW, ST1202_CHAN_DISABLE_ALL);
-+      if (ret < 0)
-+              return ret;
-+
-+      ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_HIGH, ST1202_CHAN_DISABLE_ALL);
-+      if (ret < 0)
-+              return ret;
-+
-+      ret = st1202_write_reg(chip, ST1202_CONFIG_REG,
-+                              ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_PATSR);
-+      if (ret < 0)
-+              return ret;
-+
-+      return 0;
-+}
-+
-+static int st1202_probe(struct i2c_client *client)
-+{
-+      struct st1202_chip *chip;
-+      struct st1202_led *led;
-+      int ret;
-+
-+      if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-+              return dev_err_probe(&client->dev, -EIO, "SMBUS Byte Data not Supported\n");
-+
-+      chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
-+      if (!chip)
-+              return -ENOMEM;
-+
-+      devm_mutex_init(&client->dev, &chip->lock);
-+      chip->client = client;
-+
-+      ret = st1202_dt_init(chip);
-+      if (ret < 0)
-+              return ret;
-+
-+      ret = st1202_setup(chip);
-+      if (ret < 0)
-+              return ret;
-+
-+      for (int i = 0; i < ST1202_MAX_LEDS; i++) {
-+              led = &chip->leds[i];
-+              led->chip = chip;
-+              led->led_num = i;
-+
-+              if (!led->is_active)
-+                      continue;
-+
-+              ret = st1202_channel_set(led->chip, led->led_num, true);
-+              if (ret < 0)
-+                      return dev_err_probe(&client->dev, ret,
-+                                      "Failed to activate LED channel\n");
-+
-+              ret = st1202_led_pattern_clear(&led->led_cdev);
-+              if (ret < 0)
-+                      return dev_err_probe(&client->dev, ret,
-+                                      "Failed to clear LED pattern\n");
-+      }
-+
-+      return 0;
-+}
-+
-+static const struct i2c_device_id st1202_id[] = {
-+      { "st1202-i2c" },
-+      { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(i2c, st1202_id);
-+
-+static const struct of_device_id st1202_dt_ids[] = {
-+      { .compatible = "st,led1202" },
-+      { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, st1202_dt_ids);
-+
-+static struct i2c_driver st1202_driver = {
-+      .driver = {
-+              .name = "leds-st1202",
-+              .of_match_table = of_match_ptr(st1202_dt_ids),
-+      },
-+      .probe = st1202_probe,
-+      .id_table = st1202_id,
-+};
-+module_i2c_driver(st1202_driver);
-+
-+MODULE_AUTHOR("Remote Tech LTD");
-+MODULE_DESCRIPTION("STMicroelectronics LED1202 : 12-channel constant current LED driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.18/893-v6.14-leds_st1202-Fix-NULL-pointer-access-error.patch b/target/linux/generic/backport-6.18/893-v6.14-leds_st1202-Fix-NULL-pointer-access-error.patch
deleted file mode 100644 (file)
index 39d8ddb..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-From c72e455b89f216b43cd0dbb518036ec4c98f5c46 Mon Sep 17 00:00:00 2001
-From: Manuel Fombuena <fombuena@outlook.com>
-Date: Tue, 25 Feb 2025 22:01:02 +0000
-Subject: leds: leds-st1202: Fix NULL pointer access on race condition
-
-st1202_dt_init() calls devm_led_classdev_register_ext() before the
-internal data structures are properly set up, so the LEDs become visible
-to user space while being partially initialized, leading to a window
-where trying to access them causes a NULL pointer access.
-
-Move devm_led_classdev_register_ext() from DT initialization
-to the end of the probe function when DT and hardware are fully
-initialized and ready to interact with user space.
-
-Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
-Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
-Link: https://lore.kernel.org/r/CWLP123MB54732771AC0CE5491B3C84DCC5C32@CWLP123MB5473.GBRP123.PROD.OUTLOOK.COM
-Signed-off-by: Lee Jones <lee@kernel.org>
----
- drivers/leds/leds-st1202.c | 21 ++++++++++-----------
- 1 file changed, 10 insertions(+), 11 deletions(-)
-
---- a/drivers/leds/leds-st1202.c
-+++ b/drivers/leds/leds-st1202.c
-@@ -261,8 +261,6 @@ static int st1202_dt_init(struct st1202_
-       int err, reg;
-       for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
--              struct led_init_data init_data = {};
--
-               err = of_property_read_u32(child, "reg", &reg);
-               if (err)
-                       return dev_err_probe(dev, err, "Invalid register\n");
-@@ -276,15 +274,6 @@ static int st1202_dt_init(struct st1202_
-               led->led_cdev.pattern_set = st1202_led_pattern_set;
-               led->led_cdev.pattern_clear = st1202_led_pattern_clear;
-               led->led_cdev.default_trigger = "pattern";
--
--              init_data.fwnode = led->fwnode;
--              init_data.devicename = "st1202";
--              init_data.default_label = ":";
--
--              err = devm_led_classdev_register_ext(dev, &led->led_cdev, &init_data);
--              if (err < 0)
--                      return dev_err_probe(dev, err, "Failed to register LED class device\n");
--
-               led->led_cdev.brightness_set = st1202_brightness_set;
-               led->led_cdev.brightness_get = st1202_brightness_get;
-       }
-@@ -368,6 +357,7 @@ static int st1202_probe(struct i2c_clien
-               return ret;
-       for (int i = 0; i < ST1202_MAX_LEDS; i++) {
-+              struct led_init_data init_data = {};
-               led = &chip->leds[i];
-               led->chip = chip;
-               led->led_num = i;
-@@ -384,6 +374,15 @@ static int st1202_probe(struct i2c_clien
-               if (ret < 0)
-                       return dev_err_probe(&client->dev, ret,
-                                       "Failed to clear LED pattern\n");
-+
-+              init_data.fwnode = led->fwnode;
-+              init_data.devicename = "st1202";
-+              init_data.default_label = ":";
-+
-+              ret = devm_led_classdev_register_ext(&client->dev, &led->led_cdev, &init_data);
-+              if (ret < 0)
-+                      return dev_err_probe(&client->dev, ret,
-+                                      "Failed to register LED class device\n");
-       }
-       return 0;
diff --git a/target/linux/generic/backport-6.18/900-v6.14-driver-core-add-a-faux-bus-for-use-when-a-simple-dev.patch b/target/linux/generic/backport-6.18/900-v6.14-driver-core-add-a-faux-bus-for-use-when-a-simple-dev.patch
deleted file mode 100644 (file)
index 1ada8a6..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-From 35fa2d88ca9481e5caf533d58b99ca259c63b2fe Mon Sep 17 00:00:00 2001
-From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Date: Mon, 10 Feb 2025 13:30:25 +0100
-Subject: [PATCH] driver core: add a faux bus for use when a simple device/bus
- is needed
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Many drivers abuse the platform driver/bus system as it provides a
-simple way to create and bind a device to a driver-specific set of
-probe/release functions.  Instead of doing that, and wasting all of the
-memory associated with a platform device, here is a "faux" bus that
-can be used instead.
-
-Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
-Reviewed-by: Danilo Krummrich <dakr@kernel.org>
-Reviewed-by: Lyude Paul <lyude@redhat.com>
-Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
-Reviewed-by: Zijun Hu <quic_zijuhu@quicinc.com>
-Link: https://lore.kernel.org/r/2025021026-atlantic-gibberish-3f0c@gregkh
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- Documentation/driver-api/infrastructure.rst |   6 +
- drivers/base/Makefile                       |   2 +-
- drivers/base/base.h                         |   1 +
- drivers/base/faux.c                         | 232 ++++++++++++++++++++
- drivers/base/init.c                         |   1 +
- include/linux/device/faux.h                 |  69 ++++++
- 6 files changed, 310 insertions(+), 1 deletion(-)
- create mode 100644 drivers/base/faux.c
- create mode 100644 include/linux/device/faux.h
-
---- a/Documentation/driver-api/infrastructure.rst
-+++ b/Documentation/driver-api/infrastructure.rst
-@@ -41,6 +41,12 @@ Device Drivers Base
- .. kernel-doc:: drivers/base/class.c
-    :export:
-+.. kernel-doc:: include/linux/device/faux.h
-+   :internal:
-+
-+.. kernel-doc:: drivers/base/faux.c
-+   :export:
-+
- .. kernel-doc:: drivers/base/node.c
-    :internal:
---- a/drivers/base/Makefile
-+++ b/drivers/base/Makefile
-@@ -6,7 +6,7 @@ obj-y                  := component.o core.o bus.o dd.o
-                          cpu.o firmware.o init.o map.o devres.o \
-                          attribute_container.o transport_class.o \
-                          topology.o container.o property.o cacheinfo.o \
--                         swnode.o
-+                         swnode.o faux.o
- obj-$(CONFIG_AUXILIARY_BUS) += auxiliary.o
- obj-$(CONFIG_DEVTMPFS)        += devtmpfs.o
- obj-y                 += power/
---- a/drivers/base/base.h
-+++ b/drivers/base/base.h
-@@ -138,6 +138,7 @@ int hypervisor_init(void);
- static inline int hypervisor_init(void) { return 0; }
- #endif
- int platform_bus_init(void);
-+int faux_bus_init(void);
- void cpu_dev_init(void);
- void container_dev_init(void);
- #ifdef CONFIG_AUXILIARY_BUS
---- /dev/null
-+++ b/drivers/base/faux.c
-@@ -0,0 +1,232 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2025 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-+ * Copyright (c) 2025 The Linux Foundation
-+ *
-+ * A "simple" faux bus that allows devices to be created and added
-+ * automatically to it.  This is to be used whenever you need to create a
-+ * device that is not associated with any "real" system resources, and do
-+ * not want to have to deal with a bus/driver binding logic.  It is
-+ * intended to be very simple, with only a create and a destroy function
-+ * available.
-+ */
-+#include <linux/err.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/container_of.h>
-+#include <linux/device/faux.h>
-+#include "base.h"
-+
-+/*
-+ * Internal wrapper structure so we can hold a pointer to the
-+ * faux_device_ops for this device.
-+ */
-+struct faux_object {
-+      struct faux_device faux_dev;
-+      const struct faux_device_ops *faux_ops;
-+};
-+#define to_faux_object(dev) container_of_const(dev, struct faux_object, faux_dev.dev)
-+
-+static struct device faux_bus_root = {
-+      .init_name      = "faux",
-+};
-+
-+static int faux_match(struct device *dev, const struct device_driver *drv)
-+{
-+      /* Match always succeeds, we only have one driver */
-+      return 1;
-+}
-+
-+static int faux_probe(struct device *dev)
-+{
-+      struct faux_object *faux_obj = to_faux_object(dev);
-+      struct faux_device *faux_dev = &faux_obj->faux_dev;
-+      const struct faux_device_ops *faux_ops = faux_obj->faux_ops;
-+      int ret = 0;
-+
-+      if (faux_ops && faux_ops->probe)
-+              ret = faux_ops->probe(faux_dev);
-+
-+      return ret;
-+}
-+
-+static void faux_remove(struct device *dev)
-+{
-+      struct faux_object *faux_obj = to_faux_object(dev);
-+      struct faux_device *faux_dev = &faux_obj->faux_dev;
-+      const struct faux_device_ops *faux_ops = faux_obj->faux_ops;
-+
-+      if (faux_ops && faux_ops->remove)
-+              faux_ops->remove(faux_dev);
-+}
-+
-+static const struct bus_type faux_bus_type = {
-+      .name           = "faux",
-+      .match          = faux_match,
-+      .probe          = faux_probe,
-+      .remove         = faux_remove,
-+};
-+
-+static struct device_driver faux_driver = {
-+      .name           = "faux_driver",
-+      .bus            = &faux_bus_type,
-+      .probe_type     = PROBE_FORCE_SYNCHRONOUS,
-+};
-+
-+static void faux_device_release(struct device *dev)
-+{
-+      struct faux_object *faux_obj = to_faux_object(dev);
-+
-+      kfree(faux_obj);
-+}
-+
-+/**
-+ * faux_device_create_with_groups - Create and register with the driver
-+ *            core a faux device and populate the device with an initial
-+ *            set of sysfs attributes.
-+ * @name:     The name of the device we are adding, must be unique for
-+ *            all faux devices.
-+ * @parent:   Pointer to a potential parent struct device.  If set to
-+ *            NULL, the device will be created in the "root" of the faux
-+ *            device tree in sysfs.
-+ * @faux_ops: struct faux_device_ops that the new device will call back
-+ *            into, can be NULL.
-+ * @groups:   The set of sysfs attributes that will be created for this
-+ *            device when it is registered with the driver core.
-+ *
-+ * Create a new faux device and register it in the driver core properly.
-+ * If present, callbacks in @faux_ops will be called with the device that
-+ * for the caller to do something with at the proper time given the
-+ * device's lifecycle.
-+ *
-+ * Note, when this function is called, the functions specified in struct
-+ * faux_ops can be called before the function returns, so be prepared for
-+ * everything to be properly initialized before that point in time.
-+ *
-+ * Return:
-+ * * NULL if an error happened with creating the device
-+ * * pointer to a valid struct faux_device that is registered with sysfs
-+ */
-+struct faux_device *faux_device_create_with_groups(const char *name,
-+                                                 struct device *parent,
-+                                                 const struct faux_device_ops *faux_ops,
-+                                                 const struct attribute_group **groups)
-+{
-+      struct faux_object *faux_obj;
-+      struct faux_device *faux_dev;
-+      struct device *dev;
-+      int ret;
-+
-+      faux_obj = kzalloc(sizeof(*faux_obj), GFP_KERNEL);
-+      if (!faux_obj)
-+              return NULL;
-+
-+      /* Save off the callbacks so we can use them in the future */
-+      faux_obj->faux_ops = faux_ops;
-+
-+      /* Initialize the device portion and register it with the driver core */
-+      faux_dev = &faux_obj->faux_dev;
-+      dev = &faux_dev->dev;
-+
-+      device_initialize(dev);
-+      dev->release = faux_device_release;
-+      if (parent)
-+              dev->parent = parent;
-+      else
-+              dev->parent = &faux_bus_root;
-+      dev->bus = &faux_bus_type;
-+      dev->groups = groups;
-+      dev_set_name(dev, "%s", name);
-+
-+      ret = device_add(dev);
-+      if (ret) {
-+              pr_err("%s: device_add for faux device '%s' failed with %d\n",
-+                     __func__, name, ret);
-+              put_device(dev);
-+              return NULL;
-+      }
-+
-+      return faux_dev;
-+}
-+EXPORT_SYMBOL_GPL(faux_device_create_with_groups);
-+
-+/**
-+ * faux_device_create - create and register with the driver core a faux device
-+ * @name:     The name of the device we are adding, must be unique for all
-+ *            faux devices.
-+ * @parent:   Pointer to a potential parent struct device.  If set to
-+ *            NULL, the device will be created in the "root" of the faux
-+ *            device tree in sysfs.
-+ * @faux_ops: struct faux_device_ops that the new device will call back
-+ *            into, can be NULL.
-+ *
-+ * Create a new faux device and register it in the driver core properly.
-+ * If present, callbacks in @faux_ops will be called with the device that
-+ * for the caller to do something with at the proper time given the
-+ * device's lifecycle.
-+ *
-+ * Note, when this function is called, the functions specified in struct
-+ * faux_ops can be called before the function returns, so be prepared for
-+ * everything to be properly initialized before that point in time.
-+ *
-+ * Return:
-+ * * NULL if an error happened with creating the device
-+ * * pointer to a valid struct faux_device that is registered with sysfs
-+ */
-+struct faux_device *faux_device_create(const char *name,
-+                                     struct device *parent,
-+                                     const struct faux_device_ops *faux_ops)
-+{
-+      return faux_device_create_with_groups(name, parent, faux_ops, NULL);
-+}
-+EXPORT_SYMBOL_GPL(faux_device_create);
-+
-+/**
-+ * faux_device_destroy - destroy a faux device
-+ * @faux_dev: faux device to destroy
-+ *
-+ * Unregisters and cleans up a device that was created with a call to
-+ * faux_device_create()
-+ */
-+void faux_device_destroy(struct faux_device *faux_dev)
-+{
-+      struct device *dev = &faux_dev->dev;
-+
-+      if (!faux_dev)
-+              return;
-+
-+      device_del(dev);
-+
-+      /* The final put_device() will clean up the memory we allocated for this device. */
-+      put_device(dev);
-+}
-+EXPORT_SYMBOL_GPL(faux_device_destroy);
-+
-+int __init faux_bus_init(void)
-+{
-+      int ret;
-+
-+      ret = device_register(&faux_bus_root);
-+      if (ret) {
-+              put_device(&faux_bus_root);
-+              return ret;
-+      }
-+
-+      ret = bus_register(&faux_bus_type);
-+      if (ret)
-+              goto error_bus;
-+
-+      ret = driver_register(&faux_driver);
-+      if (ret)
-+              goto error_driver;
-+
-+      return ret;
-+
-+error_driver:
-+      bus_unregister(&faux_bus_type);
-+
-+error_bus:
-+      device_unregister(&faux_bus_root);
-+      return ret;
-+}
---- a/drivers/base/init.c
-+++ b/drivers/base/init.c
-@@ -32,6 +32,7 @@ void __init driver_init(void)
-       /* These are also core pieces, but must come after the
-        * core core pieces.
-        */
-+      faux_bus_init();
-       of_core_init();
-       platform_bus_init();
-       auxiliary_bus_init();
---- /dev/null
-+++ b/include/linux/device/faux.h
-@@ -0,0 +1,69 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (c) 2025 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-+ * Copyright (c) 2025 The Linux Foundation
-+ *
-+ * A "simple" faux bus that allows devices to be created and added
-+ * automatically to it.  This is to be used whenever you need to create a
-+ * device that is not associated with any "real" system resources, and do
-+ * not want to have to deal with a bus/driver binding logic.  It is
-+ * intended to be very simple, with only a create and a destroy function
-+ * available.
-+ */
-+#ifndef _FAUX_DEVICE_H_
-+#define _FAUX_DEVICE_H_
-+
-+#include <linux/container_of.h>
-+#include <linux/device.h>
-+
-+/**
-+ * struct faux_device - a "faux" device
-+ * @dev:      internal struct device of the object
-+ *
-+ * A simple faux device that can be created/destroyed.  To be used when a
-+ * driver only needs to have a device to "hang" something off.  This can be
-+ * used for downloading firmware or other basic tasks.  Use this instead of
-+ * a struct platform_device if the device has no resources assigned to
-+ * it at all.
-+ */
-+struct faux_device {
-+      struct device dev;
-+};
-+#define to_faux_device(x) container_of_const((x), struct faux_device, dev)
-+
-+/**
-+ * struct faux_device_ops - a set of callbacks for a struct faux_device
-+ * @probe:    called when a faux device is probed by the driver core
-+ *            before the device is fully bound to the internal faux bus
-+ *            code.  If probe succeeds, return 0, otherwise return a
-+ *            negative error number to stop the probe sequence from
-+ *            succeeding.
-+ * @remove:   called when a faux device is removed from the system
-+ *
-+ * Both @probe and @remove are optional, if not needed, set to NULL.
-+ */
-+struct faux_device_ops {
-+      int (*probe)(struct faux_device *faux_dev);
-+      void (*remove)(struct faux_device *faux_dev);
-+};
-+
-+struct faux_device *faux_device_create(const char *name,
-+                                     struct device *parent,
-+                                     const struct faux_device_ops *faux_ops);
-+struct faux_device *faux_device_create_with_groups(const char *name,
-+                                                 struct device *parent,
-+                                                 const struct faux_device_ops *faux_ops,
-+                                                 const struct attribute_group **groups);
-+void faux_device_destroy(struct faux_device *faux_dev);
-+
-+static inline void *faux_device_get_drvdata(const struct faux_device *faux_dev)
-+{
-+      return dev_get_drvdata(&faux_dev->dev);
-+}
-+
-+static inline void faux_device_set_drvdata(struct faux_device *faux_dev, void *data)
-+{
-+      dev_set_drvdata(&faux_dev->dev, data);
-+}
-+
-+#endif /* _FAUX_DEVICE_H_ */