kernel: 5.10: compress 7xx patch numbering
authorMatthew Hagan <mnhagan88@gmail.com>
Sat, 6 Nov 2021 13:50:27 +0000 (13:50 +0000)
committerAdrian Schmutzler <freifunk@adrianschmutzler.de>
Sat, 6 Nov 2021 23:05:26 +0000 (00:05 +0100)
The qca8k patch series brings the numbering to 799. This patch renames
7xx patches to create space for more backports to be added.

Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
[rename 729->719]
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
186 files changed:
target/linux/generic/backport-5.10/705-net-phy-at803x-select-correct-page-on-config-init.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/706-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/710-v5.12-net-phy-Add-100-base-x-mode.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/711-v5.12-sfp-add-support-for-100-base-x-SFPs.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/712-v5.13-net-phy-marvell-refactor-HWMON-OOP-style.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/713-v5.15-net-phy-marvell-add-SFP-support-for-88E1510.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/719-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/720-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/721-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/722-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/723-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/724-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/725-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/730-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/730-net-phy-at803x-select-correct-page-on-config-init.patch [deleted file]
target/linux/generic/backport-5.10/731-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch [deleted file]
target/linux/generic/backport-5.10/731-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/731-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/732-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/732-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/733-v5.15-0001-net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/733-v5.15-0002-net-bgmac-platform-handle-mac-address-deferral.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-01-net-dsa-qca8k-change-simple-print-to-dev-variant.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-02-net-dsa-qca8k-use-iopoll-macro-for-qca8k_busy_wait.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-03-net-dsa-qca8k-improve-qca8k-read-write-rmw-bus-acces.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-04-net-dsa-qca8k-handle-qca8k_set_page-errors.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-05-net-dsa-qca8k-handle-error-with-qca8k_read-operation.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-06-net-dsa-qca8k-handle-error-with-qca8k_write-operatio.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-07-net-dsa-qca8k-handle-error-with-qca8k_rmw-operation.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-08-net-dsa-qca8k-handle-error-from-qca8k_busy_wait.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-09-net-dsa-qca8k-add-support-for-qca8327-switch.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-10-devicetree-net-dsa-qca8k-Document-new-compatible-qca.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-11-net-dsa-qca8k-add-priority-tweak-to-qca8337-switch.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-12-net-dsa-qca8k-limit-port5-delay-to-qca8337.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-13-net-dsa-qca8k-add-GLOBAL_FC-settings-needed-for-qca8.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-14-net-dsa-qca8k-add-support-for-switch-rev.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-15-net-dsa-qca8k-add-ethernet-ports-fallback-to-setup_m.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-16-net-dsa-qca8k-make-rgmii-delay-configurable.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-17-net-dsa-qca8k-clear-MASTER_EN-after-phy-read-write.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-18-net-dsa-qca8k-dsa-qca8k-protect-MASTER-busy_wait-wit.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-19-net-dsa-qca8k-enlarge-mdio-delay-and-timeout.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-20-net-dsa-qca8k-add-support-for-internal-phy-and-inter.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-21-devicetree-bindings-dsa-qca8k-Document-internal-mdio.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-22-net-dsa-qca8k-improve-internal-mdio-read-write-bus-a.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-23-net-dsa-qca8k-pass-switch_revision-info-to-phy-dev_f.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/735-v5.14-25-net-phy-add-support-for-qca8k-switch-internal-PHY-in.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/736-v5.14-net-dsa-qca8k-fix-missing-unlock-on-error-in-qca8k-vlan.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/737-v5.14-01-net-dsa-qca8k-check-return-value-of-read-functions-c.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/737-v5.14-02-net-dsa-qca8k-add-missing-check-return-value-in-qca8.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/738-v5.14-01-net-dsa-qca8k-fix-an-endian-bug-in-qca8k-get-ethtool.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/738-v5.14-02-net-dsa-qca8k-check-the-correct-variable-in-qca8k-se.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/739-v5.15-net-dsa-qca8k-fix-kernel-panic-with-legacy-mdio-mapping.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/740-v5.12-net-phy-Add-100-base-x-mode.patch [deleted file]
target/linux/generic/backport-5.10/740-v5.13-0001-net-dsa-b53-Add-debug-prints-in-b53_vlan_enable.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/740-v5.13-0002-net-dsa-b53-spi-allow-device-tree-probing.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/740-v5.13-0003-net-dsa-b53-relax-is63xx-condition.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/740-v5.13-0004-net-dsa-tag_brcm-add-support-for-legacy-tags.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/740-v5.13-0005-net-dsa-b53-support-legacy-tags.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/740-v5.13-0006-net-dsa-b53-mmap-Add-device-tree-support.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/740-v5.13-0007-net-dsa-b53-spi-add-missing-MODULE_DEVICE_TABLE.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/741-v5.12-sfp-add-support-for-100-base-x-SFPs.patch [deleted file]
target/linux/generic/backport-5.10/741-v5.14-0001-net-dsa-b53-Do-not-force-CPU-to-be-always-tagged.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/741-v5.14-0002-net-dsa-b53-remove-redundant-null-check-on-dev.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/741-v5.14-0003-net-dsa-b53-Create-default-VLAN-entry-explicitly.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/742-v5.13-net-phy-marvell-refactor-HWMON-OOP-style.patch [deleted file]
target/linux/generic/backport-5.10/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/743-v5.15-net-phy-marvell-add-SFP-support-for-88E1510.patch [deleted file]
target/linux/generic/backport-5.10/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/744-v5.15-net-dsa-don-t-set-skb-offload_fwd_mark-when-not-offl.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/765-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch [deleted file]
target/linux/generic/backport-5.10/770-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch [deleted file]
target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch [deleted file]
target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch [deleted file]
target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch [deleted file]
target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch [deleted file]
target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch [deleted file]
target/linux/generic/backport-5.10/780-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch [deleted file]
target/linux/generic/backport-5.10/781-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch [deleted file]
target/linux/generic/backport-5.10/781-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch [deleted file]
target/linux/generic/backport-5.10/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch [deleted file]
target/linux/generic/backport-5.10/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch [deleted file]
target/linux/generic/backport-5.10/783-v5.15-0001-net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch [deleted file]
target/linux/generic/backport-5.10/783-v5.15-0002-net-bgmac-platform-handle-mac-address-deferral.patch [deleted file]
target/linux/generic/backport-5.10/784-v5.16-0001-net-bgmac-improve-handling-PHY.patch [deleted file]
target/linux/generic/backport-5.10/784-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-01-net-dsa-qca8k-change-simple-print-to-dev-variant.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-02-net-dsa-qca8k-use-iopoll-macro-for-qca8k_busy_wait.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-03-net-dsa-qca8k-improve-qca8k-read-write-rmw-bus-acces.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-04-net-dsa-qca8k-handle-qca8k_set_page-errors.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-05-net-dsa-qca8k-handle-error-with-qca8k_read-operation.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-06-net-dsa-qca8k-handle-error-with-qca8k_write-operatio.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-07-net-dsa-qca8k-handle-error-with-qca8k_rmw-operation.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-08-net-dsa-qca8k-handle-error-from-qca8k_busy_wait.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-09-net-dsa-qca8k-add-support-for-qca8327-switch.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-10-devicetree-net-dsa-qca8k-Document-new-compatible-qca.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-11-net-dsa-qca8k-add-priority-tweak-to-qca8337-switch.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-12-net-dsa-qca8k-limit-port5-delay-to-qca8337.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-13-net-dsa-qca8k-add-GLOBAL_FC-settings-needed-for-qca8.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-14-net-dsa-qca8k-add-support-for-switch-rev.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-15-net-dsa-qca8k-add-ethernet-ports-fallback-to-setup_m.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-16-net-dsa-qca8k-make-rgmii-delay-configurable.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-17-net-dsa-qca8k-clear-MASTER_EN-after-phy-read-write.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-18-net-dsa-qca8k-dsa-qca8k-protect-MASTER-busy_wait-wit.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-19-net-dsa-qca8k-enlarge-mdio-delay-and-timeout.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-20-net-dsa-qca8k-add-support-for-internal-phy-and-inter.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-21-devicetree-bindings-dsa-qca8k-Document-internal-mdio.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-22-net-dsa-qca8k-improve-internal-mdio-read-write-bus-a.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-23-net-dsa-qca8k-pass-switch_revision-info-to-phy-dev_f.patch [deleted file]
target/linux/generic/backport-5.10/785-v5.14-25-net-phy-add-support-for-qca8k-switch-internal-PHY-in.patch [deleted file]
target/linux/generic/backport-5.10/786-v5.14-net-dsa-qca8k-fix-missing-unlock-on-error-in-qca8k-vlan.patch [deleted file]
target/linux/generic/backport-5.10/787-v5.14-01-net-dsa-qca8k-check-return-value-of-read-functions-c.patch [deleted file]
target/linux/generic/backport-5.10/787-v5.14-02-net-dsa-qca8k-add-missing-check-return-value-in-qca8.patch [deleted file]
target/linux/generic/backport-5.10/788-v5.14-01-net-dsa-qca8k-fix-an-endian-bug-in-qca8k-get-ethtool.patch [deleted file]
target/linux/generic/backport-5.10/788-v5.14-02-net-dsa-qca8k-check-the-correct-variable-in-qca8k-se.patch [deleted file]
target/linux/generic/backport-5.10/789-v5.15-net-dsa-qca8k-fix-kernel-panic-with-legacy-mdio-mapping.patch [deleted file]
target/linux/generic/backport-5.10/790-v5.13-0001-net-dsa-b53-Add-debug-prints-in-b53_vlan_enable.patch [deleted file]
target/linux/generic/backport-5.10/790-v5.13-0002-net-dsa-b53-spi-allow-device-tree-probing.patch [deleted file]
target/linux/generic/backport-5.10/790-v5.13-0003-net-dsa-b53-relax-is63xx-condition.patch [deleted file]
target/linux/generic/backport-5.10/790-v5.13-0004-net-dsa-tag_brcm-add-support-for-legacy-tags.patch [deleted file]
target/linux/generic/backport-5.10/790-v5.13-0005-net-dsa-b53-support-legacy-tags.patch [deleted file]
target/linux/generic/backport-5.10/790-v5.13-0006-net-dsa-b53-mmap-Add-device-tree-support.patch [deleted file]
target/linux/generic/backport-5.10/790-v5.13-0007-net-dsa-b53-spi-add-missing-MODULE_DEVICE_TABLE.patch [deleted file]
target/linux/generic/backport-5.10/791-v5.14-0001-net-dsa-b53-Do-not-force-CPU-to-be-always-tagged.patch [deleted file]
target/linux/generic/backport-5.10/791-v5.14-0002-net-dsa-b53-remove-redundant-null-check-on-dev.patch [deleted file]
target/linux/generic/backport-5.10/791-v5.14-0003-net-dsa-b53-Create-default-VLAN-entry-explicitly.patch [deleted file]
target/linux/generic/backport-5.10/792-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch [deleted file]
target/linux/generic/backport-5.10/793-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch [deleted file]
target/linux/generic/backport-5.10/793-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch [deleted file]
target/linux/generic/backport-5.10/793-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch [deleted file]
target/linux/generic/backport-5.10/793-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch [deleted file]
target/linux/generic/backport-5.10/794-v5.15-net-dsa-don-t-set-skb-offload_fwd_mark-when-not-offl.patch [deleted file]
target/linux/generic/backport-5.10/795-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch [deleted file]
target/linux/generic/backport-5.10/795-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch [deleted file]
target/linux/generic/backport-5.10/795-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch [deleted file]
target/linux/generic/backport-5.10/796-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch [deleted file]
target/linux/generic/backport-5.10/796-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch [deleted file]
target/linux/generic/backport-5.10/796-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch [deleted file]
target/linux/generic/backport-5.10/796-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch [deleted file]
target/linux/generic/backport-5.10/797-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch [deleted file]
target/linux/generic/backport-5.10/798-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch [deleted file]
target/linux/generic/backport-5.10/799-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch [deleted file]

diff --git a/target/linux/generic/backport-5.10/705-net-phy-at803x-select-correct-page-on-config-init.patch b/target/linux/generic/backport-5.10/705-net-phy-at803x-select-correct-page-on-config-init.patch
new file mode 100644 (file)
index 0000000..00be403
--- /dev/null
@@ -0,0 +1,108 @@
+From c329e5afb42ff0a88285eb4d8a391a18793e4777 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+Date: Thu, 15 Apr 2021 03:26:50 +0200
+Subject: [PATCH] net: phy: at803x: select correct page on config init
+
+The Atheros AR8031 and AR8033 expose different registers for SGMII/Fiber
+as well as the copper side of the PHY depending on the BT_BX_REG_SEL bit
+in the chip configure register.
+
+The driver assumes the copper side is selected on probe, but this might
+not be the case depending which page was last selected by the
+bootloader. Notably, Ubiquiti UniFi bootloaders show this behavior.
+
+Select the copper page when probing to circumvent this.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 50 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 49 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -139,6 +139,9 @@
+ #define ATH8035_PHY_ID 0x004dd072
+ #define AT8030_PHY_ID_MASK                    0xffffffef
++#define AT803X_PAGE_FIBER             0
++#define AT803X_PAGE_COPPER            1
++
+ MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
+ MODULE_AUTHOR("Matus Ujhelyi");
+ MODULE_LICENSE("GPL");
+@@ -190,6 +193,35 @@ static int at803x_debug_reg_mask(struct
+       return phy_write(phydev, AT803X_DEBUG_DATA, val);
+ }
++static int at803x_write_page(struct phy_device *phydev, int page)
++{
++      int mask;
++      int set;
++
++      if (page == AT803X_PAGE_COPPER) {
++              set = AT803X_BT_BX_REG_SEL;
++              mask = 0;
++      } else {
++              set = 0;
++              mask = AT803X_BT_BX_REG_SEL;
++      }
++
++      return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set);
++}
++
++static int at803x_read_page(struct phy_device *phydev)
++{
++      int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG);
++
++      if (ccr < 0)
++              return ccr;
++
++      if (ccr & AT803X_BT_BX_REG_SEL)
++              return AT803X_PAGE_COPPER;
++
++      return AT803X_PAGE_FIBER;
++}
++
+ static int at803x_enable_rx_delay(struct phy_device *phydev)
+ {
+       return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
+@@ -508,6 +540,7 @@ static int at803x_probe(struct phy_devic
+ {
+       struct device *dev = &phydev->mdio.dev;
+       struct at803x_priv *priv;
++      int ret;
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+@@ -515,7 +548,20 @@ static int at803x_probe(struct phy_devic
+       phydev->priv = priv;
+-      return at803x_parse_dt(phydev);
++      ret = at803x_parse_dt(phydev);
++      if (ret)
++              return ret;
++
++      /* Some bootloaders leave the fiber page selected.
++       * Switch to the copper page, as otherwise we read
++       * the PHY capabilities from the fiber side.
++       */
++      if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) {
++              ret = phy_select_page(phydev, AT803X_PAGE_COPPER);
++              ret = phy_restore_page(phydev, AT803X_PAGE_COPPER, ret);
++      }
++
++      return ret;
+ }
+ static void at803x_remove(struct phy_device *phydev)
+@@ -1097,6 +1143,8 @@ static struct phy_driver at803x_driver[]
+       .get_wol                = at803x_get_wol,
+       .suspend                = at803x_suspend,
+       .resume                 = at803x_resume,
++      .read_page              = at803x_read_page,
++      .write_page             = at803x_write_page,
+       /* PHY_GBIT_FEATURES */
+       .read_status            = at803x_read_status,
+       .aneg_done              = at803x_aneg_done,
diff --git a/target/linux/generic/backport-5.10/706-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch b/target/linux/generic/backport-5.10/706-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch
new file mode 100644 (file)
index 0000000..d6ec745
--- /dev/null
@@ -0,0 +1,73 @@
+From 8f7e876273e294b732b42af2e5e6bba91d798954 Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Tue, 20 Apr 2021 12:29:29 +0200
+Subject: [PATCH] net: phy: at803x: fix probe error if copper page is selected
+
+The commit c329e5afb42f ("net: phy: at803x: select correct page on
+config init") selects the copper page during probe. This fails if the
+copper page was already selected. In this case, the value of the copper
+page (which is 1) is propagated through phy_restore_page() and is
+finally returned for at803x_probe(). Fix it, by just using the
+at803x_page_write() directly.
+
+Also in case of an error, the regulator is not disabled and leads to a
+WARN_ON() when the probe fails. This couldn't happen before, because
+at803x_parse_dt() was the last call in at803x_probe(). It is hard to
+see, that the parse_dt() actually enables the regulator. Thus move the
+regulator_enable() to the probe function and undo it in case of an
+error.
+
+Fixes: c329e5afb42f ("net: phy: at803x: select correct page on config init")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: David Bauer <mail@david-bauer.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -527,10 +527,6 @@ static int at803x_parse_dt(struct phy_de
+                       phydev_err(phydev, "failed to get VDDIO regulator\n");
+                       return PTR_ERR(priv->vddio);
+               }
+-
+-              ret = regulator_enable(priv->vddio);
+-              if (ret < 0)
+-                      return ret;
+       }
+       return 0;
+@@ -552,15 +548,30 @@ static int at803x_probe(struct phy_devic
+       if (ret)
+               return ret;
++      if (priv->vddio) {
++              ret = regulator_enable(priv->vddio);
++              if (ret < 0)
++                      return ret;
++      }
++
+       /* Some bootloaders leave the fiber page selected.
+        * Switch to the copper page, as otherwise we read
+        * the PHY capabilities from the fiber side.
+        */
+       if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) {
+-              ret = phy_select_page(phydev, AT803X_PAGE_COPPER);
+-              ret = phy_restore_page(phydev, AT803X_PAGE_COPPER, ret);
++              phy_lock_mdio_bus(phydev);
++              ret = at803x_write_page(phydev, AT803X_PAGE_COPPER);
++              phy_unlock_mdio_bus(phydev);
++              if (ret)
++                      goto err;
+       }
++      return 0;
++
++err:
++      if (priv->vddio)
++              regulator_disable(priv->vddio);
++
+       return ret;
+ }
diff --git a/target/linux/generic/backport-5.10/710-v5.12-net-phy-Add-100-base-x-mode.patch b/target/linux/generic/backport-5.10/710-v5.12-net-phy-Add-100-base-x-mode.patch
new file mode 100644 (file)
index 0000000..5c7f97e
--- /dev/null
@@ -0,0 +1,56 @@
+From b1ae3587d16a8c8fc9453e147c8708d6f006ffbb Mon Sep 17 00:00:00 2001
+From: Bjarni Jonasson <bjarni.jonasson@microchip.com>
+Date: Wed, 13 Jan 2021 12:56:25 +0100
+Subject: [PATCH] net: phy: Add 100 base-x mode
+
+Sparx-5 supports this mode and it is missing in the PHY core.
+
+Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
+Reviewed-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ Documentation/networking/phy.rst | 5 +++++
+ include/linux/phy.h              | 4 ++++
+ 2 files changed, 9 insertions(+)
+
+--- a/Documentation/networking/phy.rst
++++ b/Documentation/networking/phy.rst
+@@ -286,6 +286,11 @@ Some of the interface modes are describe
+     Note: due to legacy usage, some 10GBASE-R usage incorrectly makes
+     use of this definition.
++``PHY_INTERFACE_MODE_100BASEX``
++    This defines IEEE 802.3 Clause 24.  The link operates at a fixed data
++    rate of 125Mpbs using a 4B/5B encoding scheme, resulting in an underlying
++    data rate of 100Mpbs.
++
+ Pause frames / flow control
+ ===========================
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -104,6 +104,7 @@ extern const int phy_10gbit_features_arr
+  * @PHY_INTERFACE_MODE_MOCA: Multimedia over Coax
+  * @PHY_INTERFACE_MODE_QSGMII: Quad SGMII
+  * @PHY_INTERFACE_MODE_TRGMII: Turbo RGMII
++ * @PHY_INTERFACE_MODE_100BASEX: 100 BaseX
+  * @PHY_INTERFACE_MODE_1000BASEX: 1000 BaseX
+  * @PHY_INTERFACE_MODE_2500BASEX: 2500 BaseX
+  * @PHY_INTERFACE_MODE_RXAUI: Reduced XAUI
+@@ -135,6 +136,7 @@ typedef enum {
+       PHY_INTERFACE_MODE_MOCA,
+       PHY_INTERFACE_MODE_QSGMII,
+       PHY_INTERFACE_MODE_TRGMII,
++      PHY_INTERFACE_MODE_100BASEX,
+       PHY_INTERFACE_MODE_1000BASEX,
+       PHY_INTERFACE_MODE_2500BASEX,
+       PHY_INTERFACE_MODE_RXAUI,
+@@ -217,6 +219,8 @@ static inline const char *phy_modes(phy_
+               return "usxgmii";
+       case PHY_INTERFACE_MODE_10GKR:
+               return "10gbase-kr";
++      case PHY_INTERFACE_MODE_100BASEX:
++              return "100base-x";
+       default:
+               return "unknown";
+       }
diff --git a/target/linux/generic/backport-5.10/711-v5.12-sfp-add-support-for-100-base-x-SFPs.patch b/target/linux/generic/backport-5.10/711-v5.12-sfp-add-support-for-100-base-x-SFPs.patch
new file mode 100644 (file)
index 0000000..7d06c23
--- /dev/null
@@ -0,0 +1,40 @@
+From 6e12f35cef6b8a458d7ecf507ae330e0bffaad8c Mon Sep 17 00:00:00 2001
+From: Bjarni Jonasson <bjarni.jonasson@microchip.com>
+Date: Wed, 13 Jan 2021 12:56:26 +0100
+Subject: [PATCH] sfp: add support for 100 base-x SFPs
+
+Add support for 100Base-FX, 100Base-LX, 100Base-PX and 100Base-BX10 modules
+This is needed for Sparx-5 switch.
+
+Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
+Reviewed-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/sfp-bus.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -280,6 +280,12 @@ void sfp_parse_support(struct sfp_bus *b
+           br_min <= 1300 && br_max >= 1200)
+               phylink_set(modes, 1000baseX_Full);
++      /* 100Base-FX, 100Base-LX, 100Base-PX, 100Base-BX10 */
++      if (id->base.e100_base_fx || id->base.e100_base_lx)
++              phylink_set(modes, 100baseFX_Full);
++      if ((id->base.e_base_px || id->base.e_base_bx10) && br_nom == 100)
++              phylink_set(modes, 100baseFX_Full);
++
+       /* For active or passive cables, select the link modes
+        * based on the bit rates and the cable compliance bytes.
+        */
+@@ -399,6 +405,9 @@ phy_interface_t sfp_select_interface(str
+       if (phylink_test(link_modes, 1000baseX_Full))
+               return PHY_INTERFACE_MODE_1000BASEX;
++      if (phylink_test(link_modes, 100baseFX_Full))
++              return PHY_INTERFACE_MODE_100BASEX;
++
+       dev_warn(bus->sfp_dev, "Unable to ascertain link mode\n");
+       return PHY_INTERFACE_MODE_NA;
diff --git a/target/linux/generic/backport-5.10/712-v5.13-net-phy-marvell-refactor-HWMON-OOP-style.patch b/target/linux/generic/backport-5.10/712-v5.13-net-phy-marvell-refactor-HWMON-OOP-style.patch
new file mode 100644 (file)
index 0000000..7bf5926
--- /dev/null
@@ -0,0 +1,549 @@
+From 41d26bf4aba070dfd2ab48866cc27a48ee6228c7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Tue, 20 Apr 2021 09:53:59 +0200
+Subject: [PATCH] net: phy: marvell: refactor HWMON OOP style
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use a structure of Marvell PHY specific HWMON methods to reduce code
+duplication. Store a pointer to this structure into the PHY driver's
+driver_data member.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/marvell.c | 369 +++++++++++++-------------------------
+ 1 file changed, 125 insertions(+), 244 deletions(-)
+
+--- a/drivers/net/phy/marvell.c
++++ b/drivers/net/phy/marvell.c
+@@ -2134,6 +2134,19 @@ static int marvell_vct7_cable_test_get_s
+ }
+ #ifdef CONFIG_HWMON
++struct marvell_hwmon_ops {
++      int (*get_temp)(struct phy_device *phydev, long *temp);
++      int (*get_temp_critical)(struct phy_device *phydev, long *temp);
++      int (*set_temp_critical)(struct phy_device *phydev, long temp);
++      int (*get_temp_alarm)(struct phy_device *phydev, long *alarm);
++};
++
++static const struct marvell_hwmon_ops *
++to_marvell_hwmon_ops(const struct phy_device *phydev)
++{
++      return phydev->drv->driver_data;
++}
++
+ static int m88e1121_get_temp(struct phy_device *phydev, long *temp)
+ {
+       int oldpage;
+@@ -2177,75 +2190,6 @@ error:
+       return phy_restore_page(phydev, oldpage, ret);
+ }
+-static int m88e1121_hwmon_read(struct device *dev,
+-                             enum hwmon_sensor_types type,
+-                             u32 attr, int channel, long *temp)
+-{
+-      struct phy_device *phydev = dev_get_drvdata(dev);
+-      int err;
+-
+-      switch (attr) {
+-      case hwmon_temp_input:
+-              err = m88e1121_get_temp(phydev, temp);
+-              break;
+-      default:
+-              return -EOPNOTSUPP;
+-      }
+-
+-      return err;
+-}
+-
+-static umode_t m88e1121_hwmon_is_visible(const void *data,
+-                                       enum hwmon_sensor_types type,
+-                                       u32 attr, int channel)
+-{
+-      if (type != hwmon_temp)
+-              return 0;
+-
+-      switch (attr) {
+-      case hwmon_temp_input:
+-              return 0444;
+-      default:
+-              return 0;
+-      }
+-}
+-
+-static u32 m88e1121_hwmon_chip_config[] = {
+-      HWMON_C_REGISTER_TZ,
+-      0
+-};
+-
+-static const struct hwmon_channel_info m88e1121_hwmon_chip = {
+-      .type = hwmon_chip,
+-      .config = m88e1121_hwmon_chip_config,
+-};
+-
+-static u32 m88e1121_hwmon_temp_config[] = {
+-      HWMON_T_INPUT,
+-      0
+-};
+-
+-static const struct hwmon_channel_info m88e1121_hwmon_temp = {
+-      .type = hwmon_temp,
+-      .config = m88e1121_hwmon_temp_config,
+-};
+-
+-static const struct hwmon_channel_info *m88e1121_hwmon_info[] = {
+-      &m88e1121_hwmon_chip,
+-      &m88e1121_hwmon_temp,
+-      NULL
+-};
+-
+-static const struct hwmon_ops m88e1121_hwmon_hwmon_ops = {
+-      .is_visible = m88e1121_hwmon_is_visible,
+-      .read = m88e1121_hwmon_read,
+-};
+-
+-static const struct hwmon_chip_info m88e1121_hwmon_chip_info = {
+-      .ops = &m88e1121_hwmon_hwmon_ops,
+-      .info = m88e1121_hwmon_info,
+-};
+-
+ static int m88e1510_get_temp(struct phy_device *phydev, long *temp)
+ {
+       int ret;
+@@ -2308,92 +2252,6 @@ static int m88e1510_get_temp_alarm(struc
+       return 0;
+ }
+-static int m88e1510_hwmon_read(struct device *dev,
+-                             enum hwmon_sensor_types type,
+-                             u32 attr, int channel, long *temp)
+-{
+-      struct phy_device *phydev = dev_get_drvdata(dev);
+-      int err;
+-
+-      switch (attr) {
+-      case hwmon_temp_input:
+-              err = m88e1510_get_temp(phydev, temp);
+-              break;
+-      case hwmon_temp_crit:
+-              err = m88e1510_get_temp_critical(phydev, temp);
+-              break;
+-      case hwmon_temp_max_alarm:
+-              err = m88e1510_get_temp_alarm(phydev, temp);
+-              break;
+-      default:
+-              return -EOPNOTSUPP;
+-      }
+-
+-      return err;
+-}
+-
+-static int m88e1510_hwmon_write(struct device *dev,
+-                              enum hwmon_sensor_types type,
+-                              u32 attr, int channel, long temp)
+-{
+-      struct phy_device *phydev = dev_get_drvdata(dev);
+-      int err;
+-
+-      switch (attr) {
+-      case hwmon_temp_crit:
+-              err = m88e1510_set_temp_critical(phydev, temp);
+-              break;
+-      default:
+-              return -EOPNOTSUPP;
+-      }
+-      return err;
+-}
+-
+-static umode_t m88e1510_hwmon_is_visible(const void *data,
+-                                       enum hwmon_sensor_types type,
+-                                       u32 attr, int channel)
+-{
+-      if (type != hwmon_temp)
+-              return 0;
+-
+-      switch (attr) {
+-      case hwmon_temp_input:
+-      case hwmon_temp_max_alarm:
+-              return 0444;
+-      case hwmon_temp_crit:
+-              return 0644;
+-      default:
+-              return 0;
+-      }
+-}
+-
+-static u32 m88e1510_hwmon_temp_config[] = {
+-      HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM,
+-      0
+-};
+-
+-static const struct hwmon_channel_info m88e1510_hwmon_temp = {
+-      .type = hwmon_temp,
+-      .config = m88e1510_hwmon_temp_config,
+-};
+-
+-static const struct hwmon_channel_info *m88e1510_hwmon_info[] = {
+-      &m88e1121_hwmon_chip,
+-      &m88e1510_hwmon_temp,
+-      NULL
+-};
+-
+-static const struct hwmon_ops m88e1510_hwmon_hwmon_ops = {
+-      .is_visible = m88e1510_hwmon_is_visible,
+-      .read = m88e1510_hwmon_read,
+-      .write = m88e1510_hwmon_write,
+-};
+-
+-static const struct hwmon_chip_info m88e1510_hwmon_chip_info = {
+-      .ops = &m88e1510_hwmon_hwmon_ops,
+-      .info = m88e1510_hwmon_info,
+-};
+-
+ static int m88e6390_get_temp(struct phy_device *phydev, long *temp)
+ {
+       int sum = 0;
+@@ -2452,63 +2310,112 @@ error:
+       return ret;
+ }
+-static int m88e6390_hwmon_read(struct device *dev,
+-                             enum hwmon_sensor_types type,
+-                             u32 attr, int channel, long *temp)
++static int marvell_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
++                            u32 attr, int channel, long *temp)
+ {
+       struct phy_device *phydev = dev_get_drvdata(dev);
+-      int err;
++      const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
++      int err = -EOPNOTSUPP;
+       switch (attr) {
+       case hwmon_temp_input:
+-              err = m88e6390_get_temp(phydev, temp);
++              if (ops->get_temp)
++                      err = ops->get_temp(phydev, temp);
++              break;
++      case hwmon_temp_crit:
++              if (ops->get_temp_critical)
++                      err = ops->get_temp_critical(phydev, temp);
++              break;
++      case hwmon_temp_max_alarm:
++              if (ops->get_temp_alarm)
++                      err = ops->get_temp_alarm(phydev, temp);
++              break;
++      }
++
++      return err;
++}
++
++static int marvell_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
++                             u32 attr, int channel, long temp)
++{
++      struct phy_device *phydev = dev_get_drvdata(dev);
++      const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
++      int err = -EOPNOTSUPP;
++
++      switch (attr) {
++      case hwmon_temp_crit:
++              if (ops->set_temp_critical)
++                      err = ops->set_temp_critical(phydev, temp);
+               break;
+       default:
+-              return -EOPNOTSUPP;
++              fallthrough;
+       }
+       return err;
+ }
+-static umode_t m88e6390_hwmon_is_visible(const void *data,
+-                                       enum hwmon_sensor_types type,
+-                                       u32 attr, int channel)
++static umode_t marvell_hwmon_is_visible(const void *data,
++                                      enum hwmon_sensor_types type,
++                                      u32 attr, int channel)
+ {
++      const struct phy_device *phydev = data;
++      const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
++
+       if (type != hwmon_temp)
+               return 0;
+       switch (attr) {
+       case hwmon_temp_input:
+-              return 0444;
++              return ops->get_temp ? 0444 : 0;
++      case hwmon_temp_max_alarm:
++              return ops->get_temp_alarm ? 0444 : 0;
++      case hwmon_temp_crit:
++              return (ops->get_temp_critical ? 0444 : 0) |
++                     (ops->set_temp_critical ? 0200 : 0);
+       default:
+               return 0;
+       }
+ }
+-static u32 m88e6390_hwmon_temp_config[] = {
+-      HWMON_T_INPUT,
++static u32 marvell_hwmon_chip_config[] = {
++      HWMON_C_REGISTER_TZ,
+       0
+ };
+-static const struct hwmon_channel_info m88e6390_hwmon_temp = {
++static const struct hwmon_channel_info marvell_hwmon_chip = {
++      .type = hwmon_chip,
++      .config = marvell_hwmon_chip_config,
++};
++
++/* we can define HWMON_T_CRIT and HWMON_T_MAX_ALARM even though these are not
++ * defined for all PHYs, because the hwmon code checks whether the attributes
++ * exists via the .is_visible method
++ */
++static u32 marvell_hwmon_temp_config[] = {
++      HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM,
++      0
++};
++
++static const struct hwmon_channel_info marvell_hwmon_temp = {
+       .type = hwmon_temp,
+-      .config = m88e6390_hwmon_temp_config,
++      .config = marvell_hwmon_temp_config,
+ };
+-static const struct hwmon_channel_info *m88e6390_hwmon_info[] = {
+-      &m88e1121_hwmon_chip,
+-      &m88e6390_hwmon_temp,
++static const struct hwmon_channel_info *marvell_hwmon_info[] = {
++      &marvell_hwmon_chip,
++      &marvell_hwmon_temp,
+       NULL
+ };
+-static const struct hwmon_ops m88e6390_hwmon_hwmon_ops = {
+-      .is_visible = m88e6390_hwmon_is_visible,
+-      .read = m88e6390_hwmon_read,
++static const struct hwmon_ops marvell_hwmon_hwmon_ops = {
++      .is_visible = marvell_hwmon_is_visible,
++      .read = marvell_hwmon_read,
++      .write = marvell_hwmon_write,
+ };
+-static const struct hwmon_chip_info m88e6390_hwmon_chip_info = {
+-      .ops = &m88e6390_hwmon_hwmon_ops,
+-      .info = m88e6390_hwmon_info,
++static const struct hwmon_chip_info marvell_hwmon_chip_info = {
++      .ops = &marvell_hwmon_hwmon_ops,
++      .info = marvell_hwmon_info,
+ };
+ static int marvell_hwmon_name(struct phy_device *phydev)
+@@ -2531,49 +2438,48 @@ static int marvell_hwmon_name(struct phy
+       return 0;
+ }
+-static int marvell_hwmon_probe(struct phy_device *phydev,
+-                             const struct hwmon_chip_info *chip)
++static int marvell_hwmon_probe(struct phy_device *phydev)
+ {
++      const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
+       struct marvell_priv *priv = phydev->priv;
+       struct device *dev = &phydev->mdio.dev;
+       int err;
++      if (!ops)
++              return 0;
++
+       err = marvell_hwmon_name(phydev);
+       if (err)
+               return err;
+       priv->hwmon_dev = devm_hwmon_device_register_with_info(
+-              dev, priv->hwmon_name, phydev, chip, NULL);
++              dev, priv->hwmon_name, phydev, &marvell_hwmon_chip_info, NULL);
+       return PTR_ERR_OR_ZERO(priv->hwmon_dev);
+ }
+-static int m88e1121_hwmon_probe(struct phy_device *phydev)
+-{
+-      return marvell_hwmon_probe(phydev, &m88e1121_hwmon_chip_info);
+-}
++static const struct marvell_hwmon_ops m88e1121_hwmon_ops = {
++      .get_temp = m88e1121_get_temp,
++};
+-static int m88e1510_hwmon_probe(struct phy_device *phydev)
+-{
+-      return marvell_hwmon_probe(phydev, &m88e1510_hwmon_chip_info);
+-}
++static const struct marvell_hwmon_ops m88e1510_hwmon_ops = {
++      .get_temp = m88e1510_get_temp,
++      .get_temp_critical = m88e1510_get_temp_critical,
++      .set_temp_critical = m88e1510_set_temp_critical,
++      .get_temp_alarm = m88e1510_get_temp_alarm,
++};
++
++static const struct marvell_hwmon_ops m88e6390_hwmon_ops = {
++      .get_temp = m88e6390_get_temp,
++};
++
++#define DEF_MARVELL_HWMON_OPS(s) (&(s))
+-static int m88e6390_hwmon_probe(struct phy_device *phydev)
+-{
+-      return marvell_hwmon_probe(phydev, &m88e6390_hwmon_chip_info);
+-}
+ #else
+-static int m88e1121_hwmon_probe(struct phy_device *phydev)
+-{
+-      return 0;
+-}
+-static int m88e1510_hwmon_probe(struct phy_device *phydev)
+-{
+-      return 0;
+-}
++#define DEF_MARVELL_HWMON_OPS(s) NULL
+-static int m88e6390_hwmon_probe(struct phy_device *phydev)
++static int marvell_hwmon_probe(struct phy_device *phydev)
+ {
+       return 0;
+ }
+@@ -2589,40 +2495,7 @@ static int marvell_probe(struct phy_devi
+       phydev->priv = priv;
+-      return 0;
+-}
+-
+-static int m88e1121_probe(struct phy_device *phydev)
+-{
+-      int err;
+-
+-      err = marvell_probe(phydev);
+-      if (err)
+-              return err;
+-
+-      return m88e1121_hwmon_probe(phydev);
+-}
+-
+-static int m88e1510_probe(struct phy_device *phydev)
+-{
+-      int err;
+-
+-      err = marvell_probe(phydev);
+-      if (err)
+-              return err;
+-
+-      return m88e1510_hwmon_probe(phydev);
+-}
+-
+-static int m88e6390_probe(struct phy_device *phydev)
+-{
+-      int err;
+-
+-      err = marvell_probe(phydev);
+-      if (err)
+-              return err;
+-
+-      return m88e6390_hwmon_probe(phydev);
++      return marvell_hwmon_probe(phydev);
+ }
+ static struct phy_driver marvell_drivers[] = {
+@@ -2707,8 +2580,9 @@ static struct phy_driver marvell_drivers
+               .phy_id = MARVELL_PHY_ID_88E1121R,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E1121R",
++              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1121_hwmon_ops),
+               /* PHY_GBIT_FEATURES */
+-              .probe = m88e1121_probe,
++              .probe = marvell_probe,
+               .config_init = marvell_config_init,
+               .config_aneg = m88e1121_config_aneg,
+               .read_status = marvell_read_status,
+@@ -2827,9 +2701,10 @@ static struct phy_driver marvell_drivers
+               .phy_id = MARVELL_PHY_ID_88E1510,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E1510",
++              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
+               .features = PHY_GBIT_FIBRE_FEATURES,
+               .flags = PHY_POLL_CABLE_TEST,
+-              .probe = m88e1510_probe,
++              .probe = marvell_probe,
+               .config_init = m88e1510_config_init,
+               .config_aneg = m88e1510_config_aneg,
+               .read_status = marvell_read_status,
+@@ -2856,9 +2731,10 @@ static struct phy_driver marvell_drivers
+               .phy_id = MARVELL_PHY_ID_88E1540,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E1540",
++              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
+               /* PHY_GBIT_FEATURES */
+               .flags = PHY_POLL_CABLE_TEST,
+-              .probe = m88e1510_probe,
++              .probe = marvell_probe,
+               .config_init = marvell_config_init,
+               .config_aneg = m88e1510_config_aneg,
+               .read_status = marvell_read_status,
+@@ -2882,7 +2758,8 @@ static struct phy_driver marvell_drivers
+               .phy_id = MARVELL_PHY_ID_88E1545,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E1545",
+-              .probe = m88e1510_probe,
++              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
++              .probe = marvell_probe,
+               /* PHY_GBIT_FEATURES */
+               .flags = PHY_POLL_CABLE_TEST,
+               .config_init = marvell_config_init,
+@@ -2928,9 +2805,10 @@ static struct phy_driver marvell_drivers
+               .phy_id = MARVELL_PHY_ID_88E6341_FAMILY,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E6341 Family",
++              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
+               /* PHY_GBIT_FEATURES */
+               .flags = PHY_POLL_CABLE_TEST,
+-              .probe = m88e1510_probe,
++              .probe = marvell_probe,
+               .config_init = marvell_config_init,
+               .config_aneg = m88e6390_config_aneg,
+               .read_status = marvell_read_status,
+@@ -2954,9 +2832,10 @@ static struct phy_driver marvell_drivers
+               .phy_id = MARVELL_PHY_ID_88E6390_FAMILY,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E6390 Family",
++              .driver_data = DEF_MARVELL_HWMON_OPS(m88e6390_hwmon_ops),
+               /* PHY_GBIT_FEATURES */
+               .flags = PHY_POLL_CABLE_TEST,
+-              .probe = m88e6390_probe,
++              .probe = marvell_probe,
+               .config_init = marvell_config_init,
+               .config_aneg = m88e6390_config_aneg,
+               .read_status = marvell_read_status,
+@@ -2980,7 +2859,8 @@ static struct phy_driver marvell_drivers
+               .phy_id = MARVELL_PHY_ID_88E1340S,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E1340S",
+-              .probe = m88e1510_probe,
++              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
++              .probe = marvell_probe,
+               /* PHY_GBIT_FEATURES */
+               .config_init = marvell_config_init,
+               .config_aneg = m88e1510_config_aneg,
+@@ -3002,7 +2882,8 @@ static struct phy_driver marvell_drivers
+               .phy_id = MARVELL_PHY_ID_88E1548P,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+               .name = "Marvell 88E1548P",
+-              .probe = m88e1510_probe,
++              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
++              .probe = marvell_probe,
+               .features = PHY_GBIT_FIBRE_FEATURES,
+               .config_init = marvell_config_init,
+               .config_aneg = m88e1510_config_aneg,
diff --git a/target/linux/generic/backport-5.10/713-v5.15-net-phy-marvell-add-SFP-support-for-88E1510.patch b/target/linux/generic/backport-5.10/713-v5.15-net-phy-marvell-add-SFP-support-for-88E1510.patch
new file mode 100644 (file)
index 0000000..7fb7808
--- /dev/null
@@ -0,0 +1,161 @@
+From b697d9d38a5a5ab405d7cc4743d39fe2c5d7517c Mon Sep 17 00:00:00 2001
+From: Ivan Bornyakov <i.bornyakov@metrotek.ru>
+Date: Thu, 12 Aug 2021 16:42:56 +0300
+Subject: [PATCH] net: phy: marvell: add SFP support for 88E1510
+
+Add support for SFP cages connected to the Marvell 88E1512 transceiver.
+88E1512 supports for SGMII/1000Base-X/100Base-FX media type with RGMII
+on system interface. Configure PHY to appropriate mode depending on the
+type of SFP inserted. On SFP removal configure PHY to the RGMII-copper
+mode so RJ-45 port can still work.
+
+Signed-off-by: Ivan Bornyakov <i.bornyakov@metrotek.ru>
+Link: https://lore.kernel.org/r/20210812134256.2436-1-i.bornyakov@metrotek.ru
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/marvell.c | 105 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 104 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/marvell.c
++++ b/drivers/net/phy/marvell.c
+@@ -32,6 +32,7 @@
+ #include <linux/marvell_phy.h>
+ #include <linux/bitfield.h>
+ #include <linux/of.h>
++#include <linux/sfp.h>
+ #include <linux/io.h>
+ #include <asm/irq.h>
+@@ -46,6 +47,7 @@
+ #define MII_MARVELL_MISC_TEST_PAGE    0x06
+ #define MII_MARVELL_VCT7_PAGE         0x07
+ #define MII_MARVELL_WOL_PAGE          0x11
++#define MII_MARVELL_MODE_PAGE         0x12
+ #define MII_M1011_IEVENT              0x13
+ #define MII_M1011_IEVENT_CLEAR                0x0000
+@@ -162,7 +164,14 @@
+ #define MII_88E1510_GEN_CTRL_REG_1            0x14
+ #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK  0x7
++#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII 0x0     /* RGMII to copper */
+ #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1     /* SGMII to copper */
++/* RGMII to 1000BASE-X */
++#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X   0x2
++/* RGMII to 100BASE-FX */
++#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX   0x3
++/* RGMII to SGMII */
++#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII   0x4
+ #define MII_88E1510_GEN_CTRL_REG_1_RESET      0x8000  /* Soft reset */
+ #define MII_VCT5_TX_RX_MDI0_COUPLING  0x10
+@@ -2498,6 +2507,100 @@ static int marvell_probe(struct phy_devi
+       return marvell_hwmon_probe(phydev);
+ }
++static int m88e1510_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
++{
++      struct phy_device *phydev = upstream;
++      phy_interface_t interface;
++      struct device *dev;
++      int oldpage;
++      int ret = 0;
++      u16 mode;
++
++      __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
++
++      dev = &phydev->mdio.dev;
++
++      sfp_parse_support(phydev->sfp_bus, id, supported);
++      interface = sfp_select_interface(phydev->sfp_bus, supported);
++
++      dev_info(dev, "%s SFP module inserted\n", phy_modes(interface));
++
++      switch (interface) {
++      case PHY_INTERFACE_MODE_1000BASEX:
++              mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X;
++
++              break;
++      case PHY_INTERFACE_MODE_100BASEX:
++              mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX;
++
++              break;
++      case PHY_INTERFACE_MODE_SGMII:
++              mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII;
++
++              break;
++      default:
++              dev_err(dev, "Incompatible SFP module inserted\n");
++
++              return -EINVAL;
++      }
++
++      oldpage = phy_select_page(phydev, MII_MARVELL_MODE_PAGE);
++      if (oldpage < 0)
++              goto error;
++
++      ret = __phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
++                         MII_88E1510_GEN_CTRL_REG_1_MODE_MASK, mode);
++      if (ret < 0)
++              goto error;
++
++      ret = __phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
++                           MII_88E1510_GEN_CTRL_REG_1_RESET);
++
++error:
++      return phy_restore_page(phydev, oldpage, ret);
++}
++
++static void m88e1510_sfp_remove(void *upstream)
++{
++      struct phy_device *phydev = upstream;
++      int oldpage;
++      int ret = 0;
++
++      oldpage = phy_select_page(phydev, MII_MARVELL_MODE_PAGE);
++      if (oldpage < 0)
++              goto error;
++
++      ret = __phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
++                         MII_88E1510_GEN_CTRL_REG_1_MODE_MASK,
++                         MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII);
++      if (ret < 0)
++              goto error;
++
++      ret = __phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
++                           MII_88E1510_GEN_CTRL_REG_1_RESET);
++
++error:
++      phy_restore_page(phydev, oldpage, ret);
++}
++
++static const struct sfp_upstream_ops m88e1510_sfp_ops = {
++      .module_insert = m88e1510_sfp_insert,
++      .module_remove = m88e1510_sfp_remove,
++      .attach = phy_sfp_attach,
++      .detach = phy_sfp_detach,
++};
++
++static int m88e1510_probe(struct phy_device *phydev)
++{
++      int err;
++
++      err = marvell_probe(phydev);
++      if (err)
++              return err;
++
++      return phy_sfp_probe(phydev, &m88e1510_sfp_ops);
++}
++
+ static struct phy_driver marvell_drivers[] = {
+       {
+               .phy_id = MARVELL_PHY_ID_88E1101,
+@@ -2704,7 +2807,7 @@ static struct phy_driver marvell_drivers
+               .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
+               .features = PHY_GBIT_FIBRE_FEATURES,
+               .flags = PHY_POLL_CABLE_TEST,
+-              .probe = marvell_probe,
++              .probe = m88e1510_probe,
+               .config_init = m88e1510_config_init,
+               .config_aneg = m88e1510_config_aneg,
+               .read_status = marvell_read_status,
diff --git a/target/linux/generic/backport-5.10/719-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch b/target/linux/generic/backport-5.10/719-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch
new file mode 100644 (file)
index 0000000..3b63037
--- /dev/null
@@ -0,0 +1,85 @@
+From 9d5ef190e5615a7b63af89f88c4106a5bc127974 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Fri, 5 Feb 2021 15:37:10 +0200
+Subject: [PATCH] net: dsa: automatically bring up DSA master when opening user
+ port
+
+DSA wants the master interface to be open before the user port is due to
+historical reasons. The promiscuity of interfaces that are down used to
+have issues, as referenced Lennert Buytenhek in commit df02c6ff2e39
+("dsa: fix master interface allmulti/promisc handling").
+
+The bugfix mentioned there, commit b6c40d68ff64 ("net: only invoke
+dev->change_rx_flags when device is UP"), was basically a "don't do
+that" approach to working around the promiscuity while down issue.
+
+Further work done by Vlad Yasevich in commit d2615bf45069 ("net: core:
+Always propagate flag changes to interfaces") has resolved the
+underlying issue, and it is strictly up to the DSA and 8021q drivers
+now, it is no longer mandated by the networking core that the master
+interface must be up when changing its promiscuity.
+
+From DSA's point of view, deciding to error out in dsa_slave_open
+because the master isn't up is
+(a) a bad user experience and
+(b) knocking at an open door.
+Even if there still was an issue with promiscuity while down, DSA could
+still just open the master and avoid it.
+
+Doing it this way has the additional benefit that user space can now
+remove DSA-specific workarounds, like systemd-networkd with BindCarrier:
+https://github.com/systemd/systemd/issues/7478
+
+And we can finally remove one of the 2 bullets in the "Common pitfalls
+using DSA setups" chapter.
+
+Tested with two cascaded DSA switches:
+
+$ ip link set sw0p2 up
+fsl_enetc 0000:00:00.2 eno2: configuring for fixed/internal link mode
+fsl_enetc 0000:00:00.2 eno2: Link is Up - 1Gbps/Full - flow control rx/tx
+mscc_felix 0000:00:00.5 swp0: configuring for fixed/sgmii link mode
+mscc_felix 0000:00:00.5 swp0: Link is Up - 1Gbps/Full - flow control off
+8021q: adding VLAN 0 to HW filter on device swp0
+sja1105 spi2.0 sw0p2: configuring for phy/rgmii-id link mode
+IPv6: ADDRCONF(NETDEV_CHANGE): eno2: link becomes ready
+IPv6: ADDRCONF(NETDEV_CHANGE): swp0: link becomes ready
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ Documentation/networking/dsa/dsa.rst | 4 ----
+ net/dsa/slave.c                      | 7 +++++--
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+--- a/Documentation/networking/dsa/dsa.rst
++++ b/Documentation/networking/dsa/dsa.rst
+@@ -273,10 +273,6 @@ will not make us go through the switch t
+ the Ethernet switch on the other end, expecting a tag will typically drop this
+ frame.
+-Slave network devices check that the master network device is UP before allowing
+-you to administratively bring UP these slave network devices. A common
+-configuration mistake is forgetting to bring UP the master network device first.
+-
+ Interactions with other subsystems
+ ==================================
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -68,8 +68,11 @@ static int dsa_slave_open(struct net_dev
+       struct dsa_port *dp = dsa_slave_to_port(dev);
+       int err;
+-      if (!(master->flags & IFF_UP))
+-              return -ENETDOWN;
++      err = dev_open(master, NULL);
++      if (err < 0) {
++              netdev_err(dev, "failed to open master %s\n", master->name);
++              goto out;
++      }
+       if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) {
+               err = dev_uc_add(master, dev->dev_addr);
diff --git a/target/linux/generic/backport-5.10/720-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch b/target/linux/generic/backport-5.10/720-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch
new file mode 100644 (file)
index 0000000..c43cb4d
--- /dev/null
@@ -0,0 +1,126 @@
+From 90dc8fd36078a536671adae884d0b929cce6480a Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 6 Jan 2021 11:51:30 +0200
+Subject: [PATCH] net: bridge: notify switchdev of disappearance of old FDB
+ entry upon migration
+
+Currently the bridge emits atomic switchdev notifications for
+dynamically learnt FDB entries. Monitoring these notifications works
+wonders for switchdev drivers that want to keep their hardware FDB in
+sync with the bridge's FDB.
+
+For example station A wants to talk to station B in the diagram below,
+and we are concerned with the behavior of the bridge on the DUT device:
+
+                   DUT
+ +-------------------------------------+
+ |                 br0                 |
+ | +------+ +------+ +------+ +------+ |
+ | |      | |      | |      | |      | |
+ | | swp0 | | swp1 | | swp2 | | eth0 | |
+ +-------------------------------------+
+      |        |                  |
+  Station A    |                  |
+               |                  |
+         +--+------+--+    +--+------+--+
+         |  |      |  |    |  |      |  |
+         |  | swp0 |  |    |  | swp0 |  |
+ Another |  +------+  |    |  +------+  | Another
+  switch |     br0    |    |     br0    | switch
+         |  +------+  |    |  +------+  |
+         |  |      |  |    |  |      |  |
+         |  | swp1 |  |    |  | swp1 |  |
+         +--+------+--+    +--+------+--+
+                                  |
+                              Station B
+
+Interfaces swp0, swp1, swp2 are handled by a switchdev driver that has
+the following property: frames injected from its control interface bypass
+the internal address analyzer logic, and therefore, this hardware does
+not learn from the source address of packets transmitted by the network
+stack through it. So, since bridging between eth0 (where Station B is
+attached) and swp0 (where Station A is attached) is done in software,
+the switchdev hardware will never learn the source address of Station B.
+So the traffic towards that destination will be treated as unknown, i.e.
+flooded.
+
+This is where the bridge notifications come in handy. When br0 on the
+DUT sees frames with Station B's MAC address on eth0, the switchdev
+driver gets these notifications and can install a rule to send frames
+towards Station B's address that are incoming from swp0, swp1, swp2,
+only towards the control interface. This is all switchdev driver private
+business, which the notification makes possible.
+
+All is fine until someone unplugs Station B's cable and moves it to the
+other switch:
+
+                   DUT
+ +-------------------------------------+
+ |                 br0                 |
+ | +------+ +------+ +------+ +------+ |
+ | |      | |      | |      | |      | |
+ | | swp0 | | swp1 | | swp2 | | eth0 | |
+ +-------------------------------------+
+      |        |                  |
+  Station A    |                  |
+               |                  |
+         +--+------+--+    +--+------+--+
+         |  |      |  |    |  |      |  |
+         |  | swp0 |  |    |  | swp0 |  |
+ Another |  +------+  |    |  +------+  | Another
+  switch |     br0    |    |     br0    | switch
+         |  +------+  |    |  +------+  |
+         |  |      |  |    |  |      |  |
+         |  | swp1 |  |    |  | swp1 |  |
+         +--+------+--+    +--+------+--+
+               |
+           Station B
+
+Luckily for the use cases we care about, Station B is noisy enough that
+the DUT hears it (on swp1 this time). swp1 receives the frames and
+delivers them to the bridge, who enters the unlikely path in br_fdb_update
+of updating an existing entry. It moves the entry in the software bridge
+to swp1 and emits an addition notification towards that.
+
+As far as the switchdev driver is concerned, all that it needs to ensure
+is that traffic between Station A and Station B is not forever broken.
+If it does nothing, then the stale rule to send frames for Station B
+towards the control interface remains in place. But Station B is no
+longer reachable via the control interface, but via a port that can
+offload the bridge port learning attribute. It's just that the port is
+prevented from learning this address, since the rule overrides FDB
+updates. So the rule needs to go. The question is via what mechanism.
+
+It sure would be possible for this switchdev driver to keep track of all
+addresses which are sent to the control interface, and then also listen
+for bridge notifier events on its own ports, searching for the ones that
+have a MAC address which was previously sent to the control interface.
+But this is cumbersome and inefficient. Instead, with one small change,
+the bridge could notify of the address deletion from the old port, in a
+symmetrical manner with how it did for the insertion. Then the switchdev
+driver would not be required to monitor learn/forget events for its own
+ports. It could just delete the rule towards the control interface upon
+bridge entry migration. This would make hardware address learning be
+possible again. Then it would take a few more packets until the hardware
+and software FDB would be in sync again.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ net/bridge/br_fdb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/bridge/br_fdb.c
++++ b/net/bridge/br_fdb.c
+@@ -602,6 +602,7 @@ void br_fdb_update(struct net_bridge *br
+                       /* fastpath: update of existing entry */
+                       if (unlikely(source != fdb->dst &&
+                                    !test_bit(BR_FDB_STICKY, &fdb->flags))) {
++                              br_switchdev_fdb_notify(fdb, RTM_DELNEIGH);
+                               fdb->dst = source;
+                               fdb_modified = true;
+                               /* Take over HW learned entry */
diff --git a/target/linux/generic/backport-5.10/721-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch b/target/linux/generic/backport-5.10/721-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch
new file mode 100644 (file)
index 0000000..f933759
--- /dev/null
@@ -0,0 +1,52 @@
+From 2fd186501b1cff155cc4a755c210793cfc0dffb5 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 6 Jan 2021 11:51:31 +0200
+Subject: [PATCH] net: dsa: be louder when a non-legacy FDB operation fails
+
+The dev_close() call was added in commit c9eb3e0f8701 ("net: dsa: Add
+support for learning FDB through notification") "to indicate inconsistent
+situation" when we could not delete an FDB entry from the port.
+
+bridge fdb del d8:58:d7:00:ca:6d dev swp0 self master
+
+It is a bit drastic and at the same time not helpful if the above fails
+to only print with netdev_dbg log level, but on the other hand to bring
+the interface down.
+
+So increase the verbosity of the error message, and drop dev_close().
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ net/dsa/slave.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -2112,7 +2112,9 @@ static void dsa_slave_switchdev_event_wo
+               err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid);
+               if (err) {
+-                      netdev_dbg(dev, "fdb add failed err=%d\n", err);
++                      netdev_err(dev,
++                                 "failed to add %pM vid %d to fdb: %d\n",
++                                 fdb_info->addr, fdb_info->vid, err);
+                       break;
+               }
+               fdb_info->offloaded = true;
+@@ -2127,9 +2129,11 @@ static void dsa_slave_switchdev_event_wo
+               err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid);
+               if (err) {
+-                      netdev_dbg(dev, "fdb del failed err=%d\n", err);
+-                      dev_close(dev);
++                      netdev_err(dev,
++                                 "failed to delete %pM vid %d from fdb: %d\n",
++                                 fdb_info->addr, fdb_info->vid, err);
+               }
++
+               break;
+       }
+       rtnl_unlock();
diff --git a/target/linux/generic/backport-5.10/722-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch b/target/linux/generic/backport-5.10/722-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch
new file mode 100644 (file)
index 0000000..c1aa8fd
--- /dev/null
@@ -0,0 +1,226 @@
+From c4bb76a9a0ef87c4cc1f636defed5f12deb9f5a7 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 6 Jan 2021 11:51:32 +0200
+Subject: [PATCH] net: dsa: don't use switchdev_notifier_fdb_info in
+ dsa_switchdev_event_work
+
+Currently DSA doesn't add FDB entries on the CPU port, because it only
+does so through switchdev, which is associated with a net_device, and
+there are none of those for the CPU port.
+
+But actually FDB addresses on the CPU port have some use cases of their
+own, if the switchdev operations are initiated from within the DSA
+layer. There is just one problem with the existing code: it passes a
+structure in dsa_switchdev_event_work which was retrieved directly from
+switchdev, so it contains a net_device. We need to generalize the
+contents to something that covers the CPU port as well: the "ds, port"
+tuple is fine for that.
+
+Note that the new procedure for notifying the successful FDB offload is
+inspired from the rocker model.
+
+Also, nothing was being done if added_by_user was false. Let's check for
+that a lot earlier, and don't actually bother to schedule the worker
+for nothing.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ net/dsa/dsa_priv.h |  12 +++++
+ net/dsa/slave.c    | 106 ++++++++++++++++++++++-----------------------
+ 2 files changed, 65 insertions(+), 53 deletions(-)
+
+--- a/net/dsa/dsa_priv.h
++++ b/net/dsa/dsa_priv.h
+@@ -73,6 +73,18 @@ struct dsa_notifier_mtu_info {
+       int mtu;
+ };
++struct dsa_switchdev_event_work {
++      struct dsa_switch *ds;
++      int port;
++      struct work_struct work;
++      unsigned long event;
++      /* Specific for SWITCHDEV_FDB_ADD_TO_DEVICE and
++       * SWITCHDEV_FDB_DEL_TO_DEVICE
++       */
++      unsigned char addr[ETH_ALEN];
++      u16 vid;
++};
++
+ struct dsa_slave_priv {
+       /* Copy of CPU port xmit for faster access in slave transmit hot path */
+       struct sk_buff *        (*xmit)(struct sk_buff *skb,
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -2087,76 +2087,66 @@ static int dsa_slave_netdevice_event(str
+       return NOTIFY_DONE;
+ }
+-struct dsa_switchdev_event_work {
+-      struct work_struct work;
+-      struct switchdev_notifier_fdb_info fdb_info;
+-      struct net_device *dev;
+-      unsigned long event;
+-};
++static void
++dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work)
++{
++      struct dsa_switch *ds = switchdev_work->ds;
++      struct switchdev_notifier_fdb_info info;
++      struct dsa_port *dp;
++
++      if (!dsa_is_user_port(ds, switchdev_work->port))
++              return;
++
++      info.addr = switchdev_work->addr;
++      info.vid = switchdev_work->vid;
++      info.offloaded = true;
++      dp = dsa_to_port(ds, switchdev_work->port);
++      call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED,
++                               dp->slave, &info.info, NULL);
++}
+ static void dsa_slave_switchdev_event_work(struct work_struct *work)
+ {
+       struct dsa_switchdev_event_work *switchdev_work =
+               container_of(work, struct dsa_switchdev_event_work, work);
+-      struct net_device *dev = switchdev_work->dev;
+-      struct switchdev_notifier_fdb_info *fdb_info;
+-      struct dsa_port *dp = dsa_slave_to_port(dev);
++      struct dsa_switch *ds = switchdev_work->ds;
++      struct dsa_port *dp;
+       int err;
++      dp = dsa_to_port(ds, switchdev_work->port);
++
+       rtnl_lock();
+       switch (switchdev_work->event) {
+       case SWITCHDEV_FDB_ADD_TO_DEVICE:
+-              fdb_info = &switchdev_work->fdb_info;
+-              if (!fdb_info->added_by_user)
+-                      break;
+-
+-              err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid);
++              err = dsa_port_fdb_add(dp, switchdev_work->addr,
++                                     switchdev_work->vid);
+               if (err) {
+-                      netdev_err(dev,
+-                                 "failed to add %pM vid %d to fdb: %d\n",
+-                                 fdb_info->addr, fdb_info->vid, err);
++                      dev_err(ds->dev,
++                              "port %d failed to add %pM vid %d to fdb: %d\n",
++                              dp->index, switchdev_work->addr,
++                              switchdev_work->vid, err);
+                       break;
+               }
+-              fdb_info->offloaded = true;
+-              call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, dev,
+-                                       &fdb_info->info, NULL);
++              dsa_fdb_offload_notify(switchdev_work);
+               break;
+       case SWITCHDEV_FDB_DEL_TO_DEVICE:
+-              fdb_info = &switchdev_work->fdb_info;
+-              if (!fdb_info->added_by_user)
+-                      break;
+-
+-              err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid);
++              err = dsa_port_fdb_del(dp, switchdev_work->addr,
++                                     switchdev_work->vid);
+               if (err) {
+-                      netdev_err(dev,
+-                                 "failed to delete %pM vid %d from fdb: %d\n",
+-                                 fdb_info->addr, fdb_info->vid, err);
++                      dev_err(ds->dev,
++                              "port %d failed to delete %pM vid %d from fdb: %d\n",
++                              dp->index, switchdev_work->addr,
++                              switchdev_work->vid, err);
+               }
+               break;
+       }
+       rtnl_unlock();
+-      kfree(switchdev_work->fdb_info.addr);
+       kfree(switchdev_work);
+-      dev_put(dev);
+-}
+-
+-static int
+-dsa_slave_switchdev_fdb_work_init(struct dsa_switchdev_event_work *
+-                                switchdev_work,
+-                                const struct switchdev_notifier_fdb_info *
+-                                fdb_info)
+-{
+-      memcpy(&switchdev_work->fdb_info, fdb_info,
+-             sizeof(switchdev_work->fdb_info));
+-      switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
+-      if (!switchdev_work->fdb_info.addr)
+-              return -ENOMEM;
+-      ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
+-                      fdb_info->addr);
+-      return 0;
++      if (dsa_is_user_port(ds, dp->index))
++              dev_put(dp->slave);
+ }
+ /* Called under rcu_read_lock() */
+@@ -2164,7 +2154,9 @@ static int dsa_slave_switchdev_event(str
+                                    unsigned long event, void *ptr)
+ {
+       struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
++      const struct switchdev_notifier_fdb_info *fdb_info;
+       struct dsa_switchdev_event_work *switchdev_work;
++      struct dsa_port *dp;
+       int err;
+       if (event == SWITCHDEV_PORT_ATTR_SET) {
+@@ -2177,20 +2169,32 @@ static int dsa_slave_switchdev_event(str
+       if (!dsa_slave_dev_check(dev))
+               return NOTIFY_DONE;
++      dp = dsa_slave_to_port(dev);
++
+       switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
+       if (!switchdev_work)
+               return NOTIFY_BAD;
+       INIT_WORK(&switchdev_work->work,
+                 dsa_slave_switchdev_event_work);
+-      switchdev_work->dev = dev;
++      switchdev_work->ds = dp->ds;
++      switchdev_work->port = dp->index;
+       switchdev_work->event = event;
+       switch (event) {
+       case SWITCHDEV_FDB_ADD_TO_DEVICE:
+       case SWITCHDEV_FDB_DEL_TO_DEVICE:
+-              if (dsa_slave_switchdev_fdb_work_init(switchdev_work, ptr))
+-                      goto err_fdb_work_init;
++              fdb_info = ptr;
++
++              if (!fdb_info->added_by_user) {
++                      kfree(switchdev_work);
++                      return NOTIFY_OK;
++              }
++
++              ether_addr_copy(switchdev_work->addr,
++                              fdb_info->addr);
++              switchdev_work->vid = fdb_info->vid;
++
+               dev_hold(dev);
+               break;
+       default:
+@@ -2200,10 +2204,6 @@ static int dsa_slave_switchdev_event(str
+       dsa_schedule_work(&switchdev_work->work);
+       return NOTIFY_OK;
+-
+-err_fdb_work_init:
+-      kfree(switchdev_work);
+-      return NOTIFY_BAD;
+ }
+ static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
diff --git a/target/linux/generic/backport-5.10/723-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch b/target/linux/generic/backport-5.10/723-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch
new file mode 100644 (file)
index 0000000..9131df7
--- /dev/null
@@ -0,0 +1,85 @@
+From 447d290a58bd335d68f665713842365d3d6447df Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 6 Jan 2021 11:51:33 +0200
+Subject: [PATCH] net: dsa: move switchdev event implementation under the same
+ switch/case statement
+
+We'll need to start listening to SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE
+events even for interfaces where dsa_slave_dev_check returns false, so
+we need that check inside the switch-case statement for SWITCHDEV_FDB_*.
+
+This movement also avoids a useless allocation / free of switchdev_work
+on the untreated "default event" case.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ net/dsa/slave.c | 35 ++++++++++++++++-------------------
+ 1 file changed, 16 insertions(+), 19 deletions(-)
+
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -2159,31 +2159,29 @@ static int dsa_slave_switchdev_event(str
+       struct dsa_port *dp;
+       int err;
+-      if (event == SWITCHDEV_PORT_ATTR_SET) {
++      switch (event) {
++      case SWITCHDEV_PORT_ATTR_SET:
+               err = switchdev_handle_port_attr_set(dev, ptr,
+                                                    dsa_slave_dev_check,
+                                                    dsa_slave_port_attr_set);
+               return notifier_from_errno(err);
+-      }
+-
+-      if (!dsa_slave_dev_check(dev))
+-              return NOTIFY_DONE;
++      case SWITCHDEV_FDB_ADD_TO_DEVICE:
++      case SWITCHDEV_FDB_DEL_TO_DEVICE:
++              if (!dsa_slave_dev_check(dev))
++                      return NOTIFY_DONE;
+-      dp = dsa_slave_to_port(dev);
++              dp = dsa_slave_to_port(dev);
+-      switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
+-      if (!switchdev_work)
+-              return NOTIFY_BAD;
+-
+-      INIT_WORK(&switchdev_work->work,
+-                dsa_slave_switchdev_event_work);
+-      switchdev_work->ds = dp->ds;
+-      switchdev_work->port = dp->index;
+-      switchdev_work->event = event;
++              switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
++              if (!switchdev_work)
++                      return NOTIFY_BAD;
++
++              INIT_WORK(&switchdev_work->work,
++                        dsa_slave_switchdev_event_work);
++              switchdev_work->ds = dp->ds;
++              switchdev_work->port = dp->index;
++              switchdev_work->event = event;
+-      switch (event) {
+-      case SWITCHDEV_FDB_ADD_TO_DEVICE:
+-      case SWITCHDEV_FDB_DEL_TO_DEVICE:
+               fdb_info = ptr;
+               if (!fdb_info->added_by_user) {
+@@ -2196,13 +2194,12 @@ static int dsa_slave_switchdev_event(str
+               switchdev_work->vid = fdb_info->vid;
+               dev_hold(dev);
++              dsa_schedule_work(&switchdev_work->work);
+               break;
+       default:
+-              kfree(switchdev_work);
+               return NOTIFY_DONE;
+       }
+-      dsa_schedule_work(&switchdev_work->work);
+       return NOTIFY_OK;
+ }
diff --git a/target/linux/generic/backport-5.10/724-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch b/target/linux/generic/backport-5.10/724-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch
new file mode 100644 (file)
index 0000000..b7b6ebe
--- /dev/null
@@ -0,0 +1,42 @@
+From 5fb4a451a87d8ed3363d28b63a3295399373d6c4 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 6 Jan 2021 11:51:34 +0200
+Subject: [PATCH] net: dsa: exit early in dsa_slave_switchdev_event if we can't
+ program the FDB
+
+Right now, the following would happen for a switch driver that does not
+implement .port_fdb_add or .port_fdb_del.
+
+dsa_slave_switchdev_event returns NOTIFY_OK and schedules:
+-> dsa_slave_switchdev_event_work
+   -> dsa_port_fdb_add
+      -> dsa_port_notify(DSA_NOTIFIER_FDB_ADD)
+         -> dsa_switch_fdb_add
+            -> if (!ds->ops->port_fdb_add) return -EOPNOTSUPP;
+   -> an error is printed with dev_dbg, and
+      dsa_fdb_offload_notify(switchdev_work) is not called.
+
+We can avoid scheduling the worker for nothing and say NOTIFY_DONE.
+Because we don't call dsa_fdb_offload_notify, the static FDB entry will
+remain just in the software bridge.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ net/dsa/slave.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -2172,6 +2172,9 @@ static int dsa_slave_switchdev_event(str
+               dp = dsa_slave_to_port(dev);
++              if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del)
++                      return NOTIFY_DONE;
++
+               switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
+               if (!switchdev_work)
+                       return NOTIFY_BAD;
diff --git a/target/linux/generic/backport-5.10/725-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch b/target/linux/generic/backport-5.10/725-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch
new file mode 100644 (file)
index 0000000..e7b9af1
--- /dev/null
@@ -0,0 +1,264 @@
+From d5f19486cee79d04c054427577ac96ed123706db Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 6 Jan 2021 11:51:35 +0200
+Subject: [PATCH] net: dsa: listen for SWITCHDEV_{FDB,DEL}_ADD_TO_DEVICE on
+ foreign bridge neighbors
+
+Some DSA switches (and not only) cannot learn source MAC addresses from
+packets injected from the CPU. They only perform hardware address
+learning from inbound traffic.
+
+This can be problematic when we have a bridge spanning some DSA switch
+ports and some non-DSA ports (which we'll call "foreign interfaces" from
+DSA's perspective).
+
+There are 2 classes of problems created by the lack of learning on
+CPU-injected traffic:
+- excessive flooding, due to the fact that DSA treats those addresses as
+  unknown
+- the risk of stale routes, which can lead to temporary packet loss
+
+To illustrate the second class, consider the following situation, which
+is common in production equipment (wireless access points, where there
+is a WLAN interface and an Ethernet switch, and these form a single
+bridging domain).
+
+ AP 1:
+ +------------------------------------------------------------------------+
+ |                                          br0                           |
+ +------------------------------------------------------------------------+
+ +------------+ +------------+ +------------+ +------------+ +------------+
+ |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
+ +------------+ +------------+ +------------+ +------------+ +------------+
+       |                                                       ^        ^
+       |                                                       |        |
+       |                                                       |        |
+       |                                                    Client A  Client B
+       |
+       |
+       |
+ +------------+ +------------+ +------------+ +------------+ +------------+
+ |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
+ +------------+ +------------+ +------------+ +------------+ +------------+
+ +------------------------------------------------------------------------+
+ |                                          br0                           |
+ +------------------------------------------------------------------------+
+ AP 2
+
+- br0 of AP 1 will know that Clients A and B are reachable via wlan0
+- the hardware fdb of a DSA switch driver today is not kept in sync with
+  the software entries on other bridge ports, so it will not know that
+  clients A and B are reachable via the CPU port UNLESS the hardware
+  switch itself performs SA learning from traffic injected from the CPU.
+  Nonetheless, a substantial number of switches don't.
+- the hardware fdb of the DSA switch on AP 2 may autonomously learn that
+  Client A and B are reachable through swp0. Therefore, the software br0
+  of AP 2 also may or may not learn this. In the example we're
+  illustrating, some Ethernet traffic has been going on, and br0 from AP
+  2 has indeed learnt that it can reach Client B through swp0.
+
+One of the wireless clients, say Client B, disconnects from AP 1 and
+roams to AP 2. The topology now looks like this:
+
+ AP 1:
+ +------------------------------------------------------------------------+
+ |                                          br0                           |
+ +------------------------------------------------------------------------+
+ +------------+ +------------+ +------------+ +------------+ +------------+
+ |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
+ +------------+ +------------+ +------------+ +------------+ +------------+
+       |                                                            ^
+       |                                                            |
+       |                                                         Client A
+       |
+       |
+       |                                                         Client B
+       |                                                            |
+       |                                                            v
+ +------------+ +------------+ +------------+ +------------+ +------------+
+ |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
+ +------------+ +------------+ +------------+ +------------+ +------------+
+ +------------------------------------------------------------------------+
+ |                                          br0                           |
+ +------------------------------------------------------------------------+
+ AP 2
+
+- br0 of AP 1 still knows that Client A is reachable via wlan0 (no change)
+- br0 of AP 1 will (possibly) know that Client B has left wlan0. There
+  are cases where it might never find out though. Either way, DSA today
+  does not process that notification in any way.
+- the hardware FDB of the DSA switch on AP 1 may learn autonomously that
+  Client B can be reached via swp0, if it receives any packet with
+  Client 1's source MAC address over Ethernet.
+- the hardware FDB of the DSA switch on AP 2 still thinks that Client B
+  can be reached via swp0. It does not know that it has roamed to wlan0,
+  because it doesn't perform SA learning from the CPU port.
+
+Now Client A contacts Client B.
+AP 1 routes the packet fine towards swp0 and delivers it on the Ethernet
+segment.
+AP 2 sees a frame on swp0 and its fdb says that the destination is swp0.
+Hairpinning is disabled => drop.
+
+This problem comes from the fact that these switches have a 'blind spot'
+for addresses coming from software bridging. The generic solution is not
+to assume that hardware learning can be enabled somehow, but to listen
+to more bridge learning events. It turns out that the bridge driver does
+learn in software from all inbound frames, in __br_handle_local_finish.
+A proper SWITCHDEV_FDB_ADD_TO_DEVICE notification is emitted for the
+addresses serviced by the bridge on 'foreign' interfaces. The software
+bridge also does the right thing on migration, by notifying that the old
+entry is deleted, so that does not need to be special-cased in DSA. When
+it is deleted, we just need to delete our static FDB entry towards the
+CPU too, and wait.
+
+The problem is that DSA currently only cares about SWITCHDEV_FDB_ADD_TO_DEVICE
+events received on its own interfaces, such as static FDB entries.
+
+Luckily we can change that, and DSA can listen to all switchdev FDB
+add/del events in the system and figure out if those events were emitted
+by a bridge that spans at least one of DSA's own ports. In case that is
+true, DSA will also offload that address towards its own CPU port, in
+the eventuality that there might be bridge clients attached to the DSA
+switch who want to talk to the station connected to the foreign
+interface.
+
+In terms of implementation, we need to keep the fdb_info->added_by_user
+check for the case where the switchdev event was targeted directly at a
+DSA switch port. But we don't need to look at that flag for snooped
+events. So the check is currently too late, we need to move it earlier.
+This also simplifies the code a bit, since we avoid uselessly allocating
+and freeing switchdev_work.
+
+We could probably do some improvements in the future. For example,
+multi-bridge support is rudimentary at the moment. If there are two
+bridges spanning a DSA switch's ports, and both of them need to service
+the same MAC address, then what will happen is that the migration of one
+of those stations will trigger the deletion of the FDB entry from the
+CPU port while it is still used by other bridge. That could be improved
+with reference counting but is left for another time.
+
+This behavior needs to be enabled at driver level by setting
+ds->assisted_learning_on_cpu_port = true. This is because we don't want
+to inflict a potential performance penalty (accesses through
+MDIO/I2C/SPI are expensive) to hardware that really doesn't need it
+because address learning on the CPU port works there.
+
+Reported-by: DENG Qingfang <dqfext@gmail.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/net/dsa.h |  5 +++++
+ net/dsa/slave.c   | 66 +++++++++++++++++++++++++++++++++++++++++++++----------
+ 2 files changed, 60 insertions(+), 11 deletions(-)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -317,6 +317,11 @@ struct dsa_switch {
+        */
+       bool                    untag_bridge_pvid;
++      /* Let DSA manage the FDB entries towards the CPU, based on the
++       * software bridge database.
++       */
++      bool                    assisted_learning_on_cpu_port;
++
+       /* In case vlan_filtering_is_global is set, the VLAN awareness state
+        * should be retrieved from here and not from the per-port settings.
+        */
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -2149,6 +2149,28 @@ static void dsa_slave_switchdev_event_wo
+               dev_put(dp->slave);
+ }
++static int dsa_lower_dev_walk(struct net_device *lower_dev,
++                            struct netdev_nested_priv *priv)
++{
++      if (dsa_slave_dev_check(lower_dev)) {
++              priv->data = (void *)netdev_priv(lower_dev);
++              return 1;
++      }
++
++      return 0;
++}
++
++static struct dsa_slave_priv *dsa_slave_dev_lower_find(struct net_device *dev)
++{
++      struct netdev_nested_priv priv = {
++              .data = NULL,
++      };
++
++      netdev_walk_all_lower_dev_rcu(dev, dsa_lower_dev_walk, &priv);
++
++      return (struct dsa_slave_priv *)priv.data;
++}
++
+ /* Called under rcu_read_lock() */
+ static int dsa_slave_switchdev_event(struct notifier_block *unused,
+                                    unsigned long event, void *ptr)
+@@ -2167,10 +2189,37 @@ static int dsa_slave_switchdev_event(str
+               return notifier_from_errno(err);
+       case SWITCHDEV_FDB_ADD_TO_DEVICE:
+       case SWITCHDEV_FDB_DEL_TO_DEVICE:
+-              if (!dsa_slave_dev_check(dev))
+-                      return NOTIFY_DONE;
++              fdb_info = ptr;
++
++              if (dsa_slave_dev_check(dev)) {
++                      if (!fdb_info->added_by_user)
++                              return NOTIFY_OK;
++
++                      dp = dsa_slave_to_port(dev);
++              } else {
++                      /* Snoop addresses learnt on foreign interfaces
++                       * bridged with us, for switches that don't
++                       * automatically learn SA from CPU-injected traffic
++                       */
++                      struct net_device *br_dev;
++                      struct dsa_slave_priv *p;
++
++                      br_dev = netdev_master_upper_dev_get_rcu(dev);
++                      if (!br_dev)
++                              return NOTIFY_DONE;
++
++                      if (!netif_is_bridge_master(br_dev))
++                              return NOTIFY_DONE;
++
++                      p = dsa_slave_dev_lower_find(br_dev);
++                      if (!p)
++                              return NOTIFY_DONE;
+-              dp = dsa_slave_to_port(dev);
++                      dp = p->dp->cpu_dp;
++
++                      if (!dp->ds->assisted_learning_on_cpu_port)
++                              return NOTIFY_DONE;
++              }
+               if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del)
+                       return NOTIFY_DONE;
+@@ -2185,18 +2234,13 @@ static int dsa_slave_switchdev_event(str
+               switchdev_work->port = dp->index;
+               switchdev_work->event = event;
+-              fdb_info = ptr;
+-
+-              if (!fdb_info->added_by_user) {
+-                      kfree(switchdev_work);
+-                      return NOTIFY_OK;
+-              }
+-
+               ether_addr_copy(switchdev_work->addr,
+                               fdb_info->addr);
+               switchdev_work->vid = fdb_info->vid;
+-              dev_hold(dev);
++              /* Hold a reference on the slave for dsa_fdb_offload_notify */
++              if (dsa_is_user_port(dp->ds, dp->index))
++                      dev_hold(dev);
+               dsa_schedule_work(&switchdev_work->work);
+               break;
+       default:
diff --git a/target/linux/generic/backport-5.10/730-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch b/target/linux/generic/backport-5.10/730-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch
new file mode 100644 (file)
index 0000000..f3a6f94
--- /dev/null
@@ -0,0 +1,84 @@
+From c3b8e07909dbe67b0d580416c1a5257643a73be7 Mon Sep 17 00:00:00 2001
+From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Date: Fri, 12 Mar 2021 00:07:03 -0800
+Subject: [PATCH] net: dsa: mt7530: setup core clock even in TRGMII mode
+
+A recent change to MIPS ralink reset logic made it so mt7530 actually
+resets the switch on platforms such as mt7621 (where bit 2 is the reset
+line for the switch). That exposed an issue where the switch would not
+function properly in TRGMII mode after a reset.
+
+Reconfigure core clock in TRGMII mode to fix the issue.
+
+Tested on Ubiquiti ER-X (MT7621) with TRGMII mode enabled.
+
+Fixes: 3f9ef7785a9c ("MIPS: ralink: manage low reset lines")
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mt7530.c | 52 +++++++++++++++++++---------------------
+ 1 file changed, 25 insertions(+), 27 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -436,34 +436,32 @@ mt7530_pad_clk_setup(struct dsa_switch *
+                            TD_DM_DRVP(8) | TD_DM_DRVN(8));
+       /* Setup core clock for MT7530 */
+-      if (!trgint) {
+-              /* Disable MT7530 core clock */
+-              core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
+-
+-              /* Disable PLL, since phy_device has not yet been created
+-               * provided for phy_[read,write]_mmd_indirect is called, we
+-               * provide our own core_write_mmd_indirect to complete this
+-               * function.
+-               */
+-              core_write_mmd_indirect(priv,
+-                                      CORE_GSWPLL_GRP1,
+-                                      MDIO_MMD_VEND2,
+-                                      0);
+-
+-              /* Set core clock into 500Mhz */
+-              core_write(priv, CORE_GSWPLL_GRP2,
+-                         RG_GSWPLL_POSDIV_500M(1) |
+-                         RG_GSWPLL_FBKDIV_500M(25));
+-
+-              /* Enable PLL */
+-              core_write(priv, CORE_GSWPLL_GRP1,
+-                         RG_GSWPLL_EN_PRE |
+-                         RG_GSWPLL_POSDIV_200M(2) |
+-                         RG_GSWPLL_FBKDIV_200M(32));
+-
+-              /* Enable MT7530 core clock */
+-              core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
+-      }
++      /* Disable MT7530 core clock */
++      core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
++
++      /* Disable PLL, since phy_device has not yet been created
++       * provided for phy_[read,write]_mmd_indirect is called, we
++       * provide our own core_write_mmd_indirect to complete this
++       * function.
++       */
++      core_write_mmd_indirect(priv,
++                              CORE_GSWPLL_GRP1,
++                              MDIO_MMD_VEND2,
++                              0);
++
++      /* Set core clock into 500Mhz */
++      core_write(priv, CORE_GSWPLL_GRP2,
++                 RG_GSWPLL_POSDIV_500M(1) |
++                 RG_GSWPLL_FBKDIV_500M(25));
++
++      /* Enable PLL */
++      core_write(priv, CORE_GSWPLL_GRP1,
++                 RG_GSWPLL_EN_PRE |
++                 RG_GSWPLL_POSDIV_200M(2) |
++                 RG_GSWPLL_FBKDIV_200M(32));
++
++      /* Enable MT7530 core clock */
++      core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
+       /* Setup the MT7530 TRGMII Tx Clock */
+       core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
diff --git a/target/linux/generic/backport-5.10/730-net-phy-at803x-select-correct-page-on-config-init.patch b/target/linux/generic/backport-5.10/730-net-phy-at803x-select-correct-page-on-config-init.patch
deleted file mode 100644 (file)
index 00be403..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-From c329e5afb42ff0a88285eb4d8a391a18793e4777 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 15 Apr 2021 03:26:50 +0200
-Subject: [PATCH] net: phy: at803x: select correct page on config init
-
-The Atheros AR8031 and AR8033 expose different registers for SGMII/Fiber
-as well as the copper side of the PHY depending on the BT_BX_REG_SEL bit
-in the chip configure register.
-
-The driver assumes the copper side is selected on probe, but this might
-not be the case depending which page was last selected by the
-bootloader. Notably, Ubiquiti UniFi bootloaders show this behavior.
-
-Select the copper page when probing to circumvent this.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 50 +++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 49 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -139,6 +139,9 @@
- #define ATH8035_PHY_ID 0x004dd072
- #define AT8030_PHY_ID_MASK                    0xffffffef
-+#define AT803X_PAGE_FIBER             0
-+#define AT803X_PAGE_COPPER            1
-+
- MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-@@ -190,6 +193,35 @@ static int at803x_debug_reg_mask(struct
-       return phy_write(phydev, AT803X_DEBUG_DATA, val);
- }
-+static int at803x_write_page(struct phy_device *phydev, int page)
-+{
-+      int mask;
-+      int set;
-+
-+      if (page == AT803X_PAGE_COPPER) {
-+              set = AT803X_BT_BX_REG_SEL;
-+              mask = 0;
-+      } else {
-+              set = 0;
-+              mask = AT803X_BT_BX_REG_SEL;
-+      }
-+
-+      return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set);
-+}
-+
-+static int at803x_read_page(struct phy_device *phydev)
-+{
-+      int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG);
-+
-+      if (ccr < 0)
-+              return ccr;
-+
-+      if (ccr & AT803X_BT_BX_REG_SEL)
-+              return AT803X_PAGE_COPPER;
-+
-+      return AT803X_PAGE_FIBER;
-+}
-+
- static int at803x_enable_rx_delay(struct phy_device *phydev)
- {
-       return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
-@@ -508,6 +540,7 @@ static int at803x_probe(struct phy_devic
- {
-       struct device *dev = &phydev->mdio.dev;
-       struct at803x_priv *priv;
-+      int ret;
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-@@ -515,7 +548,20 @@ static int at803x_probe(struct phy_devic
-       phydev->priv = priv;
--      return at803x_parse_dt(phydev);
-+      ret = at803x_parse_dt(phydev);
-+      if (ret)
-+              return ret;
-+
-+      /* Some bootloaders leave the fiber page selected.
-+       * Switch to the copper page, as otherwise we read
-+       * the PHY capabilities from the fiber side.
-+       */
-+      if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) {
-+              ret = phy_select_page(phydev, AT803X_PAGE_COPPER);
-+              ret = phy_restore_page(phydev, AT803X_PAGE_COPPER, ret);
-+      }
-+
-+      return ret;
- }
- static void at803x_remove(struct phy_device *phydev)
-@@ -1097,6 +1143,8 @@ static struct phy_driver at803x_driver[]
-       .get_wol                = at803x_get_wol,
-       .suspend                = at803x_suspend,
-       .resume                 = at803x_resume,
-+      .read_page              = at803x_read_page,
-+      .write_page             = at803x_write_page,
-       /* PHY_GBIT_FEATURES */
-       .read_status            = at803x_read_status,
-       .aneg_done              = at803x_aneg_done,
diff --git a/target/linux/generic/backport-5.10/731-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch b/target/linux/generic/backport-5.10/731-net-phy-at803x-fix-probe-error-if-copper-page-is-sel.patch
deleted file mode 100644 (file)
index d6ec745..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-From 8f7e876273e294b732b42af2e5e6bba91d798954 Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Tue, 20 Apr 2021 12:29:29 +0200
-Subject: [PATCH] net: phy: at803x: fix probe error if copper page is selected
-
-The commit c329e5afb42f ("net: phy: at803x: select correct page on
-config init") selects the copper page during probe. This fails if the
-copper page was already selected. In this case, the value of the copper
-page (which is 1) is propagated through phy_restore_page() and is
-finally returned for at803x_probe(). Fix it, by just using the
-at803x_page_write() directly.
-
-Also in case of an error, the regulator is not disabled and leads to a
-WARN_ON() when the probe fails. This couldn't happen before, because
-at803x_parse_dt() was the last call in at803x_probe(). It is hard to
-see, that the parse_dt() actually enables the regulator. Thus move the
-regulator_enable() to the probe function and undo it in case of an
-error.
-
-Fixes: c329e5afb42f ("net: phy: at803x: select correct page on config init")
-Signed-off-by: Michael Walle <michael@walle.cc>
-Reviewed-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 23 +++++++++++++++++------
- 1 file changed, 17 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -527,10 +527,6 @@ static int at803x_parse_dt(struct phy_de
-                       phydev_err(phydev, "failed to get VDDIO regulator\n");
-                       return PTR_ERR(priv->vddio);
-               }
--
--              ret = regulator_enable(priv->vddio);
--              if (ret < 0)
--                      return ret;
-       }
-       return 0;
-@@ -552,15 +548,30 @@ static int at803x_probe(struct phy_devic
-       if (ret)
-               return ret;
-+      if (priv->vddio) {
-+              ret = regulator_enable(priv->vddio);
-+              if (ret < 0)
-+                      return ret;
-+      }
-+
-       /* Some bootloaders leave the fiber page selected.
-        * Switch to the copper page, as otherwise we read
-        * the PHY capabilities from the fiber side.
-        */
-       if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) {
--              ret = phy_select_page(phydev, AT803X_PAGE_COPPER);
--              ret = phy_restore_page(phydev, AT803X_PAGE_COPPER, ret);
-+              phy_lock_mdio_bus(phydev);
-+              ret = at803x_write_page(phydev, AT803X_PAGE_COPPER);
-+              phy_unlock_mdio_bus(phydev);
-+              if (ret)
-+                      goto err;
-       }
-+      return 0;
-+
-+err:
-+      if (priv->vddio)
-+              regulator_disable(priv->vddio);
-+
-       return ret;
- }
diff --git a/target/linux/generic/backport-5.10/731-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch b/target/linux/generic/backport-5.10/731-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch
new file mode 100644 (file)
index 0000000..9e5047a
--- /dev/null
@@ -0,0 +1,181 @@
+From 429a0edeefd88cbfca5c417dfb8561047bb50769 Mon Sep 17 00:00:00 2001
+From: DENG Qingfang <dqfext@gmail.com>
+Date: Mon, 25 Jan 2021 12:43:22 +0800
+Subject: [PATCH] net: dsa: mt7530: MT7530 optional GPIO support
+
+MT7530's LED controller can drive up to 15 LED/GPIOs.
+
+Add support for GPIO control and allow users to use its GPIOs by
+setting gpio-controller property in device tree.
+
+Signed-off-by: DENG Qingfang <dqfext@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/mt7530.c | 110 +++++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/mt7530.h |  20 +++++++
+ 2 files changed, 130 insertions(+)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -18,6 +18,7 @@
+ #include <linux/regulator/consumer.h>
+ #include <linux/reset.h>
+ #include <linux/gpio/consumer.h>
++#include <linux/gpio/driver.h>
+ #include <net/dsa.h>
+ #include "mt7530.h"
+@@ -1534,6 +1535,109 @@ mtk_get_tag_protocol(struct dsa_switch *
+       }
+ }
++static inline u32
++mt7530_gpio_to_bit(unsigned int offset)
++{
++      /* Map GPIO offset to register bit
++       * [ 2: 0]  port 0 LED 0..2 as GPIO 0..2
++       * [ 6: 4]  port 1 LED 0..2 as GPIO 3..5
++       * [10: 8]  port 2 LED 0..2 as GPIO 6..8
++       * [14:12]  port 3 LED 0..2 as GPIO 9..11
++       * [18:16]  port 4 LED 0..2 as GPIO 12..14
++       */
++      return BIT(offset + offset / 3);
++}
++
++static int
++mt7530_gpio_get(struct gpio_chip *gc, unsigned int offset)
++{
++      struct mt7530_priv *priv = gpiochip_get_data(gc);
++      u32 bit = mt7530_gpio_to_bit(offset);
++
++      return !!(mt7530_read(priv, MT7530_LED_GPIO_DATA) & bit);
++}
++
++static void
++mt7530_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
++{
++      struct mt7530_priv *priv = gpiochip_get_data(gc);
++      u32 bit = mt7530_gpio_to_bit(offset);
++
++      if (value)
++              mt7530_set(priv, MT7530_LED_GPIO_DATA, bit);
++      else
++              mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit);
++}
++
++static int
++mt7530_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
++{
++      struct mt7530_priv *priv = gpiochip_get_data(gc);
++      u32 bit = mt7530_gpio_to_bit(offset);
++
++      return (mt7530_read(priv, MT7530_LED_GPIO_DIR) & bit) ?
++              GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
++}
++
++static int
++mt7530_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
++{
++      struct mt7530_priv *priv = gpiochip_get_data(gc);
++      u32 bit = mt7530_gpio_to_bit(offset);
++
++      mt7530_clear(priv, MT7530_LED_GPIO_OE, bit);
++      mt7530_clear(priv, MT7530_LED_GPIO_DIR, bit);
++
++      return 0;
++}
++
++static int
++mt7530_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value)
++{
++      struct mt7530_priv *priv = gpiochip_get_data(gc);
++      u32 bit = mt7530_gpio_to_bit(offset);
++
++      mt7530_set(priv, MT7530_LED_GPIO_DIR, bit);
++
++      if (value)
++              mt7530_set(priv, MT7530_LED_GPIO_DATA, bit);
++      else
++              mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit);
++
++      mt7530_set(priv, MT7530_LED_GPIO_OE, bit);
++
++      return 0;
++}
++
++static int
++mt7530_setup_gpio(struct mt7530_priv *priv)
++{
++      struct device *dev = priv->dev;
++      struct gpio_chip *gc;
++
++      gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
++      if (!gc)
++              return -ENOMEM;
++
++      mt7530_write(priv, MT7530_LED_GPIO_OE, 0);
++      mt7530_write(priv, MT7530_LED_GPIO_DIR, 0);
++      mt7530_write(priv, MT7530_LED_IO_MODE, 0);
++
++      gc->label = "mt7530";
++      gc->parent = dev;
++      gc->owner = THIS_MODULE;
++      gc->get_direction = mt7530_gpio_get_direction;
++      gc->direction_input = mt7530_gpio_direction_input;
++      gc->direction_output = mt7530_gpio_direction_output;
++      gc->get = mt7530_gpio_get;
++      gc->set = mt7530_gpio_set;
++      gc->base = -1;
++      gc->ngpio = 15;
++      gc->can_sleep = true;
++
++      return devm_gpiochip_add_data(dev, gc, priv);
++}
++
+ static int
+ mt7530_setup(struct dsa_switch *ds)
+ {
+@@ -1675,6 +1779,12 @@ mt7530_setup(struct dsa_switch *ds)
+               }
+       }
++      if (of_property_read_bool(priv->dev->of_node, "gpio-controller")) {
++              ret = mt7530_setup_gpio(priv);
++              if (ret)
++                      return ret;
++      }
++
+       mt7530_setup_port5(ds, interface);
+       /* Flush the FDB table */
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -529,6 +529,26 @@ enum mt7531_clk_skew {
+ #define  MT7531_GPIO12_RG_RXD3_MASK   GENMASK(19, 16)
+ #define  MT7531_EXT_P_MDIO_12         (2 << 16)
++/* Registers for LED GPIO control (MT7530 only)
++ * All registers follow this pattern:
++ * [ 2: 0]  port 0
++ * [ 6: 4]  port 1
++ * [10: 8]  port 2
++ * [14:12]  port 3
++ * [18:16]  port 4
++ */
++
++/* LED enable, 0: Disable, 1: Enable (Default) */
++#define MT7530_LED_EN                 0x7d00
++/* LED mode, 0: GPIO mode, 1: PHY mode (Default) */
++#define MT7530_LED_IO_MODE            0x7d04
++/* GPIO direction, 0: Input, 1: Output */
++#define MT7530_LED_GPIO_DIR           0x7d10
++/* GPIO output enable, 0: Disable, 1: Enable */
++#define MT7530_LED_GPIO_OE            0x7d14
++/* GPIO value, 0: Low, 1: High */
++#define MT7530_LED_GPIO_DATA          0x7d18
++
+ #define MT7530_CREV                   0x7ffc
+ #define  CHIP_NAME_SHIFT              16
+ #define  MT7530_ID                    0x7530
diff --git a/target/linux/generic/backport-5.10/731-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch b/target/linux/generic/backport-5.10/731-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch
new file mode 100644 (file)
index 0000000..38dd8a7
--- /dev/null
@@ -0,0 +1,120 @@
+From 40b5d2f15c091fa9c854acde91ad2acb504027d7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
+Date: Mon, 12 Apr 2021 08:50:31 +0200
+Subject: [PATCH] net: dsa: mt7530: Add support for EEE features
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch adds EEE support.
+
+Signed-off-by: René van Dorst <opensource@vdorst.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mt7530.c | 43 ++++++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/mt7530.h | 14 ++++++++++++-
+ 2 files changed, 56 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2371,6 +2371,17 @@ static void mt753x_phylink_mac_link_up(s
+                       mcr |= PMCR_RX_FC_EN;
+       }
++      if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, 0) >= 0) {
++              switch (speed) {
++              case SPEED_1000:
++                      mcr |= PMCR_FORCE_EEE1G;
++                      break;
++              case SPEED_100:
++                      mcr |= PMCR_FORCE_EEE100;
++                      break;
++              }
++      }
++
+       mt7530_set(priv, MT7530_PMCR_P(port), mcr);
+ }
+@@ -2601,6 +2612,36 @@ mt753x_phy_write(struct dsa_switch *ds,
+       return priv->info->phy_write(ds, port, regnum, val);
+ }
++static int mt753x_get_mac_eee(struct dsa_switch *ds, int port,
++                            struct ethtool_eee *e)
++{
++      struct mt7530_priv *priv = ds->priv;
++      u32 eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port));
++
++      e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN);
++      e->tx_lpi_timer = GET_LPI_THRESH(eeecr);
++
++      return 0;
++}
++
++static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
++                            struct ethtool_eee *e)
++{
++      struct mt7530_priv *priv = ds->priv;
++      u32 set, mask = LPI_THRESH_MASK | LPI_MODE_EN;
++
++      if (e->tx_lpi_timer > 0xFFF)
++              return -EINVAL;
++
++      set = SET_LPI_THRESH(e->tx_lpi_timer);
++      if (!e->tx_lpi_enabled)
++              /* Force LPI Mode without a delay */
++              set |= LPI_MODE_EN;
++      mt7530_rmw(priv, MT7530_PMEEECR_P(port), mask, set);
++
++      return 0;
++}
++
+ static const struct dsa_switch_ops mt7530_switch_ops = {
+       .get_tag_protocol       = mtk_get_tag_protocol,
+       .setup                  = mt753x_setup,
+@@ -2629,6 +2670,8 @@ static const struct dsa_switch_ops mt753
+       .phylink_mac_an_restart = mt753x_phylink_mac_an_restart,
+       .phylink_mac_link_down  = mt753x_phylink_mac_link_down,
+       .phylink_mac_link_up    = mt753x_phylink_mac_link_up,
++      .get_mac_eee            = mt753x_get_mac_eee,
++      .set_mac_eee            = mt753x_set_mac_eee,
+ };
+ static const struct mt753x_info mt753x_table[] = {
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -240,6 +240,8 @@ enum mt7530_vlan_port_attr {
+ #define  PMCR_RX_EN                   BIT(13)
+ #define  PMCR_BACKOFF_EN              BIT(9)
+ #define  PMCR_BACKPR_EN                       BIT(8)
++#define  PMCR_FORCE_EEE1G             BIT(7)
++#define  PMCR_FORCE_EEE100            BIT(6)
+ #define  PMCR_TX_FC_EN                        BIT(5)
+ #define  PMCR_RX_FC_EN                        BIT(4)
+ #define  PMCR_FORCE_SPEED_1000                BIT(3)
+@@ -264,7 +266,8 @@ enum mt7530_vlan_port_attr {
+ #define  PMCR_LINK_SETTINGS_MASK      (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
+                                        PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
+                                        PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
+-                                       PMCR_FORCE_FDX | PMCR_FORCE_LNK)
++                                       PMCR_FORCE_FDX | PMCR_FORCE_LNK | \
++                                       PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100)
+ #define  PMCR_CPU_PORT_SETTING(id)    (PMCR_FORCE_MODE_ID((id)) | \
+                                        PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
+                                        PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
+@@ -273,6 +276,15 @@ enum mt7530_vlan_port_attr {
+                                        PMCR_FORCE_SPEED_1000 | \
+                                        PMCR_FORCE_FDX | PMCR_FORCE_LNK)
++#define MT7530_PMEEECR_P(x)           (0x3004 + (x) * 0x100)
++#define  WAKEUP_TIME_1000(x)          (((x) & 0xFF) << 24)
++#define  WAKEUP_TIME_100(x)           (((x) & 0xFF) << 16)
++#define  LPI_THRESH_MASK              GENMASK(15, 4)
++#define  LPI_THRESH_SHT                       4
++#define  SET_LPI_THRESH(x)            (((x) << LPI_THRESH_SHT) & LPI_THRESH_MASK)
++#define  GET_LPI_THRESH(x)            (((x) & LPI_THRESH_MASK) >> LPI_THRESH_SHT)
++#define  LPI_MODE_EN                  BIT(0)
++
+ #define MT7530_PMSR_P(x)              (0x3008 + (x) * 0x100)
+ #define  PMSR_EEE1G                   BIT(7)
+ #define  PMSR_EEE100M                 BIT(6)
diff --git a/target/linux/generic/backport-5.10/732-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/target/linux/generic/backport-5.10/732-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch
new file mode 100644 (file)
index 0000000..8e242bf
--- /dev/null
@@ -0,0 +1,1935 @@
+From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Mon, 12 Apr 2021 19:47:17 +0200
+Subject: of: net: pass the dst buffer to of_get_mac_address()
+
+of_get_mac_address() returns a "const void*" pointer to a MAC address.
+Lately, support to fetch the MAC address by an NVMEM provider was added.
+But this will only work with platform devices. It will not work with
+PCI devices (e.g. of an integrated root complex) and esp. not with DSA
+ports.
+
+There is an of_* variant of the nvmem binding which works without
+devices. The returned data of a nvmem_cell_read() has to be freed after
+use. On the other hand the return of_get_mac_address() points to some
+static data without a lifetime. The trick for now, was to allocate a
+device resource managed buffer which is then returned. This will only
+work if we have an actual device.
+
+Change it, so that the caller of of_get_mac_address() has to supply a
+buffer where the MAC address is written to. Unfortunately, this will
+touch all drivers which use the of_get_mac_address().
+
+Usually the code looks like:
+
+  const char *addr;
+  addr = of_get_mac_address(np);
+  if (!IS_ERR(addr))
+    ether_addr_copy(ndev->dev_addr, addr);
+
+This can then be simply rewritten as:
+
+  of_get_mac_address(np, ndev->dev_addr);
+
+Sometimes is_valid_ether_addr() is used to test the MAC address.
+of_get_mac_address() already makes sure, it just returns a valid MAC
+address. Thus we can just test its return code. But we have to be
+careful if there are still other sources for the MAC address before the
+of_get_mac_address(). In this case we have to keep the
+is_valid_ether_addr() call.
+
+The following coccinelle patch was used to convert common cases to the
+new style. Afterwards, I've manually gone over the drivers and fixed the
+return code variable: either used a new one or if one was already
+available use that. Mansour Moufid, thanks for that coccinelle patch!
+
+<spml>
+@a@
+identifier x;
+expression y, z;
+@@
+- x = of_get_mac_address(y);
++ x = of_get_mac_address(y, z);
+  <...
+- ether_addr_copy(z, x);
+  ...>
+
+@@
+identifier a.x;
+@@
+- if (<+... x ...+>) {}
+
+@@
+identifier a.x;
+@@
+  if (<+... x ...+>) {
+      ...
+  }
+- else {}
+
+@@
+identifier a.x;
+expression e;
+@@
+- if (<+... x ...+>@e)
+-     {}
+- else
++ if (!(e))
+      {...}
+
+@@
+expression x, y, z;
+@@
+- x = of_get_mac_address(y, z);
++ of_get_mac_address(y, z);
+  ... when != x
+</spml>
+
+All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
+compile-time tested.
+
+Suggested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ arch/arm/mach-mvebu/kirkwood.c                     |  3 +-
+ arch/powerpc/sysdev/tsi108_dev.c                   |  5 +-
+ drivers/net/ethernet/aeroflex/greth.c              |  6 +--
+ drivers/net/ethernet/allwinner/sun4i-emac.c        | 10 ++--
+ drivers/net/ethernet/altera/altera_tse_main.c      |  7 +--
+ drivers/net/ethernet/arc/emac_main.c               |  8 +--
+ drivers/net/ethernet/atheros/ag71xx.c              |  7 +--
+ drivers/net/ethernet/broadcom/bcm4908_enet.c       |  7 +--
+ drivers/net/ethernet/broadcom/bcmsysport.c         |  7 +--
+ drivers/net/ethernet/broadcom/bgmac-bcma.c         | 10 ++--
+ drivers/net/ethernet/broadcom/bgmac-platform.c     | 11 ++--
+ drivers/net/ethernet/cadence/macb_main.c           | 11 ++--
+ drivers/net/ethernet/cavium/octeon/octeon_mgmt.c   |  8 +--
+ drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  5 +-
+ drivers/net/ethernet/davicom/dm9000.c              | 10 ++--
+ drivers/net/ethernet/ethoc.c                       |  6 +--
+ drivers/net/ethernet/ezchip/nps_enet.c             |  7 +--
+ drivers/net/ethernet/freescale/fec_main.c          |  7 +--
+ drivers/net/ethernet/freescale/fec_mpc52xx.c       |  7 +--
+ drivers/net/ethernet/freescale/fman/mac.c          |  9 ++--
+ .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |  5 +-
+ drivers/net/ethernet/freescale/gianfar.c           |  8 +--
+ drivers/net/ethernet/freescale/ucc_geth.c          |  5 +-
+ drivers/net/ethernet/hisilicon/hisi_femac.c        |  7 +--
+ drivers/net/ethernet/hisilicon/hix5hd2_gmac.c      |  7 +--
+ drivers/net/ethernet/lantiq_xrx200.c               |  7 +--
+ drivers/net/ethernet/marvell/mv643xx_eth.c         |  5 +-
+ drivers/net/ethernet/marvell/mvneta.c              |  6 +--
+ .../net/ethernet/marvell/prestera/prestera_main.c  | 11 ++--
+ drivers/net/ethernet/marvell/pxa168_eth.c          |  9 +---
+ drivers/net/ethernet/marvell/sky2.c                |  8 ++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c        | 11 ++--
+ drivers/net/ethernet/micrel/ks8851_common.c        |  7 ++-
+ drivers/net/ethernet/microchip/lan743x_main.c      |  5 +-
+ drivers/net/ethernet/nxp/lpc_eth.c                 |  4 +-
+ drivers/net/ethernet/qualcomm/qca_spi.c            | 10 ++--
+ drivers/net/ethernet/qualcomm/qca_uart.c           |  9 +---
+ drivers/net/ethernet/renesas/ravb_main.c           | 12 +++--
+ drivers/net/ethernet/renesas/sh_eth.c              |  5 +-
+ .../net/ethernet/samsung/sxgbe/sxgbe_platform.c    | 13 ++---
+ drivers/net/ethernet/socionext/sni_ave.c           | 10 ++--
+ .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c  |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 14 ++---
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  2 +-
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c           | 19 ++++---
+ drivers/net/ethernet/ti/cpsw.c                     |  7 +--
+ drivers/net/ethernet/ti/cpsw_new.c                 |  7 +--
+ drivers/net/ethernet/ti/davinci_emac.c             |  8 +--
+ drivers/net/ethernet/ti/netcp_core.c               |  7 +--
+ drivers/net/ethernet/wiznet/w5100-spi.c            |  8 ++-
+ drivers/net/ethernet/wiznet/w5100.c                |  2 +-
+ drivers/net/ethernet/xilinx/ll_temac_main.c        |  8 +--
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c  | 15 +++---
+ drivers/net/ethernet/xilinx/xilinx_emaclite.c      |  8 +--
+ drivers/net/wireless/ath/ath9k/init.c              |  5 +-
+ drivers/net/wireless/mediatek/mt76/eeprom.c        |  9 +---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c     |  6 +--
+ drivers/of/of_net.c                                | 60 ++++++++++------------
+ drivers/staging/octeon/ethernet.c                  | 10 ++--
+ drivers/staging/wfx/main.c                         |  7 ++-
+ include/linux/of_net.h                             |  6 +--
+ include/net/dsa.h                                  |  2 +-
+ net/dsa/dsa2.c                                     |  2 +-
+ net/dsa/slave.c                                    |  2 +-
+ net/ethernet/eth.c                                 | 11 ++--
+ 85 files changed, 218 insertions(+), 364 deletions(-)
+
+--- a/arch/arm/mach-mvebu/kirkwood.c
++++ b/arch/arm/mach-mvebu/kirkwood.c
+@@ -84,6 +84,7 @@ static void __init kirkwood_dt_eth_fixup
+               struct device_node *pnp = of_get_parent(np);
+               struct clk *clk;
+               struct property *pmac;
++              u8 tmpmac[ETH_ALEN];
+               void __iomem *io;
+               u8 *macaddr;
+               u32 reg;
+@@ -93,7 +94,7 @@ static void __init kirkwood_dt_eth_fixup
+               /* skip disabled nodes or nodes with valid MAC address*/
+               if (!of_device_is_available(pnp) ||
+-                  !IS_ERR(of_get_mac_address(np)))
++                  !of_get_mac_address(np, tmpmac))
+                       goto eth_fixup_skip;
+               clk = of_clk_get(pnp, 0);
+--- a/arch/powerpc/sysdev/tsi108_dev.c
++++ b/arch/powerpc/sysdev/tsi108_dev.c
+@@ -73,7 +73,6 @@ static int __init tsi108_eth_of_init(voi
+               struct device_node *phy, *mdio;
+               hw_info tsi_eth_data;
+               const unsigned int *phy_id;
+-              const void *mac_addr;
+               const phandle *ph;
+               memset(r, 0, sizeof(r));
+@@ -101,9 +100,7 @@ static int __init tsi108_eth_of_init(voi
+                       goto err;
+               }
+-              mac_addr = of_get_mac_address(np);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(tsi_eth_data.mac_addr, mac_addr);
++              of_get_mac_address(np, tsi_eth_data.mac_addr);
+               ph = of_get_property(np, "mdio-handle", NULL);
+               mdio = of_find_node_by_phandle(*ph);
+--- a/drivers/net/ethernet/aeroflex/greth.c
++++ b/drivers/net/ethernet/aeroflex/greth.c
+@@ -1449,10 +1449,10 @@ static int greth_of_probe(struct platfor
+                       break;
+       }
+       if (i == 6) {
+-              const u8 *addr;
++              u8 addr[ETH_ALEN];
+-              addr = of_get_mac_address(ofdev->dev.of_node);
+-              if (!IS_ERR(addr)) {
++              err = of_get_mac_address(ofdev->dev.of_node, addr);
++              if (!err) {
+                       for (i = 0; i < 6; i++)
+                               macaddr[i] = (unsigned int) addr[i];
+               } else {
+--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
++++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
+@@ -790,7 +790,6 @@ static int emac_probe(struct platform_de
+       struct emac_board_info *db;
+       struct net_device *ndev;
+       int ret = 0;
+-      const char *mac_addr;
+       ndev = alloc_etherdev(sizeof(struct emac_board_info));
+       if (!ndev) {
+@@ -853,12 +852,9 @@ static int emac_probe(struct platform_de
+       }
+       /* Read MAC-address from DT */
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-
+-      /* Check if the MAC address is valid, if not get a random one */
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
++              /* if the MAC address is invalid get a random one */
+               eth_hw_addr_random(ndev);
+               dev_warn(&pdev->dev, "using random MAC address %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/altera/altera_tse_main.c
++++ b/drivers/net/ethernet/altera/altera_tse_main.c
+@@ -1351,7 +1351,6 @@ static int altera_tse_probe(struct platf
+       struct resource *control_port;
+       struct resource *dma_res;
+       struct altera_tse_private *priv;
+-      const unsigned char *macaddr;
+       void __iomem *descmap;
+       const struct of_device_id *of_id = NULL;
+@@ -1525,10 +1524,8 @@ static int altera_tse_probe(struct platf
+       priv->rx_dma_buf_sz = ALTERA_RXDMABUFFER_SIZE;
+       /* get default MAC address from device tree */
+-      macaddr = of_get_mac_address(pdev->dev.of_node);
+-      if (!IS_ERR(macaddr))
+-              ether_addr_copy(ndev->dev_addr, macaddr);
+-      else
++      ret = of_get_mac_address(pdev->dev.of_node, ndev->dev_addr);
++      if (ret)
+               eth_hw_addr_random(ndev);
+       /* get phy addr and create mdio */
+--- a/drivers/net/ethernet/arc/emac_main.c
++++ b/drivers/net/ethernet/arc/emac_main.c
+@@ -857,7 +857,6 @@ int arc_emac_probe(struct net_device *nd
+       struct device_node *phy_node;
+       struct phy_device *phydev = NULL;
+       struct arc_emac_priv *priv;
+-      const char *mac_addr;
+       unsigned int id, clock_frequency, irq;
+       int err;
+@@ -942,11 +941,8 @@ int arc_emac_probe(struct net_device *nd
+       }
+       /* Get MAC address from device tree */
+-      mac_addr = of_get_mac_address(dev->of_node);
+-
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      else
++      err = of_get_mac_address(dev->of_node, ndev->dev_addr);
++      if (err)
+               eth_hw_addr_random(ndev);
+       arc_emac_set_address_internal(ndev);
+--- a/drivers/net/ethernet/atheros/ag71xx.c
++++ b/drivers/net/ethernet/atheros/ag71xx.c
+@@ -1856,7 +1856,6 @@ static int ag71xx_probe(struct platform_
+       const struct ag71xx_dcfg *dcfg;
+       struct net_device *ndev;
+       struct resource *res;
+-      const void *mac_addr;
+       int tx_size, err, i;
+       struct ag71xx *ag;
+@@ -1957,10 +1956,8 @@ static int ag71xx_probe(struct platform_
+       ag->stop_desc->ctrl = 0;
+       ag->stop_desc->next = (u32)ag->stop_desc_dma;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+-      if (IS_ERR(mac_addr) || !is_valid_ether_addr(ndev->dev_addr)) {
++      err = of_get_mac_address(np, ndev->dev_addr);
++      if (err) {
+               netif_err(ag, probe, ndev, "invalid MAC address, using random address\n");
+               eth_random_addr(ndev->dev_addr);
+       }
+--- a/drivers/net/ethernet/broadcom/bcmsysport.c
++++ b/drivers/net/ethernet/broadcom/bcmsysport.c
+@@ -2465,7 +2465,6 @@ static int bcm_sysport_probe(struct plat
+       struct bcm_sysport_priv *priv;
+       struct device_node *dn;
+       struct net_device *dev;
+-      const void *macaddr;
+       u32 txq, rxq;
+       int ret;
+@@ -2560,12 +2559,10 @@ static int bcm_sysport_probe(struct plat
+       }
+       /* Initialize netdevice members */
+-      macaddr = of_get_mac_address(dn);
+-      if (IS_ERR(macaddr)) {
++      ret = of_get_mac_address(dn, dev->dev_addr);
++      if (ret) {
+               dev_warn(&pdev->dev, "using random Ethernet MAC\n");
+               eth_hw_addr_random(dev);
+-      } else {
+-              ether_addr_copy(dev->dev_addr, macaddr);
+       }
+       SET_NETDEV_DEV(dev, &pdev->dev);
+--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
+@@ -115,7 +115,7 @@ static int bgmac_probe(struct bcma_devic
+       struct ssb_sprom *sprom = &core->bus->sprom;
+       struct mii_bus *mii_bus;
+       struct bgmac *bgmac;
+-      const u8 *mac = NULL;
++      const u8 *mac;
+       int err;
+       bgmac = bgmac_alloc(&core->dev);
+@@ -128,11 +128,10 @@ static int bgmac_probe(struct bcma_devic
+       bcma_set_drvdata(core, bgmac);
+-      if (bgmac->dev->of_node)
+-              mac = of_get_mac_address(bgmac->dev->of_node);
++      err = of_get_mac_address(bgmac->dev->of_node, bgmac->net_dev->dev_addr);
+       /* If no MAC address assigned via device tree, check SPROM */
+-      if (IS_ERR_OR_NULL(mac)) {
++      if (err) {
+               switch (core->core_unit) {
+               case 0:
+                       mac = sprom->et0mac;
+@@ -149,10 +148,9 @@ static int bgmac_probe(struct bcma_devic
+                       err = -ENOTSUPP;
+                       goto err;
+               }
++              ether_addr_copy(bgmac->net_dev->dev_addr, mac);
+       }
+-      ether_addr_copy(bgmac->net_dev->dev_addr, mac);
+-
+       /* On BCM4706 we need common core to access PHY */
+       if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
+           !core->bus->drv_gmac_cmn.core) {
+--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
++++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
+@@ -173,7 +173,7 @@ static int bgmac_probe(struct platform_d
+       struct device_node *np = pdev->dev.of_node;
+       struct bgmac *bgmac;
+       struct resource *regs;
+-      const u8 *mac_addr;
++      int ret;
+       bgmac = bgmac_alloc(&pdev->dev);
+       if (!bgmac)
+@@ -192,11 +192,10 @@ static int bgmac_probe(struct platform_d
+       bgmac->dev = &pdev->dev;
+       bgmac->dma_dev = &pdev->dev;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(bgmac->net_dev->dev_addr, mac_addr);
+-      else
+-              dev_warn(&pdev->dev, "MAC address not present in device tree\n");
++      ret = of_get_mac_address(np, bgmac->net_dev->dev_addr);
++      if (ret)
++              dev_warn(&pdev->dev,
++                       "MAC address not present in device tree\n");
+       bgmac->irq = platform_get_irq(pdev, 0);
+       if (bgmac->irq < 0)
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -4456,7 +4456,6 @@ static int macb_probe(struct platform_de
+       struct net_device *dev;
+       struct resource *regs;
+       void __iomem *mem;
+-      const char *mac;
+       struct macb *bp;
+       int err, val;
+@@ -4569,15 +4568,11 @@ static int macb_probe(struct platform_de
+       if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR)
+               bp->rx_intr_mask |= MACB_BIT(RXUBR);
+-      mac = of_get_mac_address(np);
+-      if (PTR_ERR(mac) == -EPROBE_DEFER) {
+-              err = -EPROBE_DEFER;
++      err = of_get_mac_address(np, bp->dev->dev_addr);
++      if (err == -EPROBE_DEFER)
+               goto err_out_free_netdev;
+-      } else if (!IS_ERR_OR_NULL(mac)) {
+-              ether_addr_copy(bp->dev->dev_addr, mac);
+-      } else {
++      else if (err)
+               macb_get_hwaddr(bp);
+-      }
+       err = of_get_phy_mode(np, &interface);
+       if (err)
+--- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
++++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
+@@ -1385,7 +1385,6 @@ static int octeon_mgmt_probe(struct plat
+       struct net_device *netdev;
+       struct octeon_mgmt *p;
+       const __be32 *data;
+-      const u8 *mac;
+       struct resource *res_mix;
+       struct resource *res_agl;
+       struct resource *res_agl_prt_ctl;
+@@ -1502,11 +1501,8 @@ static int octeon_mgmt_probe(struct plat
+       netdev->min_mtu = 64 - OCTEON_MGMT_RX_HEADROOM;
+       netdev->max_mtu = 16383 - OCTEON_MGMT_RX_HEADROOM - VLAN_HLEN;
+-      mac = of_get_mac_address(pdev->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(netdev->dev_addr, mac);
+-      else
++      result = of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
++      if (result)
+               eth_hw_addr_random(netdev);
+       p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
+--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+@@ -1474,7 +1474,6 @@ static int bgx_init_of_phy(struct bgx *b
+       device_for_each_child_node(&bgx->pdev->dev, fwn) {
+               struct phy_device *pd;
+               struct device_node *phy_np;
+-              const char *mac;
+               /* Should always be an OF node.  But if it is not, we
+                * cannot handle it, so exit the loop.
+@@ -1483,9 +1482,7 @@ static int bgx_init_of_phy(struct bgx *b
+               if (!node)
+                       break;
+-              mac = of_get_mac_address(node);
+-              if (!IS_ERR(mac))
+-                      ether_addr_copy(bgx->lmac[lmac].mac, mac);
++              of_get_mac_address(node, bgx->lmac[lmac].mac);
+               SET_NETDEV_DEV(&bgx->lmac[lmac].netdev, &bgx->pdev->dev);
+               bgx->lmac[lmac].lmacid = lmac;
+--- a/drivers/net/ethernet/davicom/dm9000.c
++++ b/drivers/net/ethernet/davicom/dm9000.c
+@@ -1388,7 +1388,7 @@ static struct dm9000_plat_data *dm9000_p
+ {
+       struct dm9000_plat_data *pdata;
+       struct device_node *np = dev->of_node;
+-      const void *mac_addr;
++      int ret;
+       if (!IS_ENABLED(CONFIG_OF) || !np)
+               return ERR_PTR(-ENXIO);
+@@ -1402,11 +1402,9 @@ static struct dm9000_plat_data *dm9000_p
+       if (of_find_property(np, "davicom,no-eeprom", NULL))
+               pdata->flags |= DM9000_PLATF_NO_EEPROM;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(pdata->dev_addr, mac_addr);
+-      else if (PTR_ERR(mac_addr) == -EPROBE_DEFER)
+-              return ERR_CAST(mac_addr);
++      ret = of_get_mac_address(np, pdata->dev_addr);
++      if (ret == -EPROBE_DEFER)
++              return ERR_PTR(ret);
+       return pdata;
+ }
+--- a/drivers/net/ethernet/ethoc.c
++++ b/drivers/net/ethernet/ethoc.c
+@@ -1151,11 +1151,7 @@ static int ethoc_probe(struct platform_d
+               ether_addr_copy(netdev->dev_addr, pdata->hwaddr);
+               priv->phy_id = pdata->phy_id;
+       } else {
+-              const void *mac;
+-
+-              mac = of_get_mac_address(pdev->dev.of_node);
+-              if (!IS_ERR(mac))
+-                      ether_addr_copy(netdev->dev_addr, mac);
++              of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
+               priv->phy_id = -1;
+       }
+--- a/drivers/net/ethernet/ezchip/nps_enet.c
++++ b/drivers/net/ethernet/ezchip/nps_enet.c
+@@ -575,7 +575,6 @@ static s32 nps_enet_probe(struct platfor
+       struct net_device *ndev;
+       struct nps_enet_priv *priv;
+       s32 err = 0;
+-      const char *mac_addr;
+       if (!dev->of_node)
+               return -ENODEV;
+@@ -602,10 +601,8 @@ static s32 nps_enet_probe(struct platfor
+       dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs_base);
+       /* set kernel MAC address to dev */
+-      mac_addr = of_get_mac_address(dev->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      else
++      err = of_get_mac_address(dev->of_node, ndev->dev_addr);
++      if (err)
+               eth_hw_addr_random(ndev);
+       /* Get IRQ number */
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1666,6 +1666,7 @@ static void fec_get_mac(struct net_devic
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       struct fec_platform_data *pdata = dev_get_platdata(&fep->pdev->dev);
+       unsigned char *iap, tmpaddr[ETH_ALEN];
++      int ret;
+       /*
+        * try to get mac address in following order:
+@@ -1681,9 +1682,9 @@ static void fec_get_mac(struct net_devic
+       if (!is_valid_ether_addr(iap)) {
+               struct device_node *np = fep->pdev->dev.of_node;
+               if (np) {
+-                      const char *mac = of_get_mac_address(np);
+-                      if (!IS_ERR(mac))
+-                              iap = (unsigned char *) mac;
++                      ret = of_get_mac_address(np, tmpaddr);
++                      if (!ret)
++                              iap = tmpaddr;
+               }
+       }
+--- a/drivers/net/ethernet/freescale/fec_mpc52xx.c
++++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c
+@@ -813,7 +813,6 @@ static int mpc52xx_fec_probe(struct plat
+       const u32 *prop;
+       int prop_size;
+       struct device_node *np = op->dev.of_node;
+-      const char *mac_addr;
+       phys_addr_t rx_fifo;
+       phys_addr_t tx_fifo;
+@@ -891,10 +890,8 @@ static int mpc52xx_fec_probe(struct plat
+        *
+        * First try to read MAC address from DT
+        */
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr)) {
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      } else {
++      rv = of_get_mac_address(np, ndev->dev_addr);
++      if (rv) {
+               struct mpc52xx_fec __iomem *fec = priv->fec;
+               /*
+--- a/drivers/net/ethernet/freescale/fman/mac.c
++++ b/drivers/net/ethernet/freescale/fman/mac.c
+@@ -605,7 +605,6 @@ static int mac_probe(struct platform_dev
+       struct platform_device  *of_dev;
+       struct resource          res;
+       struct mac_priv_s       *priv;
+-      const u8                *mac_addr;
+       u32                      val;
+       u8                      fman_id;
+       phy_interface_t          phy_if;
+@@ -723,11 +722,9 @@ static int mac_probe(struct platform_dev
+       priv->cell_index = (u8)val;
+       /* Get the MAC address */
+-      mac_addr = of_get_mac_address(mac_node);
+-      if (IS_ERR(mac_addr))
++      err = of_get_mac_address(mac_node, mac_dev->addr);
++      if (err)
+               dev_warn(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
+-      else
+-              ether_addr_copy(mac_dev->addr, mac_addr);
+       /* Get the port handles */
+       nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
+@@ -853,7 +850,7 @@ static int mac_probe(struct platform_dev
+       if (err < 0)
+               dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
+-      if (!IS_ERR(mac_addr))
++      if (!is_zero_ether_addr(mac_dev->addr))
+               dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
+       priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
+--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
++++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+@@ -918,7 +918,6 @@ static int fs_enet_probe(struct platform
+       const u32 *data;
+       struct clk *clk;
+       int err;
+-      const u8 *mac_addr;
+       const char *phy_connection_type;
+       int privsize, len, ret = -ENODEV;
+@@ -1006,9 +1005,7 @@ static int fs_enet_probe(struct platform
+       spin_lock_init(&fep->lock);
+       spin_lock_init(&fep->tx_lock);
+-      mac_addr = of_get_mac_address(ofdev->dev.of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
++      of_get_mac_address(ofdev->dev.of_node, ndev->dev_addr);
+       ret = fep->ops->allocate_bd(ndev);
+       if (ret)
+--- a/drivers/net/ethernet/freescale/gianfar.c
++++ b/drivers/net/ethernet/freescale/gianfar.c
+@@ -641,7 +641,6 @@ static phy_interface_t gfar_get_interfac
+ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
+ {
+       const char *model;
+-      const void *mac_addr;
+       int err = 0, i;
+       phy_interface_t interface;
+       struct net_device *dev = NULL;
+@@ -783,11 +782,8 @@ static int gfar_of_init(struct platform_
+       if (stash_len || stash_idx)
+               priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING;
+-      mac_addr = of_get_mac_address(np);
+-
+-      if (!IS_ERR(mac_addr)) {
+-              ether_addr_copy(dev->dev_addr, mac_addr);
+-      } else {
++      err = of_get_mac_address(np, dev->dev_addr);
++      if (err) {
+               eth_hw_addr_random(dev);
+               dev_info(&ofdev->dev, "Using random MAC address: %pM\n", dev->dev_addr);
+       }
+--- a/drivers/net/ethernet/freescale/ucc_geth.c
++++ b/drivers/net/ethernet/freescale/ucc_geth.c
+@@ -3696,7 +3696,6 @@ static int ucc_geth_probe(struct platfor
+       int err, ucc_num, max_speed = 0;
+       const unsigned int *prop;
+       const char *sprop;
+-      const void *mac_addr;
+       phy_interface_t phy_interface;
+       static const int enet_to_speed[] = {
+               SPEED_10, SPEED_10, SPEED_10,
+@@ -3906,9 +3905,7 @@ static int ucc_geth_probe(struct platfor
+               goto err_free_netdev;
+       }
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(dev->dev_addr, mac_addr);
++      of_get_mac_address(np, dev->dev_addr);
+       ugeth->ug_info = ug_info;
+       ugeth->dev = device;
+--- a/drivers/net/ethernet/hisilicon/hisi_femac.c
++++ b/drivers/net/ethernet/hisilicon/hisi_femac.c
+@@ -772,7 +772,6 @@ static int hisi_femac_drv_probe(struct p
+       struct net_device *ndev;
+       struct hisi_femac_priv *priv;
+       struct phy_device *phy;
+-      const char *mac_addr;
+       int ret;
+       ndev = alloc_etherdev(sizeof(*priv));
+@@ -842,10 +841,8 @@ static int hisi_femac_drv_probe(struct p
+                          (unsigned long)phy->phy_id,
+                          phy_modes(phy->interface));
+-      mac_addr = of_get_mac_address(node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(node, ndev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(ndev);
+               dev_warn(dev, "using random MAC address %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
++++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+@@ -1098,7 +1098,6 @@ static int hix5hd2_dev_probe(struct plat
+       struct net_device *ndev;
+       struct hix5hd2_priv *priv;
+       struct mii_bus *bus;
+-      const char *mac_addr;
+       int ret;
+       ndev = alloc_etherdev(sizeof(struct hix5hd2_priv));
+@@ -1220,10 +1219,8 @@ static int hix5hd2_dev_probe(struct plat
+               goto out_phy_node;
+       }
+-      mac_addr = of_get_mac_address(node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(node, ndev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(ndev);
+               netdev_warn(ndev, "using random MAC address %pM\n",
+                           ndev->dev_addr);
+--- a/drivers/net/ethernet/lantiq_xrx200.c
++++ b/drivers/net/ethernet/lantiq_xrx200.c
+@@ -440,7 +440,6 @@ static int xrx200_probe(struct platform_
+       struct resource *res;
+       struct xrx200_priv *priv;
+       struct net_device *net_dev;
+-      const u8 *mac;
+       int err;
+       /* alloc the network device */
+@@ -484,10 +483,8 @@ static int xrx200_probe(struct platform_
+               return PTR_ERR(priv->clk);
+       }
+-      mac = of_get_mac_address(np);
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(net_dev->dev_addr, mac);
+-      else
++      err = of_get_mac_address(np, net_dev->dev_addr);
++      if (err)
+               eth_hw_addr_random(net_dev);
+       /* bring up the dma engine and IP core */
+--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
+@@ -2700,7 +2700,6 @@ static int mv643xx_eth_shared_of_add_por
+       struct platform_device *ppdev;
+       struct mv643xx_eth_platform_data ppd;
+       struct resource res;
+-      const char *mac_addr;
+       int ret;
+       int dev_num = 0;
+@@ -2731,9 +2730,7 @@ static int mv643xx_eth_shared_of_add_por
+               return -EINVAL;
+       }
+-      mac_addr = of_get_mac_address(pnp);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ppd.mac_addr, mac_addr);
++      of_get_mac_address(pnp, ppd.mac_addr);
+       mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size);
+       mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr);
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -5062,7 +5062,6 @@ static int mvneta_probe(struct platform_
+       struct net_device *dev;
+       struct phylink *phylink;
+       struct phy *comphy;
+-      const char *dt_mac_addr;
+       char hw_mac_addr[ETH_ALEN];
+       phy_interface_t phy_mode;
+       const char *mac_from;
+@@ -5158,10 +5157,9 @@ static int mvneta_probe(struct platform_
+               goto err_free_ports;
+       }
+-      dt_mac_addr = of_get_mac_address(dn);
+-      if (!IS_ERR(dt_mac_addr)) {
++      err = of_get_mac_address(dn, dev->dev_addr);
++      if (!err) {
+               mac_from = "device tree";
+-              ether_addr_copy(dev->dev_addr, dt_mac_addr);
+       } else {
+               mvneta_get_mac_addr(pp, hw_mac_addr);
+               if (is_valid_ether_addr(hw_mac_addr)) {
+--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+@@ -462,20 +462,17 @@ static int prestera_switch_set_base_mac_
+ {
+       struct device_node *base_mac_np;
+       struct device_node *np;
+-      const char *base_mac;
++      int ret;
+       np = of_find_compatible_node(NULL, NULL, "marvell,prestera");
+       base_mac_np = of_parse_phandle(np, "base-mac-provider", 0);
+-      base_mac = of_get_mac_address(base_mac_np);
+-      of_node_put(base_mac_np);
+-      if (!IS_ERR(base_mac))
+-              ether_addr_copy(sw->base_mac, base_mac);
+-
+-      if (!is_valid_ether_addr(sw->base_mac)) {
++      ret = of_get_mac_address(base_mac_np, sw->base_mac);
++      if (ret) {
+               eth_random_addr(sw->base_mac);
+               dev_info(prestera_dev(sw), "using random base mac address\n");
+       }
++      of_node_put(base_mac_np);
+       return prestera_hw_switch_mac_set(sw, sw->base_mac);
+ }
+--- a/drivers/net/ethernet/marvell/pxa168_eth.c
++++ b/drivers/net/ethernet/marvell/pxa168_eth.c
+@@ -1392,7 +1392,6 @@ static int pxa168_eth_probe(struct platf
+       struct resource *res;
+       struct clk *clk;
+       struct device_node *np;
+-      const unsigned char *mac_addr = NULL;
+       int err;
+       printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
+@@ -1435,12 +1434,8 @@ static int pxa168_eth_probe(struct platf
+       INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
+-      if (pdev->dev.of_node)
+-              mac_addr = of_get_mac_address(pdev->dev.of_node);
+-
+-      if (!IS_ERR_OR_NULL(mac_addr)) {
+-              ether_addr_copy(dev->dev_addr, mac_addr);
+-      } else {
++      err = of_get_mac_address(pdev->dev.of_node, dev->dev_addr);
++      if (err) {
+               /* try reading the mac address, if set by the bootloader */
+               pxa168_eth_get_mac_address(dev, dev->dev_addr);
+               if (!is_valid_ether_addr(dev->dev_addr)) {
+--- a/drivers/net/ethernet/marvell/sky2.c
++++ b/drivers/net/ethernet/marvell/sky2.c
+@@ -4725,7 +4725,7 @@ static struct net_device *sky2_init_netd
+ {
+       struct sky2_port *sky2;
+       struct net_device *dev = alloc_etherdev(sizeof(*sky2));
+-      const void *iap;
++      int ret;
+       if (!dev)
+               return NULL;
+@@ -4795,10 +4795,8 @@ static struct net_device *sky2_init_netd
+        * 1) from device tree data
+        * 2) from internal registers set by bootloader
+        */
+-      iap = of_get_mac_address(hw->pdev->dev.of_node);
+-      if (!IS_ERR(iap))
+-              ether_addr_copy(dev->dev_addr, iap);
+-      else
++      ret = of_get_mac_address(hw->pdev->dev.of_node, dev->dev_addr);
++      if (ret)
+               memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8,
+                             ETH_ALEN);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2580,14 +2580,11 @@ static int __init mtk_init(struct net_de
+ {
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+-      const char *mac_addr;
++      int ret;
+-      mac_addr = of_get_mac_address(mac->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(dev->dev_addr, mac_addr);
+-
+-      /* If the mac address is invalid, use random mac address  */
+-      if (!is_valid_ether_addr(dev->dev_addr)) {
++      ret = of_get_mac_address(mac->of_node, dev->dev_addr);
++      if (ret) {
++              /* If the mac address is invalid, use random mac address */
+               eth_hw_addr_random(dev);
+               dev_err(eth->dev, "generated random MAC address %pM\n",
+                       dev->dev_addr);
+--- a/drivers/net/ethernet/micrel/ks8851_common.c
++++ b/drivers/net/ethernet/micrel/ks8851_common.c
+@@ -194,11 +194,10 @@ static void ks8851_read_mac_addr(struct
+ static void ks8851_init_mac(struct ks8851_net *ks, struct device_node *np)
+ {
+       struct net_device *dev = ks->netdev;
+-      const u8 *mac_addr;
++      int ret;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr)) {
+-              ether_addr_copy(dev->dev_addr, mac_addr);
++      ret = of_get_mac_address(np, dev->dev_addr);
++      if (!ret) {
+               ks8851_write_mac_addr(dev);
+               return;
+       }
+--- a/drivers/net/ethernet/microchip/lan743x_main.c
++++ b/drivers/net/ethernet/microchip/lan743x_main.c
+@@ -2835,7 +2835,6 @@ static int lan743x_pcidev_probe(struct p
+ {
+       struct lan743x_adapter *adapter = NULL;
+       struct net_device *netdev = NULL;
+-      const void *mac_addr;
+       int ret = -ENODEV;
+       netdev = devm_alloc_etherdev(&pdev->dev,
+@@ -2852,9 +2851,7 @@ static int lan743x_pcidev_probe(struct p
+                             NETIF_MSG_IFDOWN | NETIF_MSG_TX_QUEUED;
+       netdev->max_mtu = LAN743X_MAX_FRAME_SIZE;
+-      mac_addr = of_get_mac_address(pdev->dev.of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(adapter->mac_address, mac_addr);
++      of_get_mac_address(pdev->dev.of_node, adapter->mac_address);
+       ret = lan743x_pci_init(adapter, pdev);
+       if (ret)
+--- a/drivers/net/ethernet/nxp/lpc_eth.c
++++ b/drivers/net/ethernet/nxp/lpc_eth.c
+@@ -1347,9 +1347,7 @@ static int lpc_eth_drv_probe(struct plat
+       __lpc_get_mac(pldat, ndev->dev_addr);
+       if (!is_valid_ether_addr(ndev->dev_addr)) {
+-              const char *macaddr = of_get_mac_address(np);
+-              if (!IS_ERR(macaddr))
+-                      ether_addr_copy(ndev->dev_addr, macaddr);
++              of_get_mac_address(np, ndev->dev_addr);
+       }
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               eth_hw_addr_random(ndev);
+--- a/drivers/net/ethernet/qualcomm/qca_spi.c
++++ b/drivers/net/ethernet/qualcomm/qca_spi.c
+@@ -885,7 +885,7 @@ qca_spi_probe(struct spi_device *spi)
+       struct net_device *qcaspi_devs = NULL;
+       u8 legacy_mode = 0;
+       u16 signature;
+-      const char *mac;
++      int ret;
+       if (!spi->dev.of_node) {
+               dev_err(&spi->dev, "Missing device tree\n");
+@@ -962,12 +962,8 @@ qca_spi_probe(struct spi_device *spi)
+       spi_set_drvdata(spi, qcaspi_devs);
+-      mac = of_get_mac_address(spi->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(qca->net_dev->dev_addr, mac);
+-
+-      if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
++      ret = of_get_mac_address(spi->dev.of_node, qca->net_dev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(qca->net_dev);
+               dev_info(&spi->dev, "Using random MAC address: %pM\n",
+                        qca->net_dev->dev_addr);
+--- a/drivers/net/ethernet/qualcomm/qca_uart.c
++++ b/drivers/net/ethernet/qualcomm/qca_uart.c
+@@ -323,7 +323,6 @@ static int qca_uart_probe(struct serdev_
+ {
+       struct net_device *qcauart_dev = alloc_etherdev(sizeof(struct qcauart));
+       struct qcauart *qca;
+-      const char *mac;
+       u32 speed = 115200;
+       int ret;
+@@ -348,12 +347,8 @@ static int qca_uart_probe(struct serdev_
+       of_property_read_u32(serdev->dev.of_node, "current-speed", &speed);
+-      mac = of_get_mac_address(serdev->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(qca->net_dev->dev_addr, mac);
+-
+-      if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
++      ret = of_get_mac_address(serdev->dev.of_node, qca->net_dev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(qca->net_dev);
+               dev_info(&serdev->dev, "Using random MAC address: %pM\n",
+                        qca->net_dev->dev_addr);
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -109,11 +109,13 @@ static void ravb_set_buffer_align(struct
+  * Ethernet AVB device doesn't have ROM for MAC address.
+  * This function gets the MAC address that was used by a bootloader.
+  */
+-static void ravb_read_mac_address(struct net_device *ndev, const u8 *mac)
++static void ravb_read_mac_address(struct device_node *np,
++                                struct net_device *ndev)
+ {
+-      if (!IS_ERR(mac)) {
+-              ether_addr_copy(ndev->dev_addr, mac);
+-      } else {
++      int ret;
++
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
+               u32 mahr = ravb_read(ndev, MAHR);
+               u32 malr = ravb_read(ndev, MALR);
+@@ -2189,7 +2191,7 @@ static int ravb_probe(struct platform_de
+       priv->msg_enable = RAVB_DEF_MSG_ENABLE;
+       /* Read and set MAC address */
+-      ravb_read_mac_address(ndev, of_get_mac_address(np));
++      ravb_read_mac_address(np, ndev);
+       if (!is_valid_ether_addr(ndev->dev_addr)) {
+               dev_warn(&pdev->dev,
+                        "no valid MAC address supplied, using a random one\n");
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -3145,7 +3145,6 @@ static struct sh_eth_plat_data *sh_eth_p
+       struct device_node *np = dev->of_node;
+       struct sh_eth_plat_data *pdata;
+       phy_interface_t interface;
+-      const char *mac_addr;
+       int ret;
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+@@ -3157,9 +3156,7 @@ static struct sh_eth_plat_data *sh_eth_p
+               return NULL;
+       pdata->phy_interface = interface;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(pdata->mac_addr, mac_addr);
++      of_get_mac_address(np, pdata->mac_addr);
+       pdata->no_ether_link =
+               of_property_read_bool(np, "renesas,no-ether-link");
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
+@@ -25,8 +25,7 @@
+ #ifdef CONFIG_OF
+ static int sxgbe_probe_config_dt(struct platform_device *pdev,
+-                               struct sxgbe_plat_data *plat,
+-                               const char **mac)
++                               struct sxgbe_plat_data *plat)
+ {
+       struct device_node *np = pdev->dev.of_node;
+       struct sxgbe_dma_cfg *dma_cfg;
+@@ -35,7 +34,6 @@ static int sxgbe_probe_config_dt(struct
+       if (!np)
+               return -ENODEV;
+-      *mac = of_get_mac_address(np);
+       err = of_get_phy_mode(np, &plat->interface);
+       if (err && err != -ENODEV)
+               return err;
+@@ -63,8 +61,7 @@ static int sxgbe_probe_config_dt(struct
+ }
+ #else
+ static int sxgbe_probe_config_dt(struct platform_device *pdev,
+-                               struct sxgbe_plat_data *plat,
+-                               const char **mac)
++                               struct sxgbe_plat_data *plat)
+ {
+       return -ENOSYS;
+ }
+@@ -85,7 +82,6 @@ static int sxgbe_platform_probe(struct p
+       void __iomem *addr;
+       struct sxgbe_priv_data *priv = NULL;
+       struct sxgbe_plat_data *plat_dat = NULL;
+-      const char *mac = NULL;
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct device_node *node = dev->of_node;
+@@ -101,7 +97,7 @@ static int sxgbe_platform_probe(struct p
+               if (!plat_dat)
+                       return  -ENOMEM;
+-              ret = sxgbe_probe_config_dt(pdev, plat_dat, &mac);
++              ret = sxgbe_probe_config_dt(pdev, plat_dat);
+               if (ret) {
+                       pr_err("%s: main dt probe failed\n", __func__);
+                       return ret;
+@@ -122,8 +118,7 @@ static int sxgbe_platform_probe(struct p
+       }
+       /* Get MAC address if available (DT) */
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(priv->dev->dev_addr, mac);
++      of_get_mac_address(node, priv->dev->dev_addr);
+       /* Get the TX/RX IRQ numbers */
+       for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) {
+--- a/drivers/net/ethernet/socionext/sni_ave.c
++++ b/drivers/net/ethernet/socionext/sni_ave.c
+@@ -1559,7 +1559,6 @@ static int ave_probe(struct platform_dev
+       struct ave_private *priv;
+       struct net_device *ndev;
+       struct device_node *np;
+-      const void *mac_addr;
+       void __iomem *base;
+       const char *name;
+       int i, irq, ret;
+@@ -1600,12 +1599,9 @@ static int ave_probe(struct platform_dev
+       ndev->max_mtu = AVE_MAX_ETHFRAME - (ETH_HLEN + ETH_FCS_LEN);
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-
+-      /* if the mac address is invalid, use random mac address */
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
++              /* if the mac address is invalid, use random mac address */
+               eth_hw_addr_random(ndev);
+               dev_warn(dev, "Using random MAC address: %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
+@@ -115,7 +115,7 @@ static int anarion_dwmac_probe(struct pl
+       if (IS_ERR(gmac))
+               return PTR_ERR(gmac);
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+@@ -444,7 +444,7 @@ static int dwc_eth_dwmac_probe(struct pl
+       if (IS_ERR(stmmac_res.addr))
+               return PTR_ERR(stmmac_res.addr);
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+@@ -27,7 +27,7 @@ static int dwmac_generic_probe(struct pl
+               return ret;
+       if (pdev->dev.of_node) {
+-              plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++              plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+               if (IS_ERR(plat_dat)) {
+                       dev_err(&pdev->dev, "dt configuration failed\n");
+                       return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+@@ -226,7 +226,7 @@ static int imx_dwmac_probe(struct platfo
+       if (!dwmac)
+               return -ENOMEM;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+@@ -88,7 +88,7 @@ static int intel_eth_plat_probe(struct p
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat)) {
+               dev_err(&pdev->dev, "dt configuration failed\n");
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+@@ -255,7 +255,7 @@ static int ipq806x_gmac_probe(struct pla
+       if (val)
+               return val;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
+@@ -37,7 +37,7 @@ static int lpc18xx_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+@@ -407,7 +407,7 @@ static int mediatek_dwmac_probe(struct p
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
+@@ -52,7 +52,7 @@ static int meson6_dwmac_probe(struct pla
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+@@ -372,7 +372,7 @@ static int meson8b_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
+@@ -118,7 +118,7 @@ static int oxnas_dwmac_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+@@ -461,7 +461,7 @@ static int qcom_ethqos_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat)) {
+               dev_err(&pdev->dev, "dt configuration failed\n");
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+@@ -1396,7 +1396,7 @@ static int rk_gmac_probe(struct platform
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+@@ -398,7 +398,7 @@ static int socfpga_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+@@ -325,7 +325,7 @@ static int sti_dwmac_probe(struct platfo
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+@@ -371,7 +371,7 @@ static int stm32_dwmac_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+@@ -1202,7 +1202,7 @@ static int sun8i_dwmac_probe(struct plat
+       if (ret)
+               return -EINVAL;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+@@ -108,7 +108,7 @@ static int sun7i_gmac_probe(struct platf
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -25,7 +25,7 @@
+ struct stmmac_resources {
+       void __iomem *addr;
+-      const char *mac;
++      u8 mac[ETH_ALEN];
+       int wol_irq;
+       int lpi_irq;
+       int irq;
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -4904,7 +4904,7 @@ int stmmac_dvr_probe(struct device *devi
+       priv->wol_irq = res->wol_irq;
+       priv->lpi_irq = res->lpi_irq;
+-      if (!IS_ERR_OR_NULL(res->mac))
++      if (!is_zero_ether_addr(res->mac))
+               memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
+       dev_set_drvdata(device, priv->dev);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -394,7 +394,7 @@ static int stmmac_of_get_mac_mode(struct
+  * set some private fields that will be used by the main at runtime.
+  */
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ {
+       struct device_node *np = pdev->dev.of_node;
+       struct plat_stmmacenet_data *plat;
+@@ -406,12 +406,12 @@ stmmac_probe_config_dt(struct platform_d
+       if (!plat)
+               return ERR_PTR(-ENOMEM);
+-      *mac = of_get_mac_address(np);
+-      if (IS_ERR(*mac)) {
+-              if (PTR_ERR(*mac) == -EPROBE_DEFER)
+-                      return ERR_CAST(*mac);
++      rc = of_get_mac_address(np, mac);
++      if (rc) {
++              if (rc == -EPROBE_DEFER)
++                      return ERR_PTR(rc);
+-              *mac = NULL;
++              eth_zero_addr(mac);
+       }
+       phy_mode = device_get_phy_mode(&pdev->dev);
+@@ -643,7 +643,7 @@ void stmmac_remove_config_dt(struct plat
+ }
+ #else
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ {
+       return ERR_PTR(-EINVAL);
+ }
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
+@@ -12,7 +12,7 @@
+ #include "stmmac.h"
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
+ void stmmac_remove_config_dt(struct platform_device *pdev,
+                            struct plat_stmmacenet_data *plat);
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1741,7 +1741,6 @@ static int am65_cpsw_nuss_init_slave_por
+       for_each_child_of_node(node, port_np) {
+               struct am65_cpsw_port *port;
+-              const void *mac_addr;
+               u32 port_id;
+               /* it is not a slave port node, continue */
+@@ -1820,15 +1819,15 @@ static int am65_cpsw_nuss_init_slave_por
+                       return ret;
+               }
+-              mac_addr = of_get_mac_address(port_np);
+-              if (!IS_ERR(mac_addr)) {
+-                      ether_addr_copy(port->slave.mac_addr, mac_addr);
+-              } else if (am65_cpsw_am654_get_efuse_macid(port_np,
+-                                                         port->port_id,
+-                                                         port->slave.mac_addr) ||
+-                         !is_valid_ether_addr(port->slave.mac_addr)) {
+-                      random_ether_addr(port->slave.mac_addr);
+-                      dev_err(dev, "Use random MAC address\n");
++              ret = of_get_mac_address(port_np, port->slave.mac_addr);
++              if (ret) {
++                      am65_cpsw_am654_get_efuse_macid(port_np,
++                                                      port->port_id,
++                                                      port->slave.mac_addr);
++                      if (!is_valid_ether_addr(port->slave.mac_addr)) {
++                              random_ether_addr(port->slave.mac_addr);
++                              dev_err(dev, "Use random MAC address\n");
++                      }
+               }
+       }
+       of_node_put(node);
+--- a/drivers/net/ethernet/ti/cpsw.c
++++ b/drivers/net/ethernet/ti/cpsw.c
+@@ -1306,7 +1306,6 @@ static int cpsw_probe_dt(struct cpsw_pla
+       for_each_available_child_of_node(node, slave_node) {
+               struct cpsw_slave_data *slave_data = data->slave_data + i;
+-              const void *mac_addr = NULL;
+               int lenp;
+               const __be32 *parp;
+@@ -1378,10 +1377,8 @@ static int cpsw_probe_dt(struct cpsw_pla
+               }
+ no_phy_slave:
+-              mac_addr = of_get_mac_address(slave_node);
+-              if (!IS_ERR(mac_addr)) {
+-                      ether_addr_copy(slave_data->mac_addr, mac_addr);
+-              } else {
++              ret = of_get_mac_address(slave_node, slave_data->mac_addr);
++              if (ret) {
+                       ret = ti_cm_get_macid(&pdev->dev, i,
+                                             slave_data->mac_addr);
+                       if (ret)
+--- a/drivers/net/ethernet/ti/cpsw_new.c
++++ b/drivers/net/ethernet/ti/cpsw_new.c
+@@ -1267,7 +1267,6 @@ static int cpsw_probe_dt(struct cpsw_com
+       for_each_child_of_node(tmp_node, port_np) {
+               struct cpsw_slave_data *slave_data;
+-              const void *mac_addr;
+               u32 port_id;
+               ret = of_property_read_u32(port_np, "reg", &port_id);
+@@ -1326,10 +1325,8 @@ static int cpsw_probe_dt(struct cpsw_com
+                       goto err_node_put;
+               }
+-              mac_addr = of_get_mac_address(port_np);
+-              if (!IS_ERR(mac_addr)) {
+-                      ether_addr_copy(slave_data->mac_addr, mac_addr);
+-              } else {
++              ret = of_get_mac_address(port_np, slave_data->mac_addr);
++              if (ret) {
+                       ret = ti_cm_get_macid(dev, port_id - 1,
+                                             slave_data->mac_addr);
+                       if (ret)
+--- a/drivers/net/ethernet/ti/davinci_emac.c
++++ b/drivers/net/ethernet/ti/davinci_emac.c
+@@ -1687,7 +1687,6 @@ davinci_emac_of_get_pdata(struct platfor
+       const struct of_device_id *match;
+       const struct emac_platform_data *auxdata;
+       struct emac_platform_data *pdata = NULL;
+-      const u8 *mac_addr;
+       if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
+               return dev_get_platdata(&pdev->dev);
+@@ -1699,11 +1698,8 @@ davinci_emac_of_get_pdata(struct platfor
+       np = pdev->dev.of_node;
+       pdata->version = EMAC_VERSION_2;
+-      if (!is_valid_ether_addr(pdata->mac_addr)) {
+-              mac_addr = of_get_mac_address(np);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(pdata->mac_addr, mac_addr);
+-      }
++      if (!is_valid_ether_addr(pdata->mac_addr))
++              of_get_mac_address(np, pdata->mac_addr);
+       of_property_read_u32(np, "ti,davinci-ctrl-reg-offset",
+                            &pdata->ctrl_reg_offset);
+--- a/drivers/net/ethernet/ti/netcp_core.c
++++ b/drivers/net/ethernet/ti/netcp_core.c
+@@ -1966,7 +1966,6 @@ static int netcp_create_interface(struct
+       struct resource res;
+       void __iomem *efuse = NULL;
+       u32 efuse_mac = 0;
+-      const void *mac_addr;
+       u8 efuse_mac_addr[6];
+       u32 temp[2];
+       int ret = 0;
+@@ -2036,10 +2035,8 @@ static int netcp_create_interface(struct
+               devm_iounmap(dev, efuse);
+               devm_release_mem_region(dev, res.start, size);
+       } else {
+-              mac_addr = of_get_mac_address(node_interface);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(ndev->dev_addr, mac_addr);
+-              else
++              ret = of_get_mac_address(node_interface, ndev->dev_addr);
++              if (ret)
+                       eth_random_addr(ndev->dev_addr);
+       }
+--- a/drivers/net/ethernet/wiznet/w5100-spi.c
++++ b/drivers/net/ethernet/wiznet/w5100-spi.c
+@@ -423,8 +423,14 @@ static int w5100_spi_probe(struct spi_de
+       const struct of_device_id *of_id;
+       const struct w5100_ops *ops;
+       kernel_ulong_t driver_data;
++      const void *mac = NULL;
++      u8 tmpmac[ETH_ALEN];
+       int priv_size;
+-      const void *mac = of_get_mac_address(spi->dev.of_node);
++      int ret;
++
++      ret = of_get_mac_address(spi->dev.of_node, tmpmac);
++      if (!ret)
++              mac = tmpmac;
+       if (spi->dev.of_node) {
+               of_id = of_match_device(w5100_of_match, &spi->dev);
+--- a/drivers/net/ethernet/wiznet/w5100.c
++++ b/drivers/net/ethernet/wiznet/w5100.c
+@@ -1159,7 +1159,7 @@ int w5100_probe(struct device *dev, cons
+       INIT_WORK(&priv->setrx_work, w5100_setrx_work);
+       INIT_WORK(&priv->restart_work, w5100_restart_work);
+-      if (!IS_ERR_OR_NULL(mac_addr))
++      if (mac_addr)
+               memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+       else
+               eth_hw_addr_random(ndev);
+--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
+@@ -438,7 +438,7 @@ static void temac_do_set_mac_address(str
+ static int temac_init_mac_address(struct net_device *ndev, const void *address)
+ {
+-      ether_addr_copy(ndev->dev_addr, address);
++      memcpy(ndev->dev_addr, address, ETH_ALEN);
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               eth_hw_addr_random(ndev);
+       temac_do_set_mac_address(ndev);
+@@ -1370,7 +1370,7 @@ static int temac_probe(struct platform_d
+       struct device_node *temac_np = dev_of_node(&pdev->dev), *dma_np;
+       struct temac_local *lp;
+       struct net_device *ndev;
+-      const void *addr;
++      u8 addr[ETH_ALEN];
+       __be32 *p;
+       bool little_endian;
+       int rc = 0;
+@@ -1561,8 +1561,8 @@ static int temac_probe(struct platform_d
+       if (temac_np) {
+               /* Retrieve the MAC address */
+-              addr = of_get_mac_address(temac_np);
+-              if (IS_ERR(addr)) {
++              rc = of_get_mac_address(temac_np, addr);
++              if (rc) {
+                       dev_err(&pdev->dev, "could not find MAC address\n");
+                       return -ENODEV;
+               }
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -1803,8 +1803,8 @@ static int axienet_probe(struct platform
+       struct device_node *np;
+       struct axienet_local *lp;
+       struct net_device *ndev;
+-      const void *mac_addr;
+       struct resource *ethres;
++      u8 mac_addr[ETH_ALEN];
+       int addr_width = 32;
+       u32 value;
+@@ -2004,13 +2004,14 @@ static int axienet_probe(struct platform
+               dev_info(&pdev->dev, "Ethernet core IRQ not defined\n");
+       /* Retrieve the MAC address */
+-      mac_addr = of_get_mac_address(pdev->dev.of_node);
+-      if (IS_ERR(mac_addr)) {
+-              dev_warn(&pdev->dev, "could not find MAC address property: %ld\n",
+-                       PTR_ERR(mac_addr));
+-              mac_addr = NULL;
++      ret = of_get_mac_address(pdev->dev.of_node, mac_addr);
++      if (!ret) {
++              axienet_set_mac_address(ndev, mac_addr);
++      } else {
++              dev_warn(&pdev->dev, "could not find MAC address property: %d\n",
++                       ret);
++              axienet_set_mac_address(ndev, NULL);
+       }
+-      axienet_set_mac_address(ndev, mac_addr);
+       lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
+       lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -1113,7 +1113,6 @@ static int xemaclite_of_probe(struct pla
+       struct net_device *ndev = NULL;
+       struct net_local *lp = NULL;
+       struct device *dev = &ofdev->dev;
+-      const void *mac_address;
+       int rc = 0;
+@@ -1155,12 +1154,9 @@ static int xemaclite_of_probe(struct pla
+       lp->next_rx_buf_to_use = 0x0;
+       lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong");
+       lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong");
+-      mac_address = of_get_mac_address(ofdev->dev.of_node);
+-      if (!IS_ERR(mac_address)) {
+-              /* Set the MAC address. */
+-              ether_addr_copy(ndev->dev_addr, mac_address);
+-      } else {
++      rc = of_get_mac_address(ofdev->dev.of_node, ndev->dev_addr);
++      if (rc) {
+               dev_warn(dev, "No MAC address found, using random\n");
+               eth_hw_addr_random(ndev);
+       }
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -618,7 +618,6 @@ static int ath9k_of_init(struct ath_soft
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       enum ath_bus_type bus_type = common->bus_ops->ath_bus_type;
+-      const char *mac;
+       char eeprom_name[100];
+       int ret;
+@@ -641,9 +640,7 @@ static int ath9k_of_init(struct ath_soft
+               ah->ah_flags |= AH_NO_EEP_SWAP;
+       }
+-      mac = of_get_mac_address(np);
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(common->macaddr, mac);
++      of_get_mac_address(np, common->macaddr);
+       return 0;
+ }
+--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
+@@ -90,15 +90,9 @@ out_put_node:
+ void
+ mt76_eeprom_override(struct mt76_dev *dev)
+ {
+-#ifdef CONFIG_OF
+       struct device_node *np = dev->dev->of_node;
+-      const u8 *mac = NULL;
+-      if (np)
+-              mac = of_get_mac_address(np);
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(dev->macaddr, mac);
+-#endif
++      of_get_mac_address(np, dev->macaddr);
+       if (!is_valid_ether_addr(dev->macaddr)) {
+               eth_random_addr(dev->macaddr);
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -990,11 +990,7 @@ static void rt2x00lib_rate(struct ieee80
+ void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
+ {
+-      const char *mac_addr;
+-
+-      mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(eeprom_mac_addr, mac_addr);
++      of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr);
+       if (!is_valid_ether_addr(eeprom_mac_addr)) {
+               eth_random_addr(eeprom_mac_addr);
+--- a/drivers/of/of_net.c
++++ b/drivers/of/of_net.c
+@@ -45,37 +45,29 @@ int of_get_phy_mode(struct device_node *
+ }
+ EXPORT_SYMBOL_GPL(of_get_phy_mode);
+-static const void *of_get_mac_addr(struct device_node *np, const char *name)
++static int of_get_mac_addr(struct device_node *np, const char *name, u8 *addr)
+ {
+       struct property *pp = of_find_property(np, name, NULL);
+-      if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value))
+-              return pp->value;
+-      return NULL;
++      if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value)) {
++              memcpy(addr, pp->value, ETH_ALEN);
++              return 0;
++      }
++      return -ENODEV;
+ }
+-static const void *of_get_mac_addr_nvmem(struct device_node *np)
++static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
+ {
+-      int ret;
+-      const void *mac;
+-      u8 nvmem_mac[ETH_ALEN];
+       struct platform_device *pdev = of_find_device_by_node(np);
++      int ret;
+       if (!pdev)
+-              return ERR_PTR(-ENODEV);
++              return -ENODEV;
+-      ret = nvmem_get_mac_address(&pdev->dev, &nvmem_mac);
+-      if (ret) {
+-              put_device(&pdev->dev);
+-              return ERR_PTR(ret);
+-      }
+-
+-      mac = devm_kmemdup(&pdev->dev, nvmem_mac, ETH_ALEN, GFP_KERNEL);
++      ret = nvmem_get_mac_address(&pdev->dev, addr);
+       put_device(&pdev->dev);
+-      if (!mac)
+-              return ERR_PTR(-ENOMEM);
+-      return mac;
++      return ret;
+ }
+ /**
+@@ -98,24 +90,27 @@ static const void *of_get_mac_addr_nvmem
+  * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
+  * but is all zeros.
+  *
+- * Return: Will be a valid pointer on success and ERR_PTR in case of error.
++ * Return: 0 on success and errno in case of error.
+ */
+-const void *of_get_mac_address(struct device_node *np)
++int of_get_mac_address(struct device_node *np, u8 *addr)
+ {
+-      const void *addr;
+-
+-      addr = of_get_mac_addr(np, "mac-address");
+-      if (addr)
+-              return addr;
++      int ret;
+-      addr = of_get_mac_addr(np, "local-mac-address");
+-      if (addr)
+-              return addr;
++      if (!np)
++              return -ENODEV;
+-      addr = of_get_mac_addr(np, "address");
+-      if (addr)
+-              return addr;
++      ret = of_get_mac_addr(np, "mac-address", addr);
++      if (!ret)
++              return 0;
++
++      ret = of_get_mac_addr(np, "local-mac-address", addr);
++      if (!ret)
++              return 0;
++
++      ret = of_get_mac_addr(np, "address", addr);
++      if (!ret)
++              return 0;
+-      return of_get_mac_addr_nvmem(np);
++      return of_get_mac_addr_nvmem(np, addr);
+ }
+ EXPORT_SYMBOL(of_get_mac_address);
+--- a/drivers/staging/octeon/ethernet.c
++++ b/drivers/staging/octeon/ethernet.c
+@@ -407,14 +407,10 @@ static int cvm_oct_common_set_mac_addres
+ int cvm_oct_common_init(struct net_device *dev)
+ {
+       struct octeon_ethernet *priv = netdev_priv(dev);
+-      const u8 *mac = NULL;
++      int ret;
+-      if (priv->of_node)
+-              mac = of_get_mac_address(priv->of_node);
+-
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(dev->dev_addr, mac);
+-      else
++      ret = of_get_mac_address(priv->of_node, dev->dev_addr);
++      if (ret)
+               eth_hw_addr_random(dev);
+       /*
+--- a/drivers/staging/wfx/main.c
++++ b/drivers/staging/wfx/main.c
+@@ -334,7 +334,6 @@ int wfx_probe(struct wfx_dev *wdev)
+ {
+       int i;
+       int err;
+-      const void *macaddr;
+       struct gpio_desc *gpio_saved;
+       // During first part of boot, gpio_wakeup cannot yet been used. So
+@@ -423,9 +422,9 @@ int wfx_probe(struct wfx_dev *wdev)
+       for (i = 0; i < ARRAY_SIZE(wdev->addresses); i++) {
+               eth_zero_addr(wdev->addresses[i].addr);
+-              macaddr = of_get_mac_address(wdev->dev->of_node);
+-              if (!IS_ERR_OR_NULL(macaddr)) {
+-                      ether_addr_copy(wdev->addresses[i].addr, macaddr);
++              err = of_get_mac_address(wdev->dev->of_node,
++                                       wdev->addresses[i].addr);
++              if (!err) {
+                       wdev->addresses[i].addr[ETH_ALEN - 1] += i;
+               } else {
+                       ether_addr_copy(wdev->addresses[i].addr,
+--- a/include/linux/of_net.h
++++ b/include/linux/of_net.h
+@@ -13,7 +13,7 @@
+ struct net_device;
+ extern int of_get_phy_mode(struct device_node *np, phy_interface_t *interface);
+-extern const void *of_get_mac_address(struct device_node *np);
++extern int of_get_mac_address(struct device_node *np, u8 *mac);
+ extern struct net_device *of_find_net_device_by_node(struct device_node *np);
+ #else
+ static inline int of_get_phy_mode(struct device_node *np,
+@@ -22,9 +22,9 @@ static inline int of_get_phy_mode(struct
+       return -ENODEV;
+ }
+-static inline const void *of_get_mac_address(struct device_node *np)
++static inline int of_get_mac_address(struct device_node *np, u8 *mac)
+ {
+-      return ERR_PTR(-ENODEV);
++      return -ENODEV;
+ }
+ static inline struct net_device *of_find_net_device_by_node(struct device_node *np)
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -208,7 +208,7 @@ struct dsa_port {
+       unsigned int            index;
+       const char              *name;
+       struct dsa_port         *cpu_dp;
+-      const char              *mac;
++      u8                      mac[ETH_ALEN];
+       struct device_node      *dn;
+       unsigned int            ageing_time;
+       bool                    vlan_filtering;
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -288,7 +288,7 @@ static int dsa_port_setup(struct dsa_por
+               break;
+       case DSA_PORT_TYPE_USER:
+-              dp->mac = of_get_mac_address(dp->dn);
++              of_get_mac_address(dp->dn, dp->mac);
+               err = dsa_slave_create(dp);
+               if (err)
+                       break;
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -1855,7 +1855,7 @@ int dsa_slave_create(struct dsa_port *po
+       slave_dev->hw_features |= NETIF_F_HW_TC;
+       slave_dev->features |= NETIF_F_LLTX;
+       slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
+-      if (!IS_ERR_OR_NULL(port->mac))
++      if (!is_zero_ether_addr(port->mac))
+               ether_addr_copy(slave_dev->dev_addr, port->mac);
+       else
+               eth_hw_addr_inherit(slave_dev, master);
+--- a/net/ethernet/eth.c
++++ b/net/ethernet/eth.c
+@@ -506,13 +506,14 @@ unsigned char * __weak arch_get_platform
+ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+ {
+-      const unsigned char *addr = NULL;
++      unsigned char *addr;
++      int ret;
+-      if (dev->of_node)
+-              addr = of_get_mac_address(dev->of_node);
+-      if (IS_ERR_OR_NULL(addr))
+-              addr = arch_get_platform_mac_address();
++      ret = of_get_mac_address(dev->of_node, mac_addr);
++      if (!ret)
++              return 0;
++      addr = arch_get_platform_mac_address();
+       if (!addr)
+               return -ENODEV;
diff --git a/target/linux/generic/backport-5.10/732-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch b/target/linux/generic/backport-5.10/732-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch
new file mode 100644 (file)
index 0000000..245c5f3
--- /dev/null
@@ -0,0 +1,77 @@
+From f10843e04a075202dbb39dfcee047e3a2fdf5a8d Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Mon, 12 Apr 2021 19:47:18 +0200
+Subject: of: net: fix of_get_mac_addr_nvmem() for non-platform devices
+
+of_get_mac_address() already supports fetching the MAC address by an
+nvmem provider. But until now, it was just working for platform devices.
+Esp. it was not working for DSA ports and PCI devices. It gets more
+common that PCI devices have a device tree binding since SoCs contain
+integrated root complexes.
+
+Use the nvmem of_* binding to fetch the nvmem cells by a struct
+device_node. We still have to try to read the cell by device first
+because there might be a nvmem_cell_lookup associated with that device.
+
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/of/of_net.c | 35 ++++++++++++++++++++++++++++++-----
+ 1 file changed, 30 insertions(+), 5 deletions(-)
+
+--- a/drivers/of/of_net.c
++++ b/drivers/of/of_net.c
+@@ -11,6 +11,7 @@
+ #include <linux/phy.h>
+ #include <linux/export.h>
+ #include <linux/device.h>
++#include <linux/nvmem-consumer.h>
+ /**
+  * of_get_phy_mode - Get phy mode for given device_node
+@@ -59,15 +60,39 @@ static int of_get_mac_addr(struct device
+ static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
+ {
+       struct platform_device *pdev = of_find_device_by_node(np);
++      struct nvmem_cell *cell;
++      const void *mac;
++      size_t len;
+       int ret;
+-      if (!pdev)
+-              return -ENODEV;
++      /* Try lookup by device first, there might be a nvmem_cell_lookup
++       * associated with a given device.
++       */
++      if (pdev) {
++              ret = nvmem_get_mac_address(&pdev->dev, addr);
++              put_device(&pdev->dev);
++              return ret;
++      }
++
++      cell = of_nvmem_cell_get(np, "mac-address");
++      if (IS_ERR(cell))
++              return PTR_ERR(cell);
++
++      mac = nvmem_cell_read(cell, &len);
++      nvmem_cell_put(cell);
++
++      if (IS_ERR(mac))
++              return PTR_ERR(mac);
++
++      if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
++              kfree(mac);
++              return -EINVAL;
++      }
+-      ret = nvmem_get_mac_address(&pdev->dev, addr);
+-      put_device(&pdev->dev);
++      memcpy(addr, mac, ETH_ALEN);
++      kfree(mac);
+-      return ret;
++      return 0;
+ }
+ /**
diff --git a/target/linux/generic/backport-5.10/733-v5.15-0001-net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch b/target/linux/generic/backport-5.10/733-v5.15-0001-net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch
new file mode 100644 (file)
index 0000000..6e7f206
--- /dev/null
@@ -0,0 +1,42 @@
+From 029497e66bdc762e001880e4c85a91f35a54b1e2 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Sun, 19 Sep 2021 13:57:25 +0200
+Subject: [PATCH] net: bgmac-bcma: handle deferred probe error due to
+ mac-address
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Due to the inclusion of nvmem handling into the mac-address getter
+function of_get_mac_address() by
+commit d01f449c008a ("of_net: add NVMEM support to of_get_mac_address")
+it is now possible to get a -EPROBE_DEFER return code. Which did cause
+bgmac to assign a random ethernet address.
+
+This exact issue happened on my Meraki MR32. The nvmem provider is
+an EEPROM (at24c64) which gets instantiated once the module
+driver is loaded... This happens once the filesystem becomes available.
+
+With this patch, bgmac_probe() will propagate the -EPROBE_DEFER error.
+Then the driver subsystem will reschedule the probe at a later time.
+
+Cc: Petr Štetiar <ynezz@true.cz>
+Cc: Michael Walle <michael@walle.cc>
+Fixes: d01f449c008a ("of_net: add NVMEM support to of_get_mac_address")
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/broadcom/bgmac-bcma.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
+@@ -129,6 +129,8 @@ static int bgmac_probe(struct bcma_devic
+       bcma_set_drvdata(core, bgmac);
+       err = of_get_mac_address(bgmac->dev->of_node, bgmac->net_dev->dev_addr);
++      if (err == -EPROBE_DEFER)
++              return err;
+       /* If no MAC address assigned via device tree, check SPROM */
+       if (err) {
diff --git a/target/linux/generic/backport-5.10/733-v5.15-0002-net-bgmac-platform-handle-mac-address-deferral.patch b/target/linux/generic/backport-5.10/733-v5.15-0002-net-bgmac-platform-handle-mac-address-deferral.patch
new file mode 100644 (file)
index 0000000..bde62f3
--- /dev/null
@@ -0,0 +1,36 @@
+From 763716a55cb1f480ffe1a9702e6b5d9ea1a80a24 Mon Sep 17 00:00:00 2001
+From: Matthew Hagan <mnhagan88@gmail.com>
+Date: Sat, 25 Sep 2021 11:36:27 +0000
+Subject: [PATCH] net: bgmac-platform: handle mac-address deferral
+
+This patch is a replication of Christian Lamparter's "net: bgmac-bcma:
+handle deferred probe error due to mac-address" patch for the
+bgmac-platform driver [1].
+
+As is the case with the bgmac-bcma driver, this change is to cover the
+scenario where the MAC address cannot yet be discovered due to reliance
+on an nvmem provider which is yet to be instantiated, resulting in a
+random address being assigned that has to be manually overridden.
+
+[1] https://lore.kernel.org/netdev/20210919115725.29064-1-chunkeey@gmail.com
+
+Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/broadcom/bgmac-platform.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
++++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
+@@ -193,6 +193,9 @@ static int bgmac_probe(struct platform_d
+       bgmac->dma_dev = &pdev->dev;
+       ret = of_get_mac_address(np, bgmac->net_dev->dev_addr);
++      if (ret == -EPROBE_DEFER)
++              return ret;
++
+       if (ret)
+               dev_warn(&pdev->dev,
+                        "MAC address not present in device tree\n");
diff --git a/target/linux/generic/backport-5.10/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch b/target/linux/generic/backport-5.10/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch
new file mode 100644 (file)
index 0000000..6788a2e
--- /dev/null
@@ -0,0 +1,84 @@
+From b5375509184dc23d2b7fa0c5ed8763899ccc9674 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Sat, 2 Oct 2021 19:58:11 +0200
+Subject: [PATCH] net: bgmac: improve handling PHY
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+1. Use info from DT if available
+
+It allows describing for example a fixed link. It's more accurate than
+just guessing there may be one (depending on a chipset).
+
+2. Verify PHY ID before trying to connect PHY
+
+PHY addr 0x1e (30) is special in Broadcom routers and means a switch
+connected as MDIO devices instead of a real PHY. Don't try connecting to
+it.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/broadcom/bgmac-bcma.c | 33 ++++++++++++++--------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
+@@ -11,6 +11,7 @@
+ #include <linux/bcma/bcma.h>
+ #include <linux/brcmphy.h>
+ #include <linux/etherdevice.h>
++#include <linux/of_mdio.h>
+ #include <linux/of_net.h>
+ #include "bgmac.h"
+@@ -86,17 +87,28 @@ static int bcma_phy_connect(struct bgmac
+       struct phy_device *phy_dev;
+       char bus_id[MII_BUS_ID_SIZE + 3];
++      /* DT info should be the most accurate */
++      phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
++                                       bgmac_adjust_link);
++      if (phy_dev)
++              return 0;
++
+       /* Connect to the PHY */
+-      snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
+-               bgmac->phyaddr);
+-      phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
+-                            PHY_INTERFACE_MODE_MII);
+-      if (IS_ERR(phy_dev)) {
+-              dev_err(bgmac->dev, "PHY connection failed\n");
+-              return PTR_ERR(phy_dev);
++      if (bgmac->mii_bus && bgmac->phyaddr != BGMAC_PHY_NOREGS) {
++              snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
++                       bgmac->phyaddr);
++              phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
++                                    PHY_INTERFACE_MODE_MII);
++              if (IS_ERR(phy_dev)) {
++                      dev_err(bgmac->dev, "PHY connection failed\n");
++                      return PTR_ERR(phy_dev);
++              }
++
++              return 0;
+       }
+-      return 0;
++      /* Assume a fixed link to the switch port */
++      return bgmac_phy_connect_direct(bgmac);
+ }
+ static const struct bcma_device_id bgmac_bcma_tbl[] = {
+@@ -297,10 +309,7 @@ static int bgmac_probe(struct bcma_devic
+       bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset;
+       bgmac->get_bus_clock = bcma_bgmac_get_bus_clock;
+       bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32;
+-      if (bgmac->mii_bus)
+-              bgmac->phy_connect = bcma_phy_connect;
+-      else
+-              bgmac->phy_connect = bgmac_phy_connect_direct;
++      bgmac->phy_connect = bcma_phy_connect;
+       err = bgmac_enet_probe(bgmac);
+       if (err)
diff --git a/target/linux/generic/backport-5.10/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch b/target/linux/generic/backport-5.10/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch
new file mode 100644 (file)
index 0000000..f134828
--- /dev/null
@@ -0,0 +1,54 @@
+From 45c9d966688e7fad7f24bfc450547d91e4304d0b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Sat, 2 Oct 2021 19:58:12 +0200
+Subject: [PATCH] net: bgmac: support MDIO described in DT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Check ethernet controller DT node for "mdio" subnode and use it with
+of_mdiobus_register() when present. That allows specifying MDIO and its
+PHY devices in a standard DT based way.
+
+This is required for BCM53573 SoC support. That family is sometimes
+called Northstar (by marketing?) but is quite different from it. It uses
+different CPU(s) and many different hw blocks.
+
+One of shared blocks in BCM53573 is Ethernet controller. Switch however
+is not SRAB accessible (as it Northstar) but is MDIO attached.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
+@@ -10,6 +10,7 @@
+ #include <linux/bcma/bcma.h>
+ #include <linux/brcmphy.h>
++#include <linux/of_mdio.h>
+ #include "bgmac.h"
+ static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask,
+@@ -211,6 +212,7 @@ struct mii_bus *bcma_mdio_mii_register(s
+ {
+       struct bcma_device *core = bgmac->bcma.core;
+       struct mii_bus *mii_bus;
++      struct device_node *np;
+       int err;
+       mii_bus = mdiobus_alloc();
+@@ -229,7 +231,9 @@ struct mii_bus *bcma_mdio_mii_register(s
+       mii_bus->parent = &core->dev;
+       mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
+-      err = mdiobus_register(mii_bus);
++      np = of_get_child_by_name(core->dev.of_node, "mdio");
++
++      err = of_mdiobus_register(mii_bus, np);
+       if (err) {
+               dev_err(&core->dev, "Registration of mii bus failed\n");
+               goto err_free_bus;
diff --git a/target/linux/generic/backport-5.10/735-v5.14-01-net-dsa-qca8k-change-simple-print-to-dev-variant.patch b/target/linux/generic/backport-5.10/735-v5.14-01-net-dsa-qca8k-change-simple-print-to-dev-variant.patch
new file mode 100644 (file)
index 0000000..b8e6d9b
--- /dev/null
@@ -0,0 +1,35 @@
+From 5d9e068402dcf7354cc8ee66c2152845306d2ccb Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:51 +0200
+Subject: [PATCH] net: dsa: qca8k: change simple print to dev variant
+
+Change pr_err and pr_warn to dev variant.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -701,7 +701,7 @@ qca8k_setup(struct dsa_switch *ds)
+       /* Make sure that port 0 is the cpu port */
+       if (!dsa_is_cpu_port(ds, 0)) {
+-              pr_err("port 0 is not the CPU port\n");
++              dev_err(priv->dev, "port 0 is not the CPU port");
+               return -EINVAL;
+       }
+@@ -711,7 +711,7 @@ qca8k_setup(struct dsa_switch *ds)
+       priv->regmap = devm_regmap_init(ds->dev, NULL, priv,
+                                       &qca8k_regmap_config);
+       if (IS_ERR(priv->regmap))
+-              pr_warn("regmap initialization failed");
++              dev_warn(priv->dev, "regmap initialization failed");
+       ret = qca8k_setup_mdio_bus(priv);
+       if (ret)
diff --git a/target/linux/generic/backport-5.10/735-v5.14-02-net-dsa-qca8k-use-iopoll-macro-for-qca8k_busy_wait.patch b/target/linux/generic/backport-5.10/735-v5.14-02-net-dsa-qca8k-use-iopoll-macro-for-qca8k_busy_wait.patch
new file mode 100644 (file)
index 0000000..ff8288d
--- /dev/null
@@ -0,0 +1,61 @@
+From 2ad255f2faaffb3af786031fba2e7955454b558a Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:52 +0200
+Subject: [PATCH] net: dsa: qca8k: use iopoll macro for qca8k_busy_wait
+
+Use iopoll macro instead of while loop.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 23 +++++++++++------------
+ drivers/net/dsa/qca8k.h |  2 ++
+ 2 files changed, 13 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -262,21 +262,20 @@ static struct regmap_config qca8k_regmap
+ static int
+ qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
+ {
+-      unsigned long timeout;
++      u32 val;
++      int ret;
+-      timeout = jiffies + msecs_to_jiffies(20);
++      ret = read_poll_timeout(qca8k_read, val, !(val & mask),
++                              0, QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
++                              priv, reg);
+-      /* loop until the busy flag has cleared */
+-      do {
+-              u32 val = qca8k_read(priv, reg);
+-              int busy = val & mask;
++      /* Check if qca8k_read has failed for a different reason
++       * before returning -ETIMEDOUT
++       */
++      if (ret < 0 && val < 0)
++              return val;
+-              if (!busy)
+-                      break;
+-              cond_resched();
+-      } while (!time_after_eq(jiffies, timeout));
+-
+-      return time_after_eq(jiffies, timeout);
++      return ret;
+ }
+ static void
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -18,6 +18,8 @@
+ #define PHY_ID_QCA8337                                        0x004dd036
+ #define QCA8K_ID_QCA8337                              0x13
++#define QCA8K_BUSY_WAIT_TIMEOUT                               20
++
+ #define QCA8K_NUM_FDB_RECORDS                         2048
+ #define QCA8K_CPU_PORT                                        0
diff --git a/target/linux/generic/backport-5.10/735-v5.14-03-net-dsa-qca8k-improve-qca8k-read-write-rmw-bus-acces.patch b/target/linux/generic/backport-5.10/735-v5.14-03-net-dsa-qca8k-improve-qca8k-read-write-rmw-bus-acces.patch
new file mode 100644 (file)
index 0000000..c403589
--- /dev/null
@@ -0,0 +1,86 @@
+From 504bf65931824eda83494e5b5d75686e27ace03e Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:53 +0200
+Subject: [PATCH] net: dsa: qca8k: improve qca8k read/write/rmw bus access
+
+Put bus in local variable to improve faster access to the mdio bus.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 29 ++++++++++++++++-------------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -142,17 +142,18 @@ qca8k_set_page(struct mii_bus *bus, u16
+ static u32
+ qca8k_read(struct qca8k_priv *priv, u32 reg)
+ {
++      struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+       u32 val;
+       qca8k_split_addr(reg, &r1, &r2, &page);
+-      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      qca8k_set_page(priv->bus, page);
+-      val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
++      qca8k_set_page(bus, page);
++      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
+-      mutex_unlock(&priv->bus->mdio_lock);
++      mutex_unlock(&bus->mdio_lock);
+       return val;
+ }
+@@ -160,35 +161,37 @@ qca8k_read(struct qca8k_priv *priv, u32
+ static void
+ qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
+ {
++      struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+       qca8k_split_addr(reg, &r1, &r2, &page);
+-      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      qca8k_set_page(priv->bus, page);
+-      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
++      qca8k_set_page(bus, page);
++      qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+-      mutex_unlock(&priv->bus->mdio_lock);
++      mutex_unlock(&bus->mdio_lock);
+ }
+ static u32
+ qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 val)
+ {
++      struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+       u32 ret;
+       qca8k_split_addr(reg, &r1, &r2, &page);
+-      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      qca8k_set_page(priv->bus, page);
+-      ret = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
++      qca8k_set_page(bus, page);
++      ret = qca8k_mii_read32(bus, 0x10 | r2, r1);
+       ret &= ~mask;
+       ret |= val;
+-      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, ret);
++      qca8k_mii_write32(bus, 0x10 | r2, r1, ret);
+-      mutex_unlock(&priv->bus->mdio_lock);
++      mutex_unlock(&bus->mdio_lock);
+       return ret;
+ }
diff --git a/target/linux/generic/backport-5.10/735-v5.14-04-net-dsa-qca8k-handle-qca8k_set_page-errors.patch b/target/linux/generic/backport-5.10/735-v5.14-04-net-dsa-qca8k-handle-qca8k_set_page-errors.patch
new file mode 100644 (file)
index 0000000..6be494a
--- /dev/null
@@ -0,0 +1,101 @@
+From ba5707ec58cfb6853dff41c2aae72deb6a03d389 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:54 +0200
+Subject: [PATCH] net: dsa: qca8k: handle qca8k_set_page errors
+
+With a remote possibility, the set_page function can fail. Since this is
+a critical part of the write/read qca8k regs, propagate the error and
+terminate any read/write operation.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 33 ++++++++++++++++++++++++++-------
+ 1 file changed, 26 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -127,16 +127,23 @@ qca8k_mii_write32(struct mii_bus *bus, i
+                                   "failed to write qca8k 32bit register\n");
+ }
+-static void
++static int
+ qca8k_set_page(struct mii_bus *bus, u16 page)
+ {
++      int ret;
++
+       if (page == qca8k_current_page)
+-              return;
++              return 0;
+-      if (bus->write(bus, 0x18, 0, page) < 0)
++      ret = bus->write(bus, 0x18, 0, page);
++      if (ret < 0) {
+               dev_err_ratelimited(&bus->dev,
+                                   "failed to set qca8k page\n");
++              return ret;
++      }
++
+       qca8k_current_page = page;
++      return 0;
+ }
+ static u32
+@@ -150,11 +157,14 @@ qca8k_read(struct qca8k_priv *priv, u32
+       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      qca8k_set_page(bus, page);
++      val = qca8k_set_page(bus, page);
++      if (val < 0)
++              goto exit;
++
+       val = qca8k_mii_read32(bus, 0x10 | r2, r1);
++exit:
+       mutex_unlock(&bus->mdio_lock);
+-
+       return val;
+ }
+@@ -163,14 +173,19 @@ qca8k_write(struct qca8k_priv *priv, u32
+ {
+       struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
++      int ret;
+       qca8k_split_addr(reg, &r1, &r2, &page);
+       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      qca8k_set_page(bus, page);
++      ret = qca8k_set_page(bus, page);
++      if (ret < 0)
++              goto exit;
++
+       qca8k_mii_write32(bus, 0x10 | r2, r1, val);
++exit:
+       mutex_unlock(&bus->mdio_lock);
+ }
+@@ -185,12 +200,16 @@ qca8k_rmw(struct qca8k_priv *priv, u32 r
+       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      qca8k_set_page(bus, page);
++      ret = qca8k_set_page(bus, page);
++      if (ret < 0)
++              goto exit;
++
+       ret = qca8k_mii_read32(bus, 0x10 | r2, r1);
+       ret &= ~mask;
+       ret |= val;
+       qca8k_mii_write32(bus, 0x10 | r2, r1, ret);
++exit:
+       mutex_unlock(&bus->mdio_lock);
+       return ret;
diff --git a/target/linux/generic/backport-5.10/735-v5.14-05-net-dsa-qca8k-handle-error-with-qca8k_read-operation.patch b/target/linux/generic/backport-5.10/735-v5.14-05-net-dsa-qca8k-handle-error-with-qca8k_read-operation.patch
new file mode 100644 (file)
index 0000000..3349b78
--- /dev/null
@@ -0,0 +1,207 @@
+From 028f5f8ef44fcf87a456772cbb9f0d90a0a22884 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:55 +0200
+Subject: [PATCH] net: dsa: qca8k: handle error with qca8k_read operation
+
+qca8k_read can fail. Rework any user to handle error values and
+correctly return.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 73 ++++++++++++++++++++++++++++++++---------
+ 1 file changed, 58 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -231,8 +231,13 @@ static int
+ qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
++      int ret;
++
++      ret = qca8k_read(priv, reg);
++      if (ret < 0)
++              return ret;
+-      *val = qca8k_read(priv, reg);
++      *val = ret;
+       return 0;
+ }
+@@ -300,15 +305,20 @@ qca8k_busy_wait(struct qca8k_priv *priv,
+       return ret;
+ }
+-static void
++static int
+ qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
+ {
+-      u32 reg[4];
++      u32 reg[4], val;
+       int i;
+       /* load the ARL table into an array */
+-      for (i = 0; i < 4; i++)
+-              reg[i] = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4));
++      for (i = 0; i < 4; i++) {
++              val = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4));
++              if (val < 0)
++                      return val;
++
++              reg[i] = val;
++      }
+       /* vid - 83:72 */
+       fdb->vid = (reg[2] >> QCA8K_ATU_VID_S) & QCA8K_ATU_VID_M;
+@@ -323,6 +333,8 @@ qca8k_fdb_read(struct qca8k_priv *priv,
+       fdb->mac[3] = (reg[0] >> QCA8K_ATU_ADDR3_S) & 0xff;
+       fdb->mac[4] = (reg[0] >> QCA8K_ATU_ADDR4_S) & 0xff;
+       fdb->mac[5] = reg[0] & 0xff;
++
++      return 0;
+ }
+ static void
+@@ -374,6 +386,8 @@ qca8k_fdb_access(struct qca8k_priv *priv
+       /* Check for table full violation when adding an entry */
+       if (cmd == QCA8K_FDB_LOAD) {
+               reg = qca8k_read(priv, QCA8K_REG_ATU_FUNC);
++              if (reg < 0)
++                      return reg;
+               if (reg & QCA8K_ATU_FUNC_FULL)
+                       return -1;
+       }
+@@ -388,10 +402,10 @@ qca8k_fdb_next(struct qca8k_priv *priv,
+       qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
+       ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
+-      if (ret >= 0)
+-              qca8k_fdb_read(priv, fdb);
++      if (ret < 0)
++              return ret;
+-      return ret;
++      return qca8k_fdb_read(priv, fdb);
+ }
+ static int
+@@ -449,6 +463,8 @@ qca8k_vlan_access(struct qca8k_priv *pri
+       /* Check for table full violation when adding an entry */
+       if (cmd == QCA8K_VLAN_LOAD) {
+               reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
++              if (reg < 0)
++                      return reg;
+               if (reg & QCA8K_VTU_FUNC1_FULL)
+                       return -ENOMEM;
+       }
+@@ -475,6 +491,8 @@ qca8k_vlan_add(struct qca8k_priv *priv,
+               goto out;
+       reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
++      if (reg < 0)
++              return reg;
+       reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
+       reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+       if (untagged)
+@@ -506,6 +524,8 @@ qca8k_vlan_del(struct qca8k_priv *priv,
+               goto out;
+       reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
++      if (reg < 0)
++              return reg;
+       reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+       reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
+                       QCA8K_VTU_FUNC0_EG_MODE_S(port);
+@@ -621,8 +641,11 @@ qca8k_mdio_read(struct qca8k_priv *priv,
+                           QCA8K_MDIO_MASTER_BUSY))
+               return -ETIMEDOUT;
+-      val = (qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL) &
+-              QCA8K_MDIO_MASTER_DATA_MASK);
++      val = qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL);
++      if (val < 0)
++              return val;
++
++      val &= QCA8K_MDIO_MASTER_DATA_MASK;
+       return val;
+ }
+@@ -978,6 +1001,8 @@ qca8k_phylink_mac_link_state(struct dsa_
+       u32 reg;
+       reg = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port));
++      if (reg < 0)
++              return reg;
+       state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
+       state->an_complete = state->link;
+@@ -1078,18 +1103,26 @@ qca8k_get_ethtool_stats(struct dsa_switc
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+       const struct qca8k_mib_desc *mib;
+-      u32 reg, i;
++      u32 reg, i, val;
+       u64 hi;
+       for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
+               mib = &ar8327_mib[i];
+               reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
+-              data[i] = qca8k_read(priv, reg);
++              val = qca8k_read(priv, reg);
++              if (val < 0)
++                      continue;
++
+               if (mib->size == 2) {
+                       hi = qca8k_read(priv, reg + 4);
+-                      data[i] |= hi << 32;
++                      if (hi < 0)
++                              continue;
+               }
++
++              data[i] = val;
++              if (mib->size == 2)
++                      data[i] |= hi << 32;
+       }
+ }
+@@ -1107,18 +1140,25 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+       u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
++      int ret = 0;
+       u32 reg;
+       mutex_lock(&priv->reg_mutex);
+       reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL);
++      if (reg < 0) {
++              ret = reg;
++              goto exit;
++      }
++
+       if (eee->eee_enabled)
+               reg |= lpi_en;
+       else
+               reg &= ~lpi_en;
+       qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
+-      mutex_unlock(&priv->reg_mutex);
+-      return 0;
++exit:
++      mutex_unlock(&priv->reg_mutex);
++      return ret;
+ }
+ static int
+@@ -1456,6 +1496,9 @@ qca8k_sw_probe(struct mdio_device *mdiod
+       /* read the switches ID register */
+       id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
++      if (id < 0)
++              return id;
++
+       id >>= QCA8K_MASK_CTRL_ID_S;
+       id &= QCA8K_MASK_CTRL_ID_M;
+       if (id != QCA8K_ID_QCA8337)
diff --git a/target/linux/generic/backport-5.10/735-v5.14-06-net-dsa-qca8k-handle-error-with-qca8k_write-operatio.patch b/target/linux/generic/backport-5.10/735-v5.14-06-net-dsa-qca8k-handle-error-with-qca8k_write-operatio.patch
new file mode 100644 (file)
index 0000000..1e0e224
--- /dev/null
@@ -0,0 +1,263 @@
+From d7805757c75c76e9518fc1023a29f0c4eed5b581 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:56 +0200
+Subject: [PATCH] net: dsa: qca8k: handle error with qca8k_write operation
+
+qca8k_write can fail. Rework any user to handle error values and
+correctly return.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 102 ++++++++++++++++++++++++++--------------
+ 1 file changed, 67 insertions(+), 35 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -168,7 +168,7 @@ exit:
+       return val;
+ }
+-static void
++static int
+ qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
+ {
+       struct mii_bus *bus = priv->bus;
+@@ -187,6 +187,7 @@ qca8k_write(struct qca8k_priv *priv, u32
+ exit:
+       mutex_unlock(&bus->mdio_lock);
++      return ret;
+ }
+ static u32
+@@ -247,9 +248,7 @@ qca8k_regmap_write(void *ctx, uint32_t r
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
+-      qca8k_write(priv, reg, val);
+-
+-      return 0;
++      return qca8k_write(priv, reg, val);
+ }
+ static const struct regmap_range qca8k_readable_ranges[] = {
+@@ -367,6 +366,7 @@ static int
+ qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
+ {
+       u32 reg;
++      int ret;
+       /* Set the command and FDB index */
+       reg = QCA8K_ATU_FUNC_BUSY;
+@@ -377,7 +377,9 @@ qca8k_fdb_access(struct qca8k_priv *priv
+       }
+       /* Write the function register triggering the table access */
+-      qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
++      ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
++      if (ret)
++              return ret;
+       /* wait for completion */
+       if (qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY))
+@@ -447,6 +449,7 @@ static int
+ qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
+ {
+       u32 reg;
++      int ret;
+       /* Set the command and VLAN index */
+       reg = QCA8K_VTU_FUNC1_BUSY;
+@@ -454,7 +457,9 @@ qca8k_vlan_access(struct qca8k_priv *pri
+       reg |= vid << QCA8K_VTU_FUNC1_VID_S;
+       /* Write the function register triggering the table access */
+-      qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
++      ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
++      if (ret)
++              return ret;
+       /* wait for completion */
+       if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
+@@ -502,7 +507,9 @@ qca8k_vlan_add(struct qca8k_priv *priv,
+               reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
+                               QCA8K_VTU_FUNC0_EG_MODE_S(port);
+-      qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
++      ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
++      if (ret)
++              return ret;
+       ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+ out:
+@@ -545,7 +552,9 @@ qca8k_vlan_del(struct qca8k_priv *priv,
+       if (del) {
+               ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
+       } else {
+-              qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
++              ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
++              if (ret)
++                      return ret;
+               ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+       }
+@@ -555,15 +564,20 @@ out:
+       return ret;
+ }
+-static void
++static int
+ qca8k_mib_init(struct qca8k_priv *priv)
+ {
++      int ret;
++
+       mutex_lock(&priv->reg_mutex);
+       qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
+       qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
+       qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
+-      qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
++
++      ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
++
+       mutex_unlock(&priv->reg_mutex);
++      return ret;
+ }
+ static void
+@@ -600,6 +614,7 @@ static int
+ qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
+ {
+       u32 phy, val;
++      int ret;
+       if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
+               return -EINVAL;
+@@ -613,7 +628,9 @@ qca8k_mdio_write(struct qca8k_priv *priv
+             QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
+             QCA8K_MDIO_MASTER_DATA(data);
+-      qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
++      ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
++      if (ret)
++              return ret;
+       return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+               QCA8K_MDIO_MASTER_BUSY);
+@@ -623,6 +640,7 @@ static int
+ qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
+ {
+       u32 phy, val;
++      int ret;
+       if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
+               return -EINVAL;
+@@ -635,7 +653,9 @@ qca8k_mdio_read(struct qca8k_priv *priv,
+             QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+             QCA8K_MDIO_MASTER_REG_ADDR(regnum);
+-      qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
++      ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
++      if (ret)
++              return ret;
+       if (qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+                           QCA8K_MDIO_MASTER_BUSY))
+@@ -766,12 +786,18 @@ qca8k_setup(struct dsa_switch *ds)
+                     QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
+       /* Enable MIB counters */
+-      qca8k_mib_init(priv);
++      ret = qca8k_mib_init(priv);
++      if (ret)
++              dev_warn(priv->dev, "mib init failed");
+       /* Enable QCA header mode on the cpu port */
+-      qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
+-                  QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
+-                  QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
++      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
++                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
++                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
++      if (ret) {
++              dev_err(priv->dev, "failed enabling QCA header mode");
++              return ret;
++      }
+       /* Disable forwarding by default on all ports */
+       for (i = 0; i < QCA8K_NUM_PORTS; i++)
+@@ -783,11 +809,13 @@ qca8k_setup(struct dsa_switch *ds)
+               qca8k_port_set_status(priv, i, 0);
+       /* Forward all unknown frames to CPU port for Linux processing */
+-      qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
+-                  BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
+-                  BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
+-                  BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
+-                  BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
++      ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
++                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
++                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
++                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
++                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
++      if (ret)
++              return ret;
+       /* Setup connection between CPU port & user ports */
+       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+@@ -815,16 +843,20 @@ qca8k_setup(struct dsa_switch *ds)
+                       qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
+                                 0xfff << shift,
+                                 QCA8K_PORT_VID_DEF << shift);
+-                      qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
+-                                  QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
+-                                  QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
++                      ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
++                                        QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
++                                        QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
++                      if (ret)
++                              return ret;
+               }
+       }
+       /* Setup our port MTUs to match power on defaults */
+       for (i = 0; i < QCA8K_NUM_PORTS; i++)
+               priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+-      qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
++      ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
++      if (ret)
++              dev_warn(priv->dev, "failed setting MTU settings");
+       /* Flush the FDB table */
+       qca8k_fdb_flush(priv);
+@@ -1140,8 +1172,8 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+       u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
+-      int ret = 0;
+       u32 reg;
++      int ret;
+       mutex_lock(&priv->reg_mutex);
+       reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL);
+@@ -1154,7 +1186,7 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
+               reg |= lpi_en;
+       else
+               reg &= ~lpi_en;
+-      qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
++      ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
+ exit:
+       mutex_unlock(&priv->reg_mutex);
+@@ -1284,9 +1316,7 @@ qca8k_port_change_mtu(struct dsa_switch
+                       mtu = priv->port_mtu[i];
+       /* Include L2 header / FCS length */
+-      qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+-
+-      return 0;
++      return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+ }
+ static int
diff --git a/target/linux/generic/backport-5.10/735-v5.14-07-net-dsa-qca8k-handle-error-with-qca8k_rmw-operation.patch b/target/linux/generic/backport-5.10/735-v5.14-07-net-dsa-qca8k-handle-error-with-qca8k_rmw-operation.patch
new file mode 100644 (file)
index 0000000..506966f
--- /dev/null
@@ -0,0 +1,226 @@
+From aaf421425cbdec4eb6fd75a29e65c2867b0b7bbd Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:57 +0200
+Subject: [PATCH] net: dsa: qca8k: handle error with qca8k_rmw operation
+
+qca8k_rmw can fail. Rework any user to handle error values and
+correctly return. Change qca8k_rmw to return the error code or 0 instead
+of the reg value. The reg returned by qca8k_rmw wasn't used anywhere,
+so this doesn't cause any functional change.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 133 +++++++++++++++++++++++++---------------
+ 1 file changed, 83 insertions(+), 50 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -190,12 +190,13 @@ exit:
+       return ret;
+ }
+-static u32
+-qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 val)
++static int
++qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
+ {
+       struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+-      u32 ret;
++      u32 val;
++      int ret;
+       qca8k_split_addr(reg, &r1, &r2, &page);
+@@ -205,10 +206,15 @@ qca8k_rmw(struct qca8k_priv *priv, u32 r
+       if (ret < 0)
+               goto exit;
+-      ret = qca8k_mii_read32(bus, 0x10 | r2, r1);
+-      ret &= ~mask;
+-      ret |= val;
+-      qca8k_mii_write32(bus, 0x10 | r2, r1, ret);
++      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
++      if (val < 0) {
++              ret = val;
++              goto exit;
++      }
++
++      val &= ~mask;
++      val |= write_val;
++      qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ exit:
+       mutex_unlock(&bus->mdio_lock);
+@@ -216,16 +222,16 @@ exit:
+       return ret;
+ }
+-static void
++static int
+ qca8k_reg_set(struct qca8k_priv *priv, u32 reg, u32 val)
+ {
+-      qca8k_rmw(priv, reg, 0, val);
++      return qca8k_rmw(priv, reg, 0, val);
+ }
+-static void
++static int
+ qca8k_reg_clear(struct qca8k_priv *priv, u32 reg, u32 val)
+ {
+-      qca8k_rmw(priv, reg, val, 0);
++      return qca8k_rmw(priv, reg, val, 0);
+ }
+ static int
+@@ -570,12 +576,19 @@ qca8k_mib_init(struct qca8k_priv *priv)
+       int ret;
+       mutex_lock(&priv->reg_mutex);
+-      qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
++      ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
++      if (ret)
++              goto exit;
++
+       qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
+-      qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
++
++      ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
++      if (ret)
++              goto exit;
+       ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
++exit:
+       mutex_unlock(&priv->reg_mutex);
+       return ret;
+ }
+@@ -747,9 +760,8 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
+                * a dt-overlay and driver reload changed the configuration
+                */
+-              qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
+-                              QCA8K_MDIO_MASTER_EN);
+-              return 0;
++              return qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
++                                     QCA8K_MDIO_MASTER_EN);
+       }
+       priv->ops.phy_read = qca8k_phy_read;
+@@ -782,8 +794,12 @@ qca8k_setup(struct dsa_switch *ds)
+               return ret;
+       /* Enable CPU Port */
+-      qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
+-                    QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
++      ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
++                          QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
++      if (ret) {
++              dev_err(priv->dev, "failed enabling CPU port");
++              return ret;
++      }
+       /* Enable MIB counters */
+       ret = qca8k_mib_init(priv);
+@@ -800,9 +816,12 @@ qca8k_setup(struct dsa_switch *ds)
+       }
+       /* Disable forwarding by default on all ports */
+-      for (i = 0; i < QCA8K_NUM_PORTS; i++)
+-              qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
+-                        QCA8K_PORT_LOOKUP_MEMBER, 0);
++      for (i = 0; i < QCA8K_NUM_PORTS; i++) {
++              ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
++                              QCA8K_PORT_LOOKUP_MEMBER, 0);
++              if (ret)
++                      return ret;
++      }
+       /* Disable MAC by default on all ports */
+       for (i = 1; i < QCA8K_NUM_PORTS; i++)
+@@ -821,28 +840,37 @@ qca8k_setup(struct dsa_switch *ds)
+       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+               /* CPU port gets connected to all user ports of the switch */
+               if (dsa_is_cpu_port(ds, i)) {
+-                      qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
+-                                QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
++                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
++                                      QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
++                      if (ret)
++                              return ret;
+               }
+               /* Individual user ports get connected to CPU port only */
+               if (dsa_is_user_port(ds, i)) {
+                       int shift = 16 * (i % 2);
+-                      qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
+-                                QCA8K_PORT_LOOKUP_MEMBER,
+-                                BIT(QCA8K_CPU_PORT));
++                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
++                                      QCA8K_PORT_LOOKUP_MEMBER,
++                                      BIT(QCA8K_CPU_PORT));
++                      if (ret)
++                              return ret;
+                       /* Enable ARP Auto-learning by default */
+-                      qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i),
+-                                    QCA8K_PORT_LOOKUP_LEARN);
++                      ret = qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i),
++                                          QCA8K_PORT_LOOKUP_LEARN);
++                      if (ret)
++                              return ret;
+                       /* For port based vlans to work we need to set the
+                        * default egress vid
+                        */
+-                      qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
+-                                0xfff << shift,
+-                                QCA8K_PORT_VID_DEF << shift);
++                      ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
++                                      0xfff << shift,
++                                      QCA8K_PORT_VID_DEF << shift);
++                      if (ret)
++                              return ret;
++
+                       ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
+                                         QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
+                                         QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
+@@ -1234,7 +1262,7 @@ qca8k_port_bridge_join(struct dsa_switch
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+       int port_mask = BIT(QCA8K_CPU_PORT);
+-      int i;
++      int i, ret;
+       for (i = 1; i < QCA8K_NUM_PORTS; i++) {
+               if (dsa_to_port(ds, i)->bridge_dev != br)
+@@ -1242,17 +1270,20 @@ qca8k_port_bridge_join(struct dsa_switch
+               /* Add this port to the portvlan mask of the other ports
+                * in the bridge
+                */
+-              qca8k_reg_set(priv,
+-                            QCA8K_PORT_LOOKUP_CTRL(i),
+-                            BIT(port));
++              ret = qca8k_reg_set(priv,
++                                  QCA8K_PORT_LOOKUP_CTRL(i),
++                                  BIT(port));
++              if (ret)
++                      return ret;
+               if (i != port)
+                       port_mask |= BIT(i);
+       }
++
+       /* Add all other ports to this ports portvlan mask */
+-      qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
+-                QCA8K_PORT_LOOKUP_MEMBER, port_mask);
++      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
++                      QCA8K_PORT_LOOKUP_MEMBER, port_mask);
+-      return 0;
++      return ret;
+ }
+ static void
diff --git a/target/linux/generic/backport-5.10/735-v5.14-08-net-dsa-qca8k-handle-error-from-qca8k_busy_wait.patch b/target/linux/generic/backport-5.10/735-v5.14-08-net-dsa-qca8k-handle-error-from-qca8k_busy_wait.patch
new file mode 100644 (file)
index 0000000..360ce1d
--- /dev/null
@@ -0,0 +1,66 @@
+From b7c818d194927bdc60ed15db55bb8654496a36b7 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:58 +0200
+Subject: [PATCH] net: dsa: qca8k: handle error from qca8k_busy_wait
+
+Propagate errors from qca8k_busy_wait instead of hardcoding return
+value.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -388,8 +388,9 @@ qca8k_fdb_access(struct qca8k_priv *priv
+               return ret;
+       /* wait for completion */
+-      if (qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY))
+-              return -1;
++      ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
++      if (ret)
++              return ret;
+       /* Check for table full violation when adding an entry */
+       if (cmd == QCA8K_FDB_LOAD) {
+@@ -468,8 +469,9 @@ qca8k_vlan_access(struct qca8k_priv *pri
+               return ret;
+       /* wait for completion */
+-      if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
+-              return -ETIMEDOUT;
++      ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
++      if (ret)
++              return ret;
+       /* Check for table full violation when adding an entry */
+       if (cmd == QCA8K_VLAN_LOAD) {
+@@ -580,7 +582,9 @@ qca8k_mib_init(struct qca8k_priv *priv)
+       if (ret)
+               goto exit;
+-      qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
++      ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
++      if (ret)
++              goto exit;
+       ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
+       if (ret)
+@@ -670,9 +674,10 @@ qca8k_mdio_read(struct qca8k_priv *priv,
+       if (ret)
+               return ret;
+-      if (qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+-                          QCA8K_MDIO_MASTER_BUSY))
+-              return -ETIMEDOUT;
++      ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
++                            QCA8K_MDIO_MASTER_BUSY);
++      if (ret)
++              return ret;
+       val = qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL);
+       if (val < 0)
diff --git a/target/linux/generic/backport-5.10/735-v5.14-09-net-dsa-qca8k-add-support-for-qca8327-switch.patch b/target/linux/generic/backport-5.10/735-v5.14-09-net-dsa-qca8k-add-support-for-qca8327-switch.patch
new file mode 100644 (file)
index 0000000..7230585
--- /dev/null
@@ -0,0 +1,96 @@
+From 6e82a457e06252b59102486767539cc9c2aba60b Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 22:59:59 +0200
+Subject: [PATCH] net: dsa: qca8k: add support for qca8327 switch
+
+qca8327 switch is a low tier version of the more recent qca8337.
+It does share the same regs used by the qca8k driver and can be
+supported with minimal change.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 23 ++++++++++++++++++++---
+ drivers/net/dsa/qca8k.h |  6 ++++++
+ 2 files changed, 26 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1533,6 +1533,7 @@ static const struct dsa_switch_ops qca8k
+ static int
+ qca8k_sw_probe(struct mdio_device *mdiodev)
+ {
++      const struct qca8k_match_data *data;
+       struct qca8k_priv *priv;
+       u32 id;
+@@ -1560,6 +1561,11 @@ qca8k_sw_probe(struct mdio_device *mdiod
+               gpiod_set_value_cansleep(priv->reset_gpio, 0);
+       }
++      /* get the switches ID from the compatible */
++      data = of_device_get_match_data(&mdiodev->dev);
++      if (!data)
++              return -ENODEV;
++
+       /* read the switches ID register */
+       id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
+       if (id < 0)
+@@ -1567,8 +1573,10 @@ qca8k_sw_probe(struct mdio_device *mdiod
+       id >>= QCA8K_MASK_CTRL_ID_S;
+       id &= QCA8K_MASK_CTRL_ID_M;
+-      if (id != QCA8K_ID_QCA8337)
++      if (id != data->id) {
++              dev_err(&mdiodev->dev, "Switch id detected %x but expected %x", id, data->id);
+               return -ENODEV;
++      }
+       priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
+       if (!priv->ds)
+@@ -1634,9 +1642,18 @@ static int qca8k_resume(struct device *d
+ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
+                        qca8k_suspend, qca8k_resume);
++static const struct qca8k_match_data qca832x = {
++      .id = QCA8K_ID_QCA8327,
++};
++
++static const struct qca8k_match_data qca833x = {
++      .id = QCA8K_ID_QCA8337,
++};
++
+ static const struct of_device_id qca8k_of_match[] = {
+-      { .compatible = "qca,qca8334" },
+-      { .compatible = "qca,qca8337" },
++      { .compatible = "qca,qca8327", .data = &qca832x },
++      { .compatible = "qca,qca8334", .data = &qca833x },
++      { .compatible = "qca,qca8337", .data = &qca833x },
+       { /* sentinel */ },
+ };
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -15,6 +15,8 @@
+ #define QCA8K_NUM_PORTS                                       7
+ #define QCA8K_MAX_MTU                                 9000
++#define PHY_ID_QCA8327                                        0x004dd034
++#define QCA8K_ID_QCA8327                              0x12
+ #define PHY_ID_QCA8337                                        0x004dd036
+ #define QCA8K_ID_QCA8337                              0x13
+@@ -213,6 +215,10 @@ struct ar8xxx_port_status {
+       int enabled;
+ };
++struct qca8k_match_data {
++      u8 id;
++};
++
+ struct qca8k_priv {
+       struct regmap *regmap;
+       struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.10/735-v5.14-10-devicetree-net-dsa-qca8k-Document-new-compatible-qca.patch b/target/linux/generic/backport-5.10/735-v5.14-10-devicetree-net-dsa-qca8k-Document-new-compatible-qca.patch
new file mode 100644 (file)
index 0000000..3c4a14b
--- /dev/null
@@ -0,0 +1,26 @@
+From 227a9ffc1bc77037339530607fe129af3824620e Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:00 +0200
+Subject: [PATCH] devicetree: net: dsa: qca8k: Document new compatible qca8327
+
+Add support for qca8327 in the compatible list.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Acked-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -3,6 +3,7 @@
+ Required properties:
+ - compatible: should be one of:
++    "qca,qca8327"
+     "qca,qca8334"
+     "qca,qca8337"
diff --git a/target/linux/generic/backport-5.10/735-v5.14-11-net-dsa-qca8k-add-priority-tweak-to-qca8337-switch.patch b/target/linux/generic/backport-5.10/735-v5.14-11-net-dsa-qca8k-add-priority-tweak-to-qca8337-switch.patch
new file mode 100644 (file)
index 0000000..cd3050e
--- /dev/null
@@ -0,0 +1,130 @@
+From 83a3ceb39b2495171aabe9446271b94c678354f3 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:01 +0200
+Subject: [PATCH] net: dsa: qca8k: add priority tweak to qca8337 switch
+
+The port 5 of the qca8337 have some problem in flood condition. The
+original legacy driver had some specific buffer and priority settings
+for the different port suggested by the QCA switch team. Add this
+missing settings to improve switch stability under load condition.
+The packet priority tweak is only needed for the qca8337 switch and
+other qca8k switch are not affected.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 47 +++++++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/qca8k.h | 25 ++++++++++++++++++++++
+ 2 files changed, 72 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -779,6 +779,7 @@ qca8k_setup(struct dsa_switch *ds)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+       int ret, i;
++      u32 mask;
+       /* Make sure that port 0 is the cpu port */
+       if (!dsa_is_cpu_port(ds, 0)) {
+@@ -884,6 +885,51 @@ qca8k_setup(struct dsa_switch *ds)
+               }
+       }
++      /* The port 5 of the qca8337 have some problem in flood condition. The
++       * original legacy driver had some specific buffer and priority settings
++       * for the different port suggested by the QCA switch team. Add this
++       * missing settings to improve switch stability under load condition.
++       * This problem is limited to qca8337 and other qca8k switch are not affected.
++       */
++      if (priv->switch_id == QCA8K_ID_QCA8337) {
++              for (i = 0; i < QCA8K_NUM_PORTS; i++) {
++                      switch (i) {
++                      /* The 2 CPU port and port 5 requires some different
++                       * priority than any other ports.
++                       */
++                      case 0:
++                      case 5:
++                      case 6:
++                              mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
++                              break;
++                      default:
++                              mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
++                                      QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
++                      }
++                      qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
++
++                      mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
++                      QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
++                      QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
++                      QCA8K_PORT_HOL_CTRL1_WRED_EN;
++                      qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
++                                QCA8K_PORT_HOL_CTRL1_ING_BUF |
++                                QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
++                                QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
++                                QCA8K_PORT_HOL_CTRL1_WRED_EN,
++                                mask);
++              }
++      }
++
+       /* Setup our port MTUs to match power on defaults */
+       for (i = 0; i < QCA8K_NUM_PORTS; i++)
+               priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+@@ -1578,6 +1624,7 @@ qca8k_sw_probe(struct mdio_device *mdiod
+               return -ENODEV;
+       }
++      priv->switch_id = id;
+       priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
+       if (!priv->ds)
+               return -ENOMEM;
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -168,6 +168,30 @@
+ #define   QCA8K_PORT_LOOKUP_STATE                     GENMASK(18, 16)
+ #define   QCA8K_PORT_LOOKUP_LEARN                     BIT(20)
++#define QCA8K_REG_PORT_HOL_CTRL0(_i)                  (0x970 + (_i) * 0x8)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF            GENMASK(3, 0)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI0(x)             ((x) << 0)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF            GENMASK(7, 4)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI1(x)             ((x) << 4)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF            GENMASK(11, 8)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI2(x)             ((x) << 8)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF            GENMASK(15, 12)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI3(x)             ((x) << 12)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF            GENMASK(19, 16)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI4(x)             ((x) << 16)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF            GENMASK(23, 20)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PRI5(x)             ((x) << 20)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF            GENMASK(29, 24)
++#define   QCA8K_PORT_HOL_CTRL0_EG_PORT(x)             ((x) << 24)
++
++#define QCA8K_REG_PORT_HOL_CTRL1(_i)                  (0x974 + (_i) * 0x8)
++#define   QCA8K_PORT_HOL_CTRL1_ING_BUF                        GENMASK(3, 0)
++#define   QCA8K_PORT_HOL_CTRL1_ING(x)                 ((x) << 0)
++#define   QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN          BIT(6)
++#define   QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN         BIT(7)
++#define   QCA8K_PORT_HOL_CTRL1_WRED_EN                        BIT(8)
++#define   QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN           BIT(16)
++
+ /* Pkt edit registers */
+ #define QCA8K_EGRESS_VLAN(x)                          (0x0c70 + (4 * (x / 2)))
+@@ -220,6 +244,7 @@ struct qca8k_match_data {
+ };
+ struct qca8k_priv {
++      u8 switch_id;
+       struct regmap *regmap;
+       struct mii_bus *bus;
+       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/735-v5.14-12-net-dsa-qca8k-limit-port5-delay-to-qca8337.patch b/target/linux/generic/backport-5.10/735-v5.14-12-net-dsa-qca8k-limit-port5-delay-to-qca8337.patch
new file mode 100644 (file)
index 0000000..d25edbb
--- /dev/null
@@ -0,0 +1,31 @@
+From 5bf9ff3b9fb5ecb67a1a3517b26db3a00f2a2f11 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:02 +0200
+Subject: [PATCH] net: dsa: qca8k: limit port5 delay to qca8337
+
+Limit port5 rx delay to qca8337. This is taken from the legacy QSDK code
+that limits the rx delay on port5 to only this particular switch version,
+on other switch only the tx and rx delay for port0 are needed.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1003,8 +1003,10 @@ qca8k_phylink_mac_config(struct dsa_swit
+                           QCA8K_PORT_PAD_RGMII_EN |
+                           QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
+                           QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
+-              qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
+-                          QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
++              /* QCA8337 requires to set rgmii rx delay */
++              if (priv->switch_id == QCA8K_ID_QCA8337)
++                      qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
++                                  QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
+               break;
+       case PHY_INTERFACE_MODE_SGMII:
+       case PHY_INTERFACE_MODE_1000BASEX:
diff --git a/target/linux/generic/backport-5.10/735-v5.14-13-net-dsa-qca8k-add-GLOBAL_FC-settings-needed-for-qca8.patch b/target/linux/generic/backport-5.10/735-v5.14-13-net-dsa-qca8k-add-GLOBAL_FC-settings-needed-for-qca8.patch
new file mode 100644 (file)
index 0000000..2b393d2
--- /dev/null
@@ -0,0 +1,48 @@
+From 0fc57e4b5e39461fc0a54aae0afe4241363a7267 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:03 +0200
+Subject: [PATCH] net: dsa: qca8k: add GLOBAL_FC settings needed for qca8327
+
+Switch qca8327 needs special settings for the GLOBAL_FC_THRES regs.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 10 ++++++++++
+ drivers/net/dsa/qca8k.h |  6 ++++++
+ 2 files changed, 16 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -930,6 +930,16 @@ qca8k_setup(struct dsa_switch *ds)
+               }
+       }
++      /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
++      if (priv->switch_id == QCA8K_ID_QCA8327) {
++              mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
++                     QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496);
++              qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH,
++                        QCA8K_GLOBAL_FC_GOL_XON_THRES_S |
++                        QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S,
++                        mask);
++      }
++
+       /* Setup our port MTUs to match power on defaults */
+       for (i = 0; i < QCA8K_NUM_PORTS; i++)
+               priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -168,6 +168,12 @@
+ #define   QCA8K_PORT_LOOKUP_STATE                     GENMASK(18, 16)
+ #define   QCA8K_PORT_LOOKUP_LEARN                     BIT(20)
++#define QCA8K_REG_GLOBAL_FC_THRESH                    0x800
++#define   QCA8K_GLOBAL_FC_GOL_XON_THRES(x)            ((x) << 16)
++#define   QCA8K_GLOBAL_FC_GOL_XON_THRES_S             GENMASK(24, 16)
++#define   QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x)           ((x) << 0)
++#define   QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S            GENMASK(8, 0)
++
+ #define QCA8K_REG_PORT_HOL_CTRL0(_i)                  (0x970 + (_i) * 0x8)
+ #define   QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF            GENMASK(3, 0)
+ #define   QCA8K_PORT_HOL_CTRL0_EG_PRI0(x)             ((x) << 0)
diff --git a/target/linux/generic/backport-5.10/735-v5.14-14-net-dsa-qca8k-add-support-for-switch-rev.patch b/target/linux/generic/backport-5.10/735-v5.14-14-net-dsa-qca8k-add-support-for-switch-rev.patch
new file mode 100644 (file)
index 0000000..ed9b818
--- /dev/null
@@ -0,0 +1,114 @@
+From 95ffeaf18b3bb90eeef52cbf7d79ccc9d0345ff5 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:04 +0200
+Subject: [PATCH] net: dsa: qca8k: add support for switch rev
+
+qca8k internal phy driver require some special debug value to be set
+based on the switch revision. Rework the switch id read function to
+also read the chip revision.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 53 ++++++++++++++++++++++++++---------------
+ drivers/net/dsa/qca8k.h |  7 ++++--
+ 2 files changed, 39 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1588,12 +1588,40 @@ static const struct dsa_switch_ops qca8k
+       .phylink_mac_link_up    = qca8k_phylink_mac_link_up,
+ };
++static int qca8k_read_switch_id(struct qca8k_priv *priv)
++{
++      const struct qca8k_match_data *data;
++      u32 val;
++      u8 id;
++
++      /* get the switches ID from the compatible */
++      data = of_device_get_match_data(priv->dev);
++      if (!data)
++              return -ENODEV;
++
++      val = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
++      if (val < 0)
++              return -ENODEV;
++
++      id = QCA8K_MASK_CTRL_DEVICE_ID(val & QCA8K_MASK_CTRL_DEVICE_ID_MASK);
++      if (id != data->id) {
++              dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id);
++              return -ENODEV;
++      }
++
++      priv->switch_id = id;
++
++      /* Save revision to communicate to the internal PHY driver */
++      priv->switch_revision = (val & QCA8K_MASK_CTRL_REV_ID_MASK);
++
++      return 0;
++}
++
+ static int
+ qca8k_sw_probe(struct mdio_device *mdiodev)
+ {
+-      const struct qca8k_match_data *data;
+       struct qca8k_priv *priv;
+-      u32 id;
++      int ret;
+       /* allocate the private data struct so that we can probe the switches
+        * ID register
+@@ -1619,24 +1647,11 @@ qca8k_sw_probe(struct mdio_device *mdiod
+               gpiod_set_value_cansleep(priv->reset_gpio, 0);
+       }
+-      /* get the switches ID from the compatible */
+-      data = of_device_get_match_data(&mdiodev->dev);
+-      if (!data)
+-              return -ENODEV;
++      /* Check the detected switch id */
++      ret = qca8k_read_switch_id(priv);
++      if (ret)
++              return ret;
+-      /* read the switches ID register */
+-      id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
+-      if (id < 0)
+-              return id;
+-
+-      id >>= QCA8K_MASK_CTRL_ID_S;
+-      id &= QCA8K_MASK_CTRL_ID_M;
+-      if (id != data->id) {
+-              dev_err(&mdiodev->dev, "Switch id detected %x but expected %x", id, data->id);
+-              return -ENODEV;
+-      }
+-
+-      priv->switch_id = id;
+       priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
+       if (!priv->ds)
+               return -ENOMEM;
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -30,8 +30,10 @@
+ /* Global control registers */
+ #define QCA8K_REG_MASK_CTRL                           0x000
+-#define   QCA8K_MASK_CTRL_ID_M                                0xff
+-#define   QCA8K_MASK_CTRL_ID_S                                8
++#define   QCA8K_MASK_CTRL_REV_ID_MASK                 GENMASK(7, 0)
++#define   QCA8K_MASK_CTRL_REV_ID(x)                   ((x) >> 0)
++#define   QCA8K_MASK_CTRL_DEVICE_ID_MASK              GENMASK(15, 8)
++#define   QCA8K_MASK_CTRL_DEVICE_ID(x)                        ((x) >> 8)
+ #define QCA8K_REG_PORT0_PAD_CTRL                      0x004
+ #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
+ #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
+@@ -251,6 +253,7 @@ struct qca8k_match_data {
+ struct qca8k_priv {
+       u8 switch_id;
++      u8 switch_revision;
+       struct regmap *regmap;
+       struct mii_bus *bus;
+       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/735-v5.14-15-net-dsa-qca8k-add-ethernet-ports-fallback-to-setup_m.patch b/target/linux/generic/backport-5.10/735-v5.14-15-net-dsa-qca8k-add-ethernet-ports-fallback-to-setup_m.patch
new file mode 100644 (file)
index 0000000..629cb32
--- /dev/null
@@ -0,0 +1,28 @@
+From 1ee0591a1093c2448642c33433483e9260275f7b Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:05 +0200
+Subject: [PATCH] net: dsa: qca8k: add ethernet-ports fallback to
+ setup_mdio_bus
+
+Dsa now also supports ethernet-ports. Add this new binding as a fallback
+if the ports node can't be found.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -719,6 +719,9 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
+       ports = of_get_child_by_name(priv->dev->of_node, "ports");
+       if (!ports)
++              ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports");
++
++      if (!ports)
+               return -EINVAL;
+       for_each_available_child_of_node(ports, port) {
diff --git a/target/linux/generic/backport-5.10/735-v5.14-16-net-dsa-qca8k-make-rgmii-delay-configurable.patch b/target/linux/generic/backport-5.10/735-v5.14-16-net-dsa-qca8k-make-rgmii-delay-configurable.patch
new file mode 100644 (file)
index 0000000..6dc2dc6
--- /dev/null
@@ -0,0 +1,188 @@
+From e4b9977cee1583da38a6e9118078bb728aaccf7b Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:06 +0200
+Subject: [PATCH] net: dsa: qca8k: make rgmii delay configurable
+
+The legacy qsdk code used a different delay instead of the max value.
+Qsdk use 1 ns for rx and 2 ns for tx. Make these values configurable
+using the standard rx/tx-internal-delay-ps ethernet binding and apply
+qsdk values by default. The connected gmac doesn't add any delay so no
+additional delay is added to tx/rx.
+On this switch the delay is actually in ns so value should be in the
+1000 order. Any value converted from ps to ns by dividing it by 1000
+as the switch max value for delay is 3ns.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 82 ++++++++++++++++++++++++++++++++++++++++-
+ drivers/net/dsa/qca8k.h | 11 +++---
+ 2 files changed, 86 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -778,6 +778,68 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
+ }
+ static int
++qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv)
++{
++      struct device_node *port_dn;
++      phy_interface_t mode;
++      struct dsa_port *dp;
++      u32 val;
++
++      /* CPU port is already checked */
++      dp = dsa_to_port(priv->ds, 0);
++
++      port_dn = dp->dn;
++
++      /* Check if port 0 is set to the correct type */
++      of_get_phy_mode(port_dn, &mode);
++      if (mode != PHY_INTERFACE_MODE_RGMII_ID &&
++          mode != PHY_INTERFACE_MODE_RGMII_RXID &&
++          mode != PHY_INTERFACE_MODE_RGMII_TXID) {
++              return 0;
++      }
++
++      switch (mode) {
++      case PHY_INTERFACE_MODE_RGMII_ID:
++      case PHY_INTERFACE_MODE_RGMII_RXID:
++              if (of_property_read_u32(port_dn, "rx-internal-delay-ps", &val))
++                      val = 2;
++              else
++                      /* Switch regs accept value in ns, convert ps to ns */
++                      val = val / 1000;
++
++              if (val > QCA8K_MAX_DELAY) {
++                      dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
++                      val = 3;
++              }
++
++              priv->rgmii_rx_delay = val;
++              /* Stop here if we need to check only for rx delay */
++              if (mode != PHY_INTERFACE_MODE_RGMII_ID)
++                      break;
++
++              fallthrough;
++      case PHY_INTERFACE_MODE_RGMII_TXID:
++              if (of_property_read_u32(port_dn, "tx-internal-delay-ps", &val))
++                      val = 1;
++              else
++                      /* Switch regs accept value in ns, convert ps to ns */
++                      val = val / 1000;
++
++              if (val > QCA8K_MAX_DELAY) {
++                      dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
++                      val = 3;
++              }
++
++              priv->rgmii_tx_delay = val;
++              break;
++      default:
++              return 0;
++      }
++
++      return 0;
++}
++
++static int
+ qca8k_setup(struct dsa_switch *ds)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+@@ -802,6 +864,10 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               return ret;
++      ret = qca8k_setup_of_rgmii_delay(priv);
++      if (ret)
++              return ret;
++
+       /* Enable CPU Port */
+       ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
+                           QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
+@@ -970,6 +1036,8 @@ qca8k_phylink_mac_config(struct dsa_swit
+       case 0: /* 1st CPU port */
+               if (state->interface != PHY_INTERFACE_MODE_RGMII &&
+                   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
++                  state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
++                  state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
+                   state->interface != PHY_INTERFACE_MODE_SGMII)
+                       return;
+@@ -985,6 +1053,8 @@ qca8k_phylink_mac_config(struct dsa_swit
+       case 6: /* 2nd CPU port / external PHY */
+               if (state->interface != PHY_INTERFACE_MODE_RGMII &&
+                   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
++                  state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
++                  state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
+                   state->interface != PHY_INTERFACE_MODE_SGMII &&
+                   state->interface != PHY_INTERFACE_MODE_1000BASEX)
+                       return;
+@@ -1008,14 +1078,18 @@ qca8k_phylink_mac_config(struct dsa_swit
+               qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
+               break;
+       case PHY_INTERFACE_MODE_RGMII_ID:
++      case PHY_INTERFACE_MODE_RGMII_TXID:
++      case PHY_INTERFACE_MODE_RGMII_RXID:
+               /* RGMII_ID needs internal delay. This is enabled through
+                * PORT5_PAD_CTRL for all ports, rather than individual port
+                * registers
+                */
+               qca8k_write(priv, reg,
+                           QCA8K_PORT_PAD_RGMII_EN |
+-                          QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
+-                          QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
++                          QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay) |
++                          QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay) |
++                          QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
++                          QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
+               /* QCA8337 requires to set rgmii rx delay */
+               if (priv->switch_id == QCA8K_ID_QCA8337)
+                       qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
+@@ -1073,6 +1147,8 @@ qca8k_phylink_validate(struct dsa_switch
+               if (state->interface != PHY_INTERFACE_MODE_NA &&
+                   state->interface != PHY_INTERFACE_MODE_RGMII &&
+                   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
++                  state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
++                  state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
+                   state->interface != PHY_INTERFACE_MODE_SGMII)
+                       goto unsupported;
+               break;
+@@ -1090,6 +1166,8 @@ qca8k_phylink_validate(struct dsa_switch
+               if (state->interface != PHY_INTERFACE_MODE_NA &&
+                   state->interface != PHY_INTERFACE_MODE_RGMII &&
+                   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
++                  state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
++                  state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
+                   state->interface != PHY_INTERFACE_MODE_SGMII &&
+                   state->interface != PHY_INTERFACE_MODE_1000BASEX)
+                       goto unsupported;
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -38,12 +38,11 @@
+ #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
+ #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
+ #define   QCA8K_PORT_PAD_RGMII_EN                     BIT(26)
+-#define   QCA8K_PORT_PAD_RGMII_TX_DELAY(x)            \
+-                                              ((0x8 + (x & 0x3)) << 22)
+-#define   QCA8K_PORT_PAD_RGMII_RX_DELAY(x)            \
+-                                              ((0x10 + (x & 0x3)) << 20)
+-#define   QCA8K_MAX_DELAY                             3
++#define   QCA8K_PORT_PAD_RGMII_TX_DELAY(x)            ((x) << 22)
++#define   QCA8K_PORT_PAD_RGMII_RX_DELAY(x)            ((x) << 20)
++#define         QCA8K_PORT_PAD_RGMII_TX_DELAY_EN              BIT(25)
+ #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN            BIT(24)
++#define   QCA8K_MAX_DELAY                             3
+ #define   QCA8K_PORT_PAD_SGMII_EN                     BIT(7)
+ #define QCA8K_REG_PWS                                 0x010
+ #define   QCA8K_PWS_SERDES_AEN_DIS                    BIT(7)
+@@ -254,6 +253,8 @@ struct qca8k_match_data {
+ struct qca8k_priv {
+       u8 switch_id;
+       u8 switch_revision;
++      u8 rgmii_tx_delay;
++      u8 rgmii_rx_delay;
+       struct regmap *regmap;
+       struct mii_bus *bus;
+       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/735-v5.14-17-net-dsa-qca8k-clear-MASTER_EN-after-phy-read-write.patch b/target/linux/generic/backport-5.10/735-v5.14-17-net-dsa-qca8k-clear-MASTER_EN-after-phy-read-write.patch
new file mode 100644 (file)
index 0000000..4593da0
--- /dev/null
@@ -0,0 +1,50 @@
+From 63c33bbfeb6842a956a0eb12901e28eb335bdb18 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:07 +0200
+Subject: [PATCH] net: dsa: qca8k: clear MASTER_EN after phy read/write
+
+Clear MDIO_MASTER_EN bit from MDIO_MASTER_CTRL after read/write
+operation. The MDIO_MASTER_EN bit is not reset after read/write
+operation and the next operation can be wrongly interpreted by the
+switch as a mdio operation. This cause a production of wrong/garbage
+data from the switch and underfined bheavior. (random port drop,
+unplugged port flagged with link up, wrong port speed)
+Also on driver remove the MASTER_CTRL can be left set and cause the
+malfunction of any next driver using the mdio device.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -649,8 +649,14 @@ qca8k_mdio_write(struct qca8k_priv *priv
+       if (ret)
+               return ret;
+-      return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+-              QCA8K_MDIO_MASTER_BUSY);
++      ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
++                            QCA8K_MDIO_MASTER_BUSY);
++
++      /* even if the busy_wait timeouts try to clear the MASTER_EN */
++      qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
++                      QCA8K_MDIO_MASTER_EN);
++
++      return ret;
+ }
+ static int
+@@ -685,6 +691,10 @@ qca8k_mdio_read(struct qca8k_priv *priv,
+       val &= QCA8K_MDIO_MASTER_DATA_MASK;
++      /* even if the busy_wait timeouts try to clear the MASTER_EN */
++      qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
++                      QCA8K_MDIO_MASTER_EN);
++
+       return val;
+ }
diff --git a/target/linux/generic/backport-5.10/735-v5.14-18-net-dsa-qca8k-dsa-qca8k-protect-MASTER-busy_wait-wit.patch b/target/linux/generic/backport-5.10/735-v5.14-18-net-dsa-qca8k-dsa-qca8k-protect-MASTER-busy_wait-wit.patch
new file mode 100644 (file)
index 0000000..b6684d7
--- /dev/null
@@ -0,0 +1,128 @@
+From 60df02b6ea4581d72eb7a3ab7204504a54059b72 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:08 +0200
+Subject: [PATCH] net: dsa: qca8k: dsa: qca8k: protect MASTER busy_wait with
+ mdio mutex
+
+MDIO_MASTER operation have a dedicated busy wait that is not protected
+by the mdio mutex. This can cause situation where the MASTER operation
+is done and a normal operation is executed between the MASTER read/write
+and the MASTER busy_wait. Rework the qca8k_mdio_read/write function to
+address this issue by binding the lock for the whole MASTER operation
+and not only the mdio read/write common operation.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 68 +++++++++++++++++++++++++++++++++--------
+ 1 file changed, 55 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -628,8 +628,31 @@ qca8k_port_to_phy(int port)
+ }
+ static int
++qca8k_mdio_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
++{
++      u16 r1, r2, page;
++      u32 val;
++      int ret;
++
++      qca8k_split_addr(reg, &r1, &r2, &page);
++
++      ret = read_poll_timeout(qca8k_mii_read32, val, !(val & mask), 0,
++                              QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
++                              priv->bus, 0x10 | r2, r1);
++
++      /* Check if qca8k_read has failed for a different reason
++       * before returnting -ETIMEDOUT
++       */
++      if (ret < 0 && val < 0)
++              return val;
++
++      return ret;
++}
++
++static int
+ qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
+ {
++      u16 r1, r2, page;
+       u32 phy, val;
+       int ret;
+@@ -645,12 +668,21 @@ qca8k_mdio_write(struct qca8k_priv *priv
+             QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
+             QCA8K_MDIO_MASTER_DATA(data);
+-      ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
++      qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
++
++      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++
++      ret = qca8k_set_page(priv->bus, page);
+       if (ret)
+-              return ret;
++              goto exit;
++
++      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
+-      ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+-                            QCA8K_MDIO_MASTER_BUSY);
++      ret = qca8k_mdio_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
++                                 QCA8K_MDIO_MASTER_BUSY);
++
++exit:
++      mutex_unlock(&priv->bus->mdio_lock);
+       /* even if the busy_wait timeouts try to clear the MASTER_EN */
+       qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
+@@ -662,6 +694,7 @@ qca8k_mdio_write(struct qca8k_priv *priv
+ static int
+ qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
+ {
++      u16 r1, r2, page;
+       u32 phy, val;
+       int ret;
+@@ -676,21 +709,30 @@ qca8k_mdio_read(struct qca8k_priv *priv,
+             QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+             QCA8K_MDIO_MASTER_REG_ADDR(regnum);
+-      ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
+-      if (ret)
+-              return ret;
++      qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
++
++      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+-                            QCA8K_MDIO_MASTER_BUSY);
++      ret = qca8k_set_page(priv->bus, page);
+       if (ret)
+-              return ret;
++              goto exit;
+-      val = qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL);
+-      if (val < 0)
+-              return val;
++      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
++
++      ret = qca8k_mdio_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
++                                 QCA8K_MDIO_MASTER_BUSY);
++      if (ret)
++              goto exit;
++      val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
+       val &= QCA8K_MDIO_MASTER_DATA_MASK;
++exit:
++      mutex_unlock(&priv->bus->mdio_lock);
++
++      if (val >= 0)
++              val &= QCA8K_MDIO_MASTER_DATA_MASK;
++
+       /* even if the busy_wait timeouts try to clear the MASTER_EN */
+       qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
+                       QCA8K_MDIO_MASTER_EN);
diff --git a/target/linux/generic/backport-5.10/735-v5.14-19-net-dsa-qca8k-enlarge-mdio-delay-and-timeout.patch b/target/linux/generic/backport-5.10/735-v5.14-19-net-dsa-qca8k-enlarge-mdio-delay-and-timeout.patch
new file mode 100644 (file)
index 0000000..30eeed3
--- /dev/null
@@ -0,0 +1,39 @@
+From 617960d72e93de0f3fa52407e2d39e8c43e73b0a Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:09 +0200
+Subject: [PATCH] net: dsa: qca8k: enlarge mdio delay and timeout
+
+The witch require some extra delay after setting page or the next
+read/write can use still use the old page. Add a delay after the
+set_page function to address this as it's done in QSDK legacy driver.
+Some timeouts were notice with VLAN and phy function, enlarge the
+mdio busy wait timeout to fix these problems.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 1 +
+ drivers/net/dsa/qca8k.h | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -143,6 +143,7 @@ qca8k_set_page(struct mii_bus *bus, u16
+       }
+       qca8k_current_page = page;
++      usleep_range(1000, 2000);
+       return 0;
+ }
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -20,7 +20,7 @@
+ #define PHY_ID_QCA8337                                        0x004dd036
+ #define QCA8K_ID_QCA8337                              0x13
+-#define QCA8K_BUSY_WAIT_TIMEOUT                               20
++#define QCA8K_BUSY_WAIT_TIMEOUT                               2000
+ #define QCA8K_NUM_FDB_RECORDS                         2048
diff --git a/target/linux/generic/backport-5.10/735-v5.14-20-net-dsa-qca8k-add-support-for-internal-phy-and-inter.patch b/target/linux/generic/backport-5.10/735-v5.14-20-net-dsa-qca8k-add-support-for-internal-phy-and-inter.patch
new file mode 100644 (file)
index 0000000..88d3c1e
--- /dev/null
@@ -0,0 +1,267 @@
+From 759bafb8a3226326ca357613bc90acf738f80c32 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:10 +0200
+Subject: [PATCH] net: dsa: qca8k: add support for internal phy and internal
+ mdio
+
+Add support to setup_mdio_bus for internal phy declaration. Introduce a
+flag to use the legacy port phy mapping by default and use the direct
+mapping if a mdio node is detected in the switch node. Register a
+dedicated mdio internal mdio bus to address the different mapping
+between port and phy if the mdio node is detected.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 112 +++++++++++++++++++++++++++++-----------
+ drivers/net/dsa/qca8k.h |   1 +
+ 2 files changed, 83 insertions(+), 30 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -11,6 +11,7 @@
+ #include <linux/netdevice.h>
+ #include <net/dsa.h>
+ #include <linux/of_net.h>
++#include <linux/of_mdio.h>
+ #include <linux/of_platform.h>
+ #include <linux/if_bridge.h>
+ #include <linux/mdio.h>
+@@ -629,7 +630,7 @@ qca8k_port_to_phy(int port)
+ }
+ static int
+-qca8k_mdio_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
++qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
+ {
+       u16 r1, r2, page;
+       u32 val;
+@@ -639,7 +640,7 @@ qca8k_mdio_busy_wait(struct qca8k_priv *
+       ret = read_poll_timeout(qca8k_mii_read32, val, !(val & mask), 0,
+                               QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
+-                              priv->bus, 0x10 | r2, r1);
++                              bus, 0x10 | r2, r1);
+       /* Check if qca8k_read has failed for a different reason
+        * before returnting -ETIMEDOUT
+@@ -651,19 +652,16 @@ qca8k_mdio_busy_wait(struct qca8k_priv *
+ }
+ static int
+-qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
++qca8k_mdio_write(struct mii_bus *salve_bus, int phy, int regnum, u16 data)
+ {
++      struct qca8k_priv *priv = salve_bus->priv;
+       u16 r1, r2, page;
+-      u32 phy, val;
++      u32 val;
+       int ret;
+       if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
+               return -EINVAL;
+-      /* callee is responsible for not passing bad ports,
+-       * but we still would like to make spills impossible.
+-       */
+-      phy = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
+       val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+             QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+             QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
+@@ -679,33 +677,29 @@ qca8k_mdio_write(struct qca8k_priv *priv
+       qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
+-      ret = qca8k_mdio_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
++      ret = qca8k_mdio_busy_wait(priv->bus, QCA8K_MDIO_MASTER_CTRL,
+                                  QCA8K_MDIO_MASTER_BUSY);
+ exit:
+-      mutex_unlock(&priv->bus->mdio_lock);
+-
+       /* even if the busy_wait timeouts try to clear the MASTER_EN */
+-      qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
+-                      QCA8K_MDIO_MASTER_EN);
++      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, 0);
++
++      mutex_unlock(&priv->bus->mdio_lock);
+       return ret;
+ }
+ static int
+-qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
++qca8k_mdio_read(struct mii_bus *salve_bus, int phy, int regnum)
+ {
++      struct qca8k_priv *priv = salve_bus->priv;
+       u16 r1, r2, page;
+-      u32 phy, val;
++      u32 val;
+       int ret;
+       if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
+               return -EINVAL;
+-      /* callee is responsible for not passing bad ports,
+-       * but we still would like to make spills impossible.
+-       */
+-      phy = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
+       val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+             QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+             QCA8K_MDIO_MASTER_REG_ADDR(regnum);
+@@ -720,24 +714,22 @@ qca8k_mdio_read(struct qca8k_priv *priv,
+       qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
+-      ret = qca8k_mdio_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
++      ret = qca8k_mdio_busy_wait(priv->bus, QCA8K_MDIO_MASTER_CTRL,
+                                  QCA8K_MDIO_MASTER_BUSY);
+       if (ret)
+               goto exit;
+       val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
+-      val &= QCA8K_MDIO_MASTER_DATA_MASK;
+ exit:
++      /* even if the busy_wait timeouts try to clear the MASTER_EN */
++      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, 0);
++
+       mutex_unlock(&priv->bus->mdio_lock);
+       if (val >= 0)
+               val &= QCA8K_MDIO_MASTER_DATA_MASK;
+-      /* even if the busy_wait timeouts try to clear the MASTER_EN */
+-      qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
+-                      QCA8K_MDIO_MASTER_EN);
+-
+       return val;
+ }
+@@ -746,7 +738,14 @@ qca8k_phy_write(struct dsa_switch *ds, i
+ {
+       struct qca8k_priv *priv = ds->priv;
+-      return qca8k_mdio_write(priv, port, regnum, data);
++      /* Check if the legacy mapping should be used and the
++       * port is not correctly mapped to the right PHY in the
++       * devicetree
++       */
++      if (priv->legacy_phy_port_mapping)
++              port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
++
++      return qca8k_mdio_write(priv->bus, port, regnum, data);
+ }
+ static int
+@@ -755,7 +754,14 @@ qca8k_phy_read(struct dsa_switch *ds, in
+       struct qca8k_priv *priv = ds->priv;
+       int ret;
+-      ret = qca8k_mdio_read(priv, port, regnum);
++      /* Check if the legacy mapping should be used and the
++       * port is not correctly mapped to the right PHY in the
++       * devicetree
++       */
++      if (priv->legacy_phy_port_mapping)
++              port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
++
++      ret = qca8k_mdio_read(priv->bus, port, regnum);
+       if (ret < 0)
+               return 0xffff;
+@@ -764,10 +770,37 @@ qca8k_phy_read(struct dsa_switch *ds, in
+ }
+ static int
++qca8k_mdio_register(struct qca8k_priv *priv, struct device_node *mdio)
++{
++      struct dsa_switch *ds = priv->ds;
++      struct mii_bus *bus;
++
++      bus = devm_mdiobus_alloc(ds->dev);
++
++      if (!bus)
++              return -ENOMEM;
++
++      bus->priv = (void *)priv;
++      bus->name = "qca8k slave mii";
++      bus->read = qca8k_mdio_read;
++      bus->write = qca8k_mdio_write;
++      snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d",
++               ds->index);
++
++      bus->parent = ds->dev;
++      bus->phy_mask = ~ds->phys_mii_mask;
++
++      ds->slave_mii_bus = bus;
++
++      return devm_of_mdiobus_register(priv->dev, bus, mdio);
++}
++
++static int
+ qca8k_setup_mdio_bus(struct qca8k_priv *priv)
+ {
+       u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg;
+-      struct device_node *ports, *port;
++      struct device_node *ports, *port, *mdio;
++      phy_interface_t mode;
+       int err;
+       ports = of_get_child_by_name(priv->dev->of_node, "ports");
+@@ -788,7 +821,10 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
+               if (!dsa_is_user_port(priv->ds, reg))
+                       continue;
+-              if (of_property_read_bool(port, "phy-handle"))
++              of_get_phy_mode(port, &mode);
++
++              if (of_property_read_bool(port, "phy-handle") &&
++                  mode != PHY_INTERFACE_MODE_INTERNAL)
+                       external_mdio_mask |= BIT(reg);
+               else
+                       internal_mdio_mask |= BIT(reg);
+@@ -825,8 +861,23 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
+                                      QCA8K_MDIO_MASTER_EN);
+       }
++      /* Check if the devicetree declare the port:phy mapping */
++      mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
++      if (of_device_is_available(mdio)) {
++              err = qca8k_mdio_register(priv, mdio);
++              if (err)
++                      of_node_put(mdio);
++
++              return err;
++      }
++
++      /* If a mapping can't be found the legacy mapping is used,
++       * using the qca8k_port_to_phy function
++       */
++      priv->legacy_phy_port_mapping = true;
+       priv->ops.phy_read = qca8k_phy_read;
+       priv->ops.phy_write = qca8k_phy_write;
++
+       return 0;
+ }
+@@ -1212,7 +1263,8 @@ qca8k_phylink_validate(struct dsa_switch
+       case 5:
+               /* Internal PHY */
+               if (state->interface != PHY_INTERFACE_MODE_NA &&
+-                  state->interface != PHY_INTERFACE_MODE_GMII)
++                  state->interface != PHY_INTERFACE_MODE_GMII &&
++                  state->interface != PHY_INTERFACE_MODE_INTERNAL)
+                       goto unsupported;
+               break;
+       case 6: /* 2nd CPU port / external PHY */
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -255,6 +255,7 @@ struct qca8k_priv {
+       u8 switch_revision;
+       u8 rgmii_tx_delay;
+       u8 rgmii_rx_delay;
++      bool legacy_phy_port_mapping;
+       struct regmap *regmap;
+       struct mii_bus *bus;
+       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/735-v5.14-21-devicetree-bindings-dsa-qca8k-Document-internal-mdio.patch b/target/linux/generic/backport-5.10/735-v5.14-21-devicetree-bindings-dsa-qca8k-Document-internal-mdio.patch
new file mode 100644 (file)
index 0000000..6db01b4
--- /dev/null
@@ -0,0 +1,93 @@
+From 0c994a28e7518f098c84a3049cb2915780db873a Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:11 +0200
+Subject: [PATCH] devicetree: bindings: dsa: qca8k: Document internal mdio
+ definition
+
+Document new way of declare mapping of internal PHY to port.
+The new implementation directly declare the PHY connected to the port
+by adding a node in the switch node. The driver detect this and register
+an internal mdiobus using the mapping defined in the mdio node.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../devicetree/bindings/net/dsa/qca8k.txt     | 39 +++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -21,6 +21,10 @@ described in dsa/dsa.txt. If the QCA8K s
+ mdio-bus each subnode describing a port needs to have a valid phandle
+ referencing the internal PHY it is connected to. This is because there's no
+ N:N mapping of port and PHY id.
++To declare the internal mdio-bus configuration, declare a mdio node in the
++switch node and declare the phandle for the port referencing the internal
++PHY is connected to. In this config a internal mdio-bus is registered and
++the mdio MASTER is used as communication.
+ Don't use mixed external and internal mdio-bus configurations, as this is
+ not supported by the hardware.
+@@ -150,26 +154,61 @@ for the internal master mdio-bus configu
+                               port@1 {
+                                       reg = <1>;
+                                       label = "lan1";
++                                      phy-mode = "internal";
++                                      phy-handle = <&phy_port1>;
+                               };
+                               port@2 {
+                                       reg = <2>;
+                                       label = "lan2";
++                                      phy-mode = "internal";
++                                      phy-handle = <&phy_port2>;
+                               };
+                               port@3 {
+                                       reg = <3>;
+                                       label = "lan3";
++                                      phy-mode = "internal";
++                                      phy-handle = <&phy_port3>;
+                               };
+                               port@4 {
+                                       reg = <4>;
+                                       label = "lan4";
++                                      phy-mode = "internal";
++                                      phy-handle = <&phy_port4>;
+                               };
+                               port@5 {
+                                       reg = <5>;
+                                       label = "wan";
++                                      phy-mode = "internal";
++                                      phy-handle = <&phy_port5>;
++                              };
++                      };
++
++                      mdio {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              phy_port1: phy@0 {
++                                      reg = <0>;
++                              };
++
++                              phy_port2: phy@1 {
++                                      reg = <1>;
++                              };
++
++                              phy_port3: phy@2 {
++                                      reg = <2>;
++                              };
++
++                              phy_port4: phy@3 {
++                                      reg = <3>;
++                              };
++
++                              phy_port5: phy@4 {
++                                      reg = <4>;
+                               };
+                       };
+               };
diff --git a/target/linux/generic/backport-5.10/735-v5.14-22-net-dsa-qca8k-improve-internal-mdio-read-write-bus-a.patch b/target/linux/generic/backport-5.10/735-v5.14-22-net-dsa-qca8k-improve-internal-mdio-read-write-bus-a.patch
new file mode 100644 (file)
index 0000000..da8d5b3
--- /dev/null
@@ -0,0 +1,95 @@
+From b7ebac354d54f1657bb89b7a7ca149db50203e6a Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:12 +0200
+Subject: [PATCH] net: dsa: qca8k: improve internal mdio read/write bus access
+
+Improve the internal mdio read/write bus access by caching the value
+without accessing it for every read/write.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -655,6 +655,7 @@ static int
+ qca8k_mdio_write(struct mii_bus *salve_bus, int phy, int regnum, u16 data)
+ {
+       struct qca8k_priv *priv = salve_bus->priv;
++      struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+       u32 val;
+       int ret;
+@@ -669,22 +670,22 @@ qca8k_mdio_write(struct mii_bus *salve_b
+       qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
+-      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      ret = qca8k_set_page(priv->bus, page);
++      ret = qca8k_set_page(bus, page);
+       if (ret)
+               goto exit;
+-      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
++      qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+-      ret = qca8k_mdio_busy_wait(priv->bus, QCA8K_MDIO_MASTER_CTRL,
++      ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
+                                  QCA8K_MDIO_MASTER_BUSY);
+ exit:
+       /* even if the busy_wait timeouts try to clear the MASTER_EN */
+-      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, 0);
++      qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
+-      mutex_unlock(&priv->bus->mdio_lock);
++      mutex_unlock(&bus->mdio_lock);
+       return ret;
+ }
+@@ -693,6 +694,7 @@ static int
+ qca8k_mdio_read(struct mii_bus *salve_bus, int phy, int regnum)
+ {
+       struct qca8k_priv *priv = salve_bus->priv;
++      struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+       u32 val;
+       int ret;
+@@ -706,26 +708,26 @@ qca8k_mdio_read(struct mii_bus *salve_bu
+       qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
+-      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      ret = qca8k_set_page(priv->bus, page);
++      ret = qca8k_set_page(bus, page);
+       if (ret)
+               goto exit;
+-      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
++      qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+-      ret = qca8k_mdio_busy_wait(priv->bus, QCA8K_MDIO_MASTER_CTRL,
++      ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
+                                  QCA8K_MDIO_MASTER_BUSY);
+       if (ret)
+               goto exit;
+-      val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
++      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
+ exit:
+       /* even if the busy_wait timeouts try to clear the MASTER_EN */
+-      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, 0);
++      qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
+-      mutex_unlock(&priv->bus->mdio_lock);
++      mutex_unlock(&bus->mdio_lock);
+       if (val >= 0)
+               val &= QCA8K_MDIO_MASTER_DATA_MASK;
diff --git a/target/linux/generic/backport-5.10/735-v5.14-23-net-dsa-qca8k-pass-switch_revision-info-to-phy-dev_f.patch b/target/linux/generic/backport-5.10/735-v5.14-23-net-dsa-qca8k-pass-switch_revision-info-to-phy-dev_f.patch
new file mode 100644 (file)
index 0000000..1179cf1
--- /dev/null
@@ -0,0 +1,48 @@
+From a46aec02bc06ac2c33f326339e4ef88c735dc30d Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:13 +0200
+Subject: [PATCH] net: dsa: qca8k: pass switch_revision info to phy dev_flags
+
+Define get_phy_flags to pass switch_Revision needed to tweak the
+internal PHY with debug values based on the revision.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1740,6 +1740,22 @@ qca8k_port_vlan_del(struct dsa_switch *d
+       return ret;
+ }
++static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
++{
++      struct qca8k_priv *priv = ds->priv;
++
++      /* Communicate to the phy internal driver the switch revision.
++       * Based on the switch revision different values needs to be
++       * set to the dbg and mmd reg on the phy.
++       * The first 2 bit are used to communicate the switch revision
++       * to the phy driver.
++       */
++      if (port > 0 && port < 6)
++              return priv->switch_revision;
++
++      return 0;
++}
++
+ static enum dsa_tag_protocol
+ qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
+                      enum dsa_tag_protocol mp)
+@@ -1774,6 +1790,7 @@ static const struct dsa_switch_ops qca8k
+       .phylink_mac_config     = qca8k_phylink_mac_config,
+       .phylink_mac_link_down  = qca8k_phylink_mac_link_down,
+       .phylink_mac_link_up    = qca8k_phylink_mac_link_up,
++      .get_phy_flags          = qca8k_get_phy_flags,
+ };
+ static int qca8k_read_switch_id(struct qca8k_priv *priv)
diff --git a/target/linux/generic/backport-5.10/735-v5.14-25-net-phy-add-support-for-qca8k-switch-internal-PHY-in.patch b/target/linux/generic/backport-5.10/735-v5.14-25-net-phy-add-support-for-qca8k-switch-internal-PHY-in.patch
new file mode 100644 (file)
index 0000000..20325f5
--- /dev/null
@@ -0,0 +1,229 @@
+From 272833b9b3b3969be7a91839121d86662c8c4253 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Fri, 14 May 2021 23:00:15 +0200
+Subject: [PATCH] net: phy: add support for qca8k switch internal PHY in at803x
+
+Since the at803x share the same regs, it's assumed they are based on the
+same implementation. Make it part of the at803x PHY driver to skip
+having redudant code.
+Add initial support for qca8k internal PHYs. The internal PHYs requires
+special mmd and debug values to be set based on the switch revision
+passwd using the dev_flags. Supports output of idle, receive and eee_wake
+errors stats.
+Some debug values sets can't be translated as the documentation lacks any
+reference about them.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/Kconfig  |   5 +-
+ drivers/net/phy/at803x.c | 132 ++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 134 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -235,10 +235,11 @@ config NXP_TJA11XX_PHY
+         Currently supports the NXP TJA1100 and TJA1101 PHY.
+ config AT803X_PHY
+-      tristate "Qualcomm Atheros AR803X PHYs"
++      tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs"
+       depends on REGULATOR
+       help
+-        Currently supports the AR8030, AR8031, AR8033 and AR8035 model
++        Currently supports the AR8030, AR8031, AR8033, AR8035 and internal
++        QCA8337(Internal qca8k PHY) model
+ config QSEMI_PHY
+       tristate "Quality Semiconductor PHYs"
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -92,10 +92,16 @@
+ #define AT803X_DEBUG_REG_5                    0x05
+ #define AT803X_DEBUG_TX_CLK_DLY_EN            BIT(8)
++#define AT803X_DEBUG_REG_3C                   0x3C
++
++#define AT803X_DEBUG_REG_3D                   0x3D
++
+ #define AT803X_DEBUG_REG_1F                   0x1F
+ #define AT803X_DEBUG_PLL_ON                   BIT(2)
+ #define AT803X_DEBUG_RGMII_1V8                        BIT(3)
++#define MDIO_AZ_DEBUG                         0x800D
++
+ /* AT803x supports either the XTAL input pad, an internal PLL or the
+  * DSP as clock reference for the clock output pad. The XTAL reference
+  * is only used for 25 MHz output, all other frequencies need the PLL.
+@@ -142,10 +148,34 @@
+ #define AT803X_PAGE_FIBER             0
+ #define AT803X_PAGE_COPPER            1
++#define QCA8327_PHY_ID                                0x004dd034
++#define QCA8337_PHY_ID                                0x004dd036
++#define QCA8K_PHY_ID_MASK                     0xffffffff
++
++#define QCA8K_DEVFLAGS_REVISION_MASK          GENMASK(2, 0)
++
+ MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
+ MODULE_AUTHOR("Matus Ujhelyi");
+ MODULE_LICENSE("GPL");
++enum stat_access_type {
++      PHY,
++      MMD
++};
++
++struct at803x_hw_stat {
++      const char *string;
++      u8 reg;
++      u32 mask;
++      enum stat_access_type access_type;
++};
++
++static struct at803x_hw_stat at803x_hw_stats[] = {
++      { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
++      { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
++      { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
++};
++
+ struct at803x_priv {
+       int flags;
+ #define AT803X_KEEP_PLL_ENABLED       BIT(0)  /* don't turn off internal PLL */
+@@ -154,6 +184,7 @@ struct at803x_priv {
+       struct regulator_dev *vddio_rdev;
+       struct regulator_dev *vddh_rdev;
+       struct regulator *vddio;
++      u64 stats[ARRAY_SIZE(at803x_hw_stats)];
+ };
+ struct at803x_context {
+@@ -165,6 +196,17 @@ struct at803x_context {
+       u16 led_control;
+ };
++static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data)
++{
++      int ret;
++
++      ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
++      if (ret < 0)
++              return ret;
++
++      return phy_write(phydev, AT803X_DEBUG_DATA, data);
++}
++
+ static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
+ {
+       int ret;
+@@ -327,6 +369,53 @@ static void at803x_get_wol(struct phy_de
+               wol->wolopts |= WAKE_MAGIC;
+ }
++static int at803x_get_sset_count(struct phy_device *phydev)
++{
++      return ARRAY_SIZE(at803x_hw_stats);
++}
++
++static void at803x_get_strings(struct phy_device *phydev, u8 *data)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) {
++              strscpy(data + i * ETH_GSTRING_LEN,
++                      at803x_hw_stats[i].string, ETH_GSTRING_LEN);
++      }
++}
++
++static u64 at803x_get_stat(struct phy_device *phydev, int i)
++{
++      struct at803x_hw_stat stat = at803x_hw_stats[i];
++      struct at803x_priv *priv = phydev->priv;
++      int val;
++      u64 ret;
++
++      if (stat.access_type == MMD)
++              val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg);
++      else
++              val = phy_read(phydev, stat.reg);
++
++      if (val < 0) {
++              ret = U64_MAX;
++      } else {
++              val = val & stat.mask;
++              priv->stats[i] += val;
++              ret = priv->stats[i];
++      }
++
++      return ret;
++}
++
++static void at803x_get_stats(struct phy_device *phydev,
++                           struct ethtool_stats *stats, u64 *data)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++)
++              data[i] = at803x_get_stat(phydev, i);
++}
++
+ static int at803x_suspend(struct phy_device *phydev)
+ {
+       int value;
+@@ -1102,6 +1191,34 @@ static int at803x_cable_test_start(struc
+       return 0;
+ }
++static int qca83xx_config_init(struct phy_device *phydev)
++{
++      u8 switch_revision;
++
++      switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK;
++
++      switch (switch_revision) {
++      case 1:
++              /* For 100M waveform */
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_0, 0x02ea);
++              /* Turn on Gigabit clock */
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x68a0);
++              break;
++
++      case 2:
++              phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0);
++              fallthrough;
++      case 4:
++              phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x6860);
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_5, 0x2c46);
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
++              break;
++      }
++
++      return 0;
++}
++
+ static struct phy_driver at803x_driver[] = {
+ {
+       /* Qualcomm Atheros AR8035 */
+@@ -1198,7 +1315,20 @@ static struct phy_driver at803x_driver[]
+       .read_status            = at803x_read_status,
+       .soft_reset             = genphy_soft_reset,
+       .config_aneg            = at803x_config_aneg,
+-} };
++}, {
++      /* QCA8337 */
++      .phy_id = QCA8337_PHY_ID,
++      .phy_id_mask = QCA8K_PHY_ID_MASK,
++      .name = "QCA PHY 8337",
++      /* PHY_GBIT_FEATURES */
++      .probe = at803x_probe,
++      .flags = PHY_IS_INTERNAL,
++      .config_init = qca83xx_config_init,
++      .soft_reset = genphy_soft_reset,
++      .get_sset_count = at803x_get_sset_count,
++      .get_strings = at803x_get_strings,
++      .get_stats = at803x_get_stats,
++}, };
+ module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-5.10/736-v5.14-net-dsa-qca8k-fix-missing-unlock-on-error-in-qca8k-vlan.patch b/target/linux/generic/backport-5.10/736-v5.14-net-dsa-qca8k-fix-missing-unlock-on-error-in-qca8k-vlan.patch
new file mode 100644 (file)
index 0000000..a68e3b1
--- /dev/null
@@ -0,0 +1,64 @@
+From 0d56e5c191b197e1d30a0a4c92628836dafced0f Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Tue, 18 May 2021 11:24:13 +0000
+Subject: [PATCH] net: dsa: qca8k: fix missing unlock on error in
+ qca8k_vlan_(add|del)
+
+Add the missing unlock before return from function qca8k_vlan_add()
+and qca8k_vlan_del() in the error handling case.
+
+Fixes: 028f5f8ef44f ("net: dsa: qca8k: handle error with qca8k_read operation")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -506,8 +506,10 @@ qca8k_vlan_add(struct qca8k_priv *priv,
+               goto out;
+       reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+-      if (reg < 0)
+-              return reg;
++      if (reg < 0) {
++              ret = reg;
++              goto out;
++      }
+       reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
+       reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+       if (untagged)
+@@ -519,7 +521,7 @@ qca8k_vlan_add(struct qca8k_priv *priv,
+       ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+       if (ret)
+-              return ret;
++              goto out;
+       ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+ out:
+@@ -541,8 +543,10 @@ qca8k_vlan_del(struct qca8k_priv *priv,
+               goto out;
+       reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+-      if (reg < 0)
+-              return reg;
++      if (reg < 0) {
++              ret = reg;
++              goto out;
++      }
+       reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+       reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
+                       QCA8K_VTU_FUNC0_EG_MODE_S(port);
+@@ -564,7 +568,7 @@ qca8k_vlan_del(struct qca8k_priv *priv,
+       } else {
+               ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+               if (ret)
+-                      return ret;
++                      goto out;
+               ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+       }
diff --git a/target/linux/generic/backport-5.10/737-v5.14-01-net-dsa-qca8k-check-return-value-of-read-functions-c.patch b/target/linux/generic/backport-5.10/737-v5.14-01-net-dsa-qca8k-check-return-value-of-read-functions-c.patch
new file mode 100644 (file)
index 0000000..451b0e9
--- /dev/null
@@ -0,0 +1,348 @@
+From 7c9896e37807862e276064dd9331860f5d27affc Mon Sep 17 00:00:00 2001
+From: Yang Yingliang <yangyingliang@huawei.com>
+Date: Sat, 29 May 2021 11:04:38 +0800
+Subject: [PATCH] net: dsa: qca8k: check return value of read functions
+ correctly
+
+Current return type of qca8k_mii_read32() and qca8k_read() are
+unsigned, it can't be negative, so the return value check is
+unuseful. For check the return value correctly, change return
+type of the read functions and add a output parameter to store
+the read value.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/qca8k.c | 130 +++++++++++++++++++---------------------
+ 1 file changed, 60 insertions(+), 70 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -89,26 +89,26 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u
+       *page = regaddr & 0x3ff;
+ }
+-static u32
+-qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum)
++static int
++qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
+ {
+-      u32 val;
+       int ret;
+       ret = bus->read(bus, phy_id, regnum);
+       if (ret >= 0) {
+-              val = ret;
++              *val = ret;
+               ret = bus->read(bus, phy_id, regnum + 1);
+-              val |= ret << 16;
++              *val |= ret << 16;
+       }
+       if (ret < 0) {
+               dev_err_ratelimited(&bus->dev,
+                                   "failed to read qca8k 32bit register\n");
++              *val = 0;
+               return ret;
+       }
+-      return val;
++      return 0;
+ }
+ static void
+@@ -148,26 +148,26 @@ qca8k_set_page(struct mii_bus *bus, u16
+       return 0;
+ }
+-static u32
+-qca8k_read(struct qca8k_priv *priv, u32 reg)
++static int
++qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
+ {
+       struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+-      u32 val;
++      int ret;
+       qca8k_split_addr(reg, &r1, &r2, &page);
+       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+-      val = qca8k_set_page(bus, page);
+-      if (val < 0)
++      ret = qca8k_set_page(bus, page);
++      if (ret < 0)
+               goto exit;
+-      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
++      ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val);
+ exit:
+       mutex_unlock(&bus->mdio_lock);
+-      return val;
++      return ret;
+ }
+ static int
+@@ -208,11 +208,9 @@ qca8k_rmw(struct qca8k_priv *priv, u32 r
+       if (ret < 0)
+               goto exit;
+-      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
+-      if (val < 0) {
+-              ret = val;
++      ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
++      if (ret < 0)
+               goto exit;
+-      }
+       val &= ~mask;
+       val |= write_val;
+@@ -240,15 +238,8 @@ static int
+ qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
+-      int ret;
+-
+-      ret = qca8k_read(priv, reg);
+-      if (ret < 0)
+-              return ret;
+-
+-      *val = ret;
+-      return 0;
++      return qca8k_read(priv, reg, val);
+ }
+ static int
+@@ -296,18 +287,18 @@ static struct regmap_config qca8k_regmap
+ static int
+ qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
+ {
++      int ret, ret1;
+       u32 val;
+-      int ret;
+-      ret = read_poll_timeout(qca8k_read, val, !(val & mask),
++      ret = read_poll_timeout(qca8k_read, ret1, !(val & mask),
+                               0, QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
+-                              priv, reg);
++                              priv, reg, &val);
+       /* Check if qca8k_read has failed for a different reason
+        * before returning -ETIMEDOUT
+        */
+-      if (ret < 0 && val < 0)
+-              return val;
++      if (ret < 0 && ret1 < 0)
++              return ret1;
+       return ret;
+ }
+@@ -316,13 +307,13 @@ static int
+ qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
+ {
+       u32 reg[4], val;
+-      int i;
++      int i, ret;
+       /* load the ARL table into an array */
+       for (i = 0; i < 4; i++) {
+-              val = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4));
+-              if (val < 0)
+-                      return val;
++              ret = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4), &val);
++              if (ret < 0)
++                      return ret;
+               reg[i] = val;
+       }
+@@ -396,9 +387,9 @@ qca8k_fdb_access(struct qca8k_priv *priv
+       /* Check for table full violation when adding an entry */
+       if (cmd == QCA8K_FDB_LOAD) {
+-              reg = qca8k_read(priv, QCA8K_REG_ATU_FUNC);
+-              if (reg < 0)
+-                      return reg;
++              ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
++              if (ret < 0)
++                      return ret;
+               if (reg & QCA8K_ATU_FUNC_FULL)
+                       return -1;
+       }
+@@ -477,9 +468,9 @@ qca8k_vlan_access(struct qca8k_priv *pri
+       /* Check for table full violation when adding an entry */
+       if (cmd == QCA8K_VLAN_LOAD) {
+-              reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
+-              if (reg < 0)
+-                      return reg;
++              ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
++              if (ret < 0)
++                      return ret;
+               if (reg & QCA8K_VTU_FUNC1_FULL)
+                       return -ENOMEM;
+       }
+@@ -505,11 +496,9 @@ qca8k_vlan_add(struct qca8k_priv *priv,
+       if (ret < 0)
+               goto out;
+-      reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+-      if (reg < 0) {
+-              ret = reg;
++      ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
++      if (ret < 0)
+               goto out;
+-      }
+       reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
+       reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+       if (untagged)
+@@ -542,11 +531,9 @@ qca8k_vlan_del(struct qca8k_priv *priv,
+       if (ret < 0)
+               goto out;
+-      reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+-      if (reg < 0) {
+-              ret = reg;
++      ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
++      if (ret < 0)
+               goto out;
+-      }
+       reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+       reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
+                       QCA8K_VTU_FUNC0_EG_MODE_S(port);
+@@ -638,19 +625,19 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
+ {
+       u16 r1, r2, page;
+       u32 val;
+-      int ret;
++      int ret, ret1;
+       qca8k_split_addr(reg, &r1, &r2, &page);
+-      ret = read_poll_timeout(qca8k_mii_read32, val, !(val & mask), 0,
++      ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
+                               QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
+-                              bus, 0x10 | r2, r1);
++                              bus, 0x10 | r2, r1, &val);
+       /* Check if qca8k_read has failed for a different reason
+        * before returnting -ETIMEDOUT
+        */
+-      if (ret < 0 && val < 0)
+-              return val;
++      if (ret < 0 && ret1 < 0)
++              return ret1;
+       return ret;
+ }
+@@ -725,7 +712,7 @@ qca8k_mdio_read(struct mii_bus *salve_bu
+       if (ret)
+               goto exit;
+-      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
++      ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
+ exit:
+       /* even if the busy_wait timeouts try to clear the MASTER_EN */
+@@ -733,10 +720,10 @@ exit:
+       mutex_unlock(&bus->mdio_lock);
+-      if (val >= 0)
+-              val &= QCA8K_MDIO_MASTER_DATA_MASK;
++      if (ret >= 0)
++              ret = val & QCA8K_MDIO_MASTER_DATA_MASK;
+-      return val;
++      return ret;
+ }
+ static int
+@@ -1211,7 +1198,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+               qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
+               /* Enable/disable SerDes auto-negotiation as necessary */
+-              val = qca8k_read(priv, QCA8K_REG_PWS);
++              qca8k_read(priv, QCA8K_REG_PWS, &val);
+               if (phylink_autoneg_inband(mode))
+                       val &= ~QCA8K_PWS_SERDES_AEN_DIS;
+               else
+@@ -1219,7 +1206,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+               qca8k_write(priv, QCA8K_REG_PWS, val);
+               /* Configure the SGMII parameters */
+-              val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
++              qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
+               val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+                       QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
+@@ -1314,10 +1301,11 @@ qca8k_phylink_mac_link_state(struct dsa_
+ {
+       struct qca8k_priv *priv = ds->priv;
+       u32 reg;
++      int ret;
+-      reg = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port));
+-      if (reg < 0)
+-              return reg;
++      ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), &reg);
++      if (ret < 0)
++              return ret;
+       state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
+       state->an_complete = state->link;
+@@ -1419,19 +1407,20 @@ qca8k_get_ethtool_stats(struct dsa_switc
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+       const struct qca8k_mib_desc *mib;
+       u32 reg, i, val;
+-      u64 hi;
++      u64 hi = 0;
++      int ret;
+       for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
+               mib = &ar8327_mib[i];
+               reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
+-              val = qca8k_read(priv, reg);
+-              if (val < 0)
++              ret = qca8k_read(priv, reg, &val);
++              if (ret < 0)
+                       continue;
+               if (mib->size == 2) {
+-                      hi = qca8k_read(priv, reg + 4);
+-                      if (hi < 0)
++                      ret = qca8k_read(priv, reg + 4, (u32 *)&hi);
++                      if (ret < 0)
+                               continue;
+               }
+@@ -1459,7 +1448,7 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
+       int ret;
+       mutex_lock(&priv->reg_mutex);
+-      reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL);
++      ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
+       if (reg < 0) {
+               ret = reg;
+               goto exit;
+@@ -1802,14 +1791,15 @@ static int qca8k_read_switch_id(struct q
+       const struct qca8k_match_data *data;
+       u32 val;
+       u8 id;
++      int ret;
+       /* get the switches ID from the compatible */
+       data = of_device_get_match_data(priv->dev);
+       if (!data)
+               return -ENODEV;
+-      val = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
+-      if (val < 0)
++      ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
++      if (ret < 0)
+               return -ENODEV;
+       id = QCA8K_MASK_CTRL_DEVICE_ID(val & QCA8K_MASK_CTRL_DEVICE_ID_MASK);
diff --git a/target/linux/generic/backport-5.10/737-v5.14-02-net-dsa-qca8k-add-missing-check-return-value-in-qca8.patch b/target/linux/generic/backport-5.10/737-v5.14-02-net-dsa-qca8k-add-missing-check-return-value-in-qca8.patch
new file mode 100644 (file)
index 0000000..d20da5b
--- /dev/null
@@ -0,0 +1,47 @@
+From 9fe99de01440d9ede74d447ac76e9c445d8daae9 Mon Sep 17 00:00:00 2001
+From: Yang Yingliang <yangyingliang@huawei.com>
+Date: Sat, 29 May 2021 11:04:39 +0800
+Subject: [PATCH] net: dsa: qca8k: add missing check return value in
+ qca8k_phylink_mac_config()
+
+Now we can check qca8k_read() return value correctly, so if
+it fails, we need return directly.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/qca8k.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1128,6 +1128,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+ {
+       struct qca8k_priv *priv = ds->priv;
+       u32 reg, val;
++      int ret;
+       switch (port) {
+       case 0: /* 1st CPU port */
+@@ -1198,7 +1199,9 @@ qca8k_phylink_mac_config(struct dsa_swit
+               qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
+               /* Enable/disable SerDes auto-negotiation as necessary */
+-              qca8k_read(priv, QCA8K_REG_PWS, &val);
++              ret = qca8k_read(priv, QCA8K_REG_PWS, &val);
++              if (ret)
++                      return;
+               if (phylink_autoneg_inband(mode))
+                       val &= ~QCA8K_PWS_SERDES_AEN_DIS;
+               else
+@@ -1206,7 +1209,9 @@ qca8k_phylink_mac_config(struct dsa_swit
+               qca8k_write(priv, QCA8K_REG_PWS, val);
+               /* Configure the SGMII parameters */
+-              qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
++              ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
++              if (ret)
++                      return;
+               val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+                       QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
diff --git a/target/linux/generic/backport-5.10/738-v5.14-01-net-dsa-qca8k-fix-an-endian-bug-in-qca8k-get-ethtool.patch b/target/linux/generic/backport-5.10/738-v5.14-01-net-dsa-qca8k-fix-an-endian-bug-in-qca8k-get-ethtool.patch
new file mode 100644 (file)
index 0000000..429d5d5
--- /dev/null
@@ -0,0 +1,47 @@
+aFrom aa3d020b22cb844ab7bdbb9e5d861a64666e2b74 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 9 Jun 2021 12:52:12 +0300
+Subject: [PATCH] net: dsa: qca8k: fix an endian bug in
+ qca8k_get_ethtool_stats()
+
+The "hi" variable is a u64 but the qca8k_read() writes to the top 32
+bits of it.  That will work on little endian systems but it's a bit
+subtle.  It's cleaner to make declare "hi" as a u32.  We will still need
+to cast it when we shift it later on in the function but that's fine.
+
+Fixes: 7c9896e37807 ("net: dsa: qca8k: check return value of read functions correctly")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1412,7 +1412,7 @@ qca8k_get_ethtool_stats(struct dsa_switc
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+       const struct qca8k_mib_desc *mib;
+       u32 reg, i, val;
+-      u64 hi = 0;
++      u32 hi = 0;
+       int ret;
+       for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
+@@ -1424,14 +1424,14 @@ qca8k_get_ethtool_stats(struct dsa_switc
+                       continue;
+               if (mib->size == 2) {
+-                      ret = qca8k_read(priv, reg + 4, (u32 *)&hi);
++                      ret = qca8k_read(priv, reg + 4, &hi);
+                       if (ret < 0)
+                               continue;
+               }
+               data[i] = val;
+               if (mib->size == 2)
+-                      data[i] |= hi << 32;
++                      data[i] |= (u64)hi << 32;
+       }
+ }
diff --git a/target/linux/generic/backport-5.10/738-v5.14-02-net-dsa-qca8k-check-the-correct-variable-in-qca8k-se.patch b/target/linux/generic/backport-5.10/738-v5.14-02-net-dsa-qca8k-check-the-correct-variable-in-qca8k-se.patch
new file mode 100644 (file)
index 0000000..c58f79c
--- /dev/null
@@ -0,0 +1,31 @@
+From 3d0167f2a627528032821cdeb78b4eab0510460f Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 9 Jun 2021 12:53:03 +0300
+Subject: [PATCH] net: dsa: qca8k: check the correct variable in
+ qca8k_set_mac_eee()
+
+This code check "reg" but "ret" was intended so the error handling will
+never trigger.
+
+Fixes: 7c9896e37807 ("net: dsa: qca8k: check return value of read functions correctly")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1454,10 +1454,8 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
+       mutex_lock(&priv->reg_mutex);
+       ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
+-      if (reg < 0) {
+-              ret = reg;
++      if (ret < 0)
+               goto exit;
+-      }
+       if (eee->eee_enabled)
+               reg |= lpi_en;
diff --git a/target/linux/generic/backport-5.10/739-v5.15-net-dsa-qca8k-fix-kernel-panic-with-legacy-mdio-mapping.patch b/target/linux/generic/backport-5.10/739-v5.15-net-dsa-qca8k-fix-kernel-panic-with-legacy-mdio-mapping.patch
new file mode 100644 (file)
index 0000000..1e293d3
--- /dev/null
@@ -0,0 +1,80 @@
+From ce062a0adbfe933b1932235fdfd874c4c91d1bb0 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sat, 11 Sep 2021 17:50:09 +0200
+Subject: net: dsa: qca8k: fix kernel panic with legacy mdio mapping
+
+When the mdio legacy mapping is used the mii_bus priv registered by DSA
+refer to the dsa switch struct instead of the qca8k_priv struct and
+causes a kernel panic. Create dedicated function when the internal
+dedicated mdio driver is used to properly handle the 2 different
+implementation.
+
+Fixes: 759bafb8a322 ("net: dsa: qca8k: add support for internal phy and internal mdio")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 30 ++++++++++++++++++++++--------
+ 1 file changed, 22 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -643,10 +643,8 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
+ }
+ static int
+-qca8k_mdio_write(struct mii_bus *salve_bus, int phy, int regnum, u16 data)
++qca8k_mdio_write(struct mii_bus *bus, int phy, int regnum, u16 data)
+ {
+-      struct qca8k_priv *priv = salve_bus->priv;
+-      struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+       u32 val;
+       int ret;
+@@ -682,10 +680,8 @@ exit:
+ }
+ static int
+-qca8k_mdio_read(struct mii_bus *salve_bus, int phy, int regnum)
++qca8k_mdio_read(struct mii_bus *bus, int phy, int regnum)
+ {
+-      struct qca8k_priv *priv = salve_bus->priv;
+-      struct mii_bus *bus = priv->bus;
+       u16 r1, r2, page;
+       u32 val;
+       int ret;
+@@ -727,6 +723,24 @@ exit:
+ }
+ static int
++qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)
++{
++      struct qca8k_priv *priv = slave_bus->priv;
++      struct mii_bus *bus = priv->bus;
++
++      return qca8k_mdio_write(bus, phy, regnum, data);
++}
++
++static int
++qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)
++{
++      struct qca8k_priv *priv = slave_bus->priv;
++      struct mii_bus *bus = priv->bus;
++
++      return qca8k_mdio_read(bus, phy, regnum);
++}
++
++static int
+ qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data)
+ {
+       struct qca8k_priv *priv = ds->priv;
+@@ -775,8 +789,8 @@ qca8k_mdio_register(struct qca8k_priv *p
+       bus->priv = (void *)priv;
+       bus->name = "qca8k slave mii";
+-      bus->read = qca8k_mdio_read;
+-      bus->write = qca8k_mdio_write;
++      bus->read = qca8k_internal_mdio_read;
++      bus->write = qca8k_internal_mdio_write;
+       snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d",
+                ds->index);
diff --git a/target/linux/generic/backport-5.10/740-v5.12-net-phy-Add-100-base-x-mode.patch b/target/linux/generic/backport-5.10/740-v5.12-net-phy-Add-100-base-x-mode.patch
deleted file mode 100644 (file)
index 5c7f97e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From b1ae3587d16a8c8fc9453e147c8708d6f006ffbb Mon Sep 17 00:00:00 2001
-From: Bjarni Jonasson <bjarni.jonasson@microchip.com>
-Date: Wed, 13 Jan 2021 12:56:25 +0100
-Subject: [PATCH] net: phy: Add 100 base-x mode
-
-Sparx-5 supports this mode and it is missing in the PHY core.
-
-Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
-Reviewed-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- Documentation/networking/phy.rst | 5 +++++
- include/linux/phy.h              | 4 ++++
- 2 files changed, 9 insertions(+)
-
---- a/Documentation/networking/phy.rst
-+++ b/Documentation/networking/phy.rst
-@@ -286,6 +286,11 @@ Some of the interface modes are describe
-     Note: due to legacy usage, some 10GBASE-R usage incorrectly makes
-     use of this definition.
-+``PHY_INTERFACE_MODE_100BASEX``
-+    This defines IEEE 802.3 Clause 24.  The link operates at a fixed data
-+    rate of 125Mpbs using a 4B/5B encoding scheme, resulting in an underlying
-+    data rate of 100Mpbs.
-+
- Pause frames / flow control
- ===========================
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -104,6 +104,7 @@ extern const int phy_10gbit_features_arr
-  * @PHY_INTERFACE_MODE_MOCA: Multimedia over Coax
-  * @PHY_INTERFACE_MODE_QSGMII: Quad SGMII
-  * @PHY_INTERFACE_MODE_TRGMII: Turbo RGMII
-+ * @PHY_INTERFACE_MODE_100BASEX: 100 BaseX
-  * @PHY_INTERFACE_MODE_1000BASEX: 1000 BaseX
-  * @PHY_INTERFACE_MODE_2500BASEX: 2500 BaseX
-  * @PHY_INTERFACE_MODE_RXAUI: Reduced XAUI
-@@ -135,6 +136,7 @@ typedef enum {
-       PHY_INTERFACE_MODE_MOCA,
-       PHY_INTERFACE_MODE_QSGMII,
-       PHY_INTERFACE_MODE_TRGMII,
-+      PHY_INTERFACE_MODE_100BASEX,
-       PHY_INTERFACE_MODE_1000BASEX,
-       PHY_INTERFACE_MODE_2500BASEX,
-       PHY_INTERFACE_MODE_RXAUI,
-@@ -217,6 +219,8 @@ static inline const char *phy_modes(phy_
-               return "usxgmii";
-       case PHY_INTERFACE_MODE_10GKR:
-               return "10gbase-kr";
-+      case PHY_INTERFACE_MODE_100BASEX:
-+              return "100base-x";
-       default:
-               return "unknown";
-       }
diff --git a/target/linux/generic/backport-5.10/740-v5.13-0001-net-dsa-b53-Add-debug-prints-in-b53_vlan_enable.patch b/target/linux/generic/backport-5.10/740-v5.13-0001-net-dsa-b53-Add-debug-prints-in-b53_vlan_enable.patch
new file mode 100644 (file)
index 0000000..91cf55b
--- /dev/null
@@ -0,0 +1,65 @@
+From ee47ed08d75e8f16b3cf882061ee19c2ea19dd6c Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Wed, 10 Mar 2021 10:52:26 -0800
+Subject: [PATCH] net: dsa: b53: Add debug prints in b53_vlan_enable()
+
+Having dynamic debug prints in b53_vlan_enable() has been helpful to
+uncover a recent but update the function to indicate the port being
+configured (or -1 for initial setup) and include the global VLAN enabled
+and VLAN filtering enable status.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -349,7 +349,7 @@ static void b53_set_forwarding(struct b5
+       b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt);
+ }
+-static void b53_enable_vlan(struct b53_device *dev, bool enable,
++static void b53_enable_vlan(struct b53_device *dev, int port, bool enable,
+                           bool enable_filtering)
+ {
+       u8 mgmt, vc0, vc1, vc4 = 0, vc5;
+@@ -431,6 +431,9 @@ static void b53_enable_vlan(struct b53_d
+       b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
+       dev->vlan_enabled = enable;
++
++      dev_dbg(dev->dev, "Port %d VLAN enabled: %d, filtering: %d\n",
++              port, enable, enable_filtering);
+ }
+ static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100)
+@@ -708,7 +711,7 @@ int b53_configure_vlan(struct dsa_switch
+               b53_do_vlan_op(dev, VTA_CMD_CLEAR);
+       }
+-      b53_enable_vlan(dev, dev->vlan_enabled, ds->vlan_filtering);
++      b53_enable_vlan(dev, -1, dev->vlan_enabled, ds->vlan_filtering);
+       b53_for_each_port(dev, i)
+               b53_write16(dev, B53_VLAN_PAGE,
+@@ -1390,7 +1393,7 @@ int b53_vlan_filtering(struct dsa_switch
+       if (switchdev_trans_ph_prepare(trans))
+               return 0;
+-      b53_enable_vlan(dev, dev->vlan_enabled, vlan_filtering);
++      b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering);
+       return 0;
+ }
+@@ -1415,7 +1418,7 @@ int b53_vlan_prepare(struct dsa_switch *
+       if (vlan->vid_end >= dev->num_vlans)
+               return -ERANGE;
+-      b53_enable_vlan(dev, true, ds->vlan_filtering);
++      b53_enable_vlan(dev, port, true, ds->vlan_filtering);
+       return 0;
+ }
diff --git a/target/linux/generic/backport-5.10/740-v5.13-0002-net-dsa-b53-spi-allow-device-tree-probing.patch b/target/linux/generic/backport-5.10/740-v5.13-0002-net-dsa-b53-spi-allow-device-tree-probing.patch
new file mode 100644 (file)
index 0000000..56579b2
--- /dev/null
@@ -0,0 +1,41 @@
+From 6d16eadab6db0c1d61e59fee7ed1ecc2d10269be Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Mon, 15 Mar 2021 15:14:23 +0100
+Subject: [PATCH] net: dsa: b53: spi: allow device tree probing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add missing of_match_table to allow device tree probing.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_spi.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_spi.c
++++ b/drivers/net/dsa/b53/b53_spi.c
+@@ -324,9 +324,22 @@ static int b53_spi_remove(struct spi_dev
+       return 0;
+ }
++static const struct of_device_id b53_spi_of_match[] = {
++      { .compatible = "brcm,bcm5325" },
++      { .compatible = "brcm,bcm5365" },
++      { .compatible = "brcm,bcm5395" },
++      { .compatible = "brcm,bcm5397" },
++      { .compatible = "brcm,bcm5398" },
++      { .compatible = "brcm,bcm53115" },
++      { .compatible = "brcm,bcm53125" },
++      { .compatible = "brcm,bcm53128" },
++      { /* sentinel */ }
++};
++
+ static struct spi_driver b53_spi_driver = {
+       .driver = {
+               .name   = "b53-switch",
++              .of_match_table = b53_spi_of_match,
+       },
+       .probe  = b53_spi_probe,
+       .remove = b53_spi_remove,
diff --git a/target/linux/generic/backport-5.10/740-v5.13-0003-net-dsa-b53-relax-is63xx-condition.patch b/target/linux/generic/backport-5.10/740-v5.13-0003-net-dsa-b53-relax-is63xx-condition.patch
new file mode 100644 (file)
index 0000000..99eced1
--- /dev/null
@@ -0,0 +1,31 @@
+From ad426d7d966b525b73ed5a1842dd830312bbba71 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 17 Mar 2021 09:42:01 +0100
+Subject: [PATCH] net: dsa: b53: relax is63xx() condition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM63xx switches are present on bcm63xx and bmips devices.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_priv.h | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -186,11 +186,7 @@ static inline int is531x5(struct b53_dev
+ static inline int is63xx(struct b53_device *dev)
+ {
+-#ifdef CONFIG_BCM63XX
+       return dev->chip_id == BCM63XX_DEVICE_ID;
+-#else
+-      return 0;
+-#endif
+ }
+ static inline int is5301x(struct b53_device *dev)
diff --git a/target/linux/generic/backport-5.10/740-v5.13-0004-net-dsa-tag_brcm-add-support-for-legacy-tags.patch b/target/linux/generic/backport-5.10/740-v5.13-0004-net-dsa-tag_brcm-add-support-for-legacy-tags.patch
new file mode 100644 (file)
index 0000000..3b7d8f3
--- /dev/null
@@ -0,0 +1,180 @@
+From 964dbf186eaa84d409c359ddf09c827a3fbe8228 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 17 Mar 2021 11:29:26 +0100
+Subject: [PATCH] net: dsa: tag_brcm: add support for legacy tags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for legacy Broadcom tags, which are similar to DSA_TAG_PROTO_BRCM.
+These tags are used on BCM5325, BCM5365 and BCM63xx switches.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ include/net/dsa.h  |   2 +
+ net/dsa/Kconfig    |   7 +++
+ net/dsa/tag_brcm.c | 107 +++++++++++++++++++++++++++++++++++++++++++--
+ 3 files changed, 113 insertions(+), 3 deletions(-)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -45,10 +45,12 @@ struct phylink_link_state;
+ #define DSA_TAG_PROTO_OCELOT_VALUE            15
+ #define DSA_TAG_PROTO_AR9331_VALUE            16
+ #define DSA_TAG_PROTO_RTL4_A_VALUE            17
++#define DSA_TAG_PROTO_BRCM_LEGACY_VALUE               22
+ 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_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
+@@ -47,6 +47,13 @@ config NET_DSA_TAG_BRCM
+         Say Y if you want to enable support for tagging frames for the
+         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"
++      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
++        address.
+ 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
+@@ -11,9 +11,26 @@
+ #include "dsa_priv.h"
+-/* This tag length is 4 bytes, older ones were 6 bytes, we do not
+- * handle them
+- */
++/* Legacy Broadcom tag (6 bytes) */
++#define BRCM_LEG_TAG_LEN      6
++
++/* Type fields */
++/* 1st byte in the tag */
++#define BRCM_LEG_TYPE_HI      0x88
++/* 2nd byte in the tag */
++#define BRCM_LEG_TYPE_LO      0x74
++
++/* Tag fields */
++/* 3rd byte in the tag */
++#define BRCM_LEG_UNICAST      (0 << 5)
++#define BRCM_LEG_MULTICAST    (1 << 5)
++#define BRCM_LEG_EGRESS               (2 << 5)
++#define BRCM_LEG_INGRESS      (3 << 5)
++
++/* 6th byte in the tag */
++#define BRCM_LEG_PORT_ID      (0xf)
++
++/* Newer Broadcom tag (4 bytes) */
+ #define BRCM_TAG_LEN  4
+ /* Tag is constructed and desconstructed using byte by byte access
+@@ -194,6 +211,87 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
+ MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM);
+ #endif
++#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)
++{
++      struct dsa_port *dp = dsa_slave_to_port(dev);
++      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_slave_xmit() free the SKB
++       */
++      if (__skb_put_padto(skb, ETH_ZLEN + BRCM_LEG_TAG_LEN, false))
++              return NULL;
++
++      skb_push(skb, BRCM_LEG_TAG_LEN);
++
++      memmove(skb->data, skb->data + BRCM_LEG_TAG_LEN, 2 * ETH_ALEN);
++
++      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_tag[3] = 0;
++      brcm_tag[4] = 0;
++      brcm_tag[5] = dp->index & BRCM_LEG_PORT_ID;
++
++      return skb;
++}
++
++static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
++                                      struct net_device *dev,
++                                      struct packet_type *pt)
++{
++      int source_port;
++      u8 *brcm_tag;
++
++      if (unlikely(!pskb_may_pull(skb, BRCM_LEG_PORT_ID)))
++              return NULL;
++
++      brcm_tag = skb->data - 2;
++
++      source_port = brcm_tag[5] & BRCM_LEG_PORT_ID;
++
++      skb->dev = dsa_master_find_slave(dev, 0, source_port);
++      if (!skb->dev)
++              return NULL;
++
++      /* Remove Broadcom tag and update checksum */
++      skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
++
++      skb->offload_fwd_mark = 1;
++
++      /* Move the Ethernet DA and SA */
++      memmove(skb->data - ETH_HLEN,
++              skb->data - ETH_HLEN - BRCM_LEG_TAG_LEN,
++              2 * ETH_ALEN);
++
++      return skb;
++}
++
++static const struct dsa_device_ops brcm_legacy_netdev_ops = {
++      .name = "brcm-legacy",
++      .proto = DSA_TAG_PROTO_BRCM_LEGACY,
++      .xmit = brcm_leg_tag_xmit,
++      .rcv = brcm_leg_tag_rcv,
++      .overhead = BRCM_LEG_TAG_LEN,
++};
++
++DSA_TAG_DRIVER(brcm_legacy_netdev_ops);
++MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY);
++#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */
++
+ #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)
+@@ -226,6 +324,9 @@ static struct dsa_tag_driver *dsa_tag_dr
+ #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
+       &DSA_TAG_DRIVER_NAME(brcm_netdev_ops),
+ #endif
++#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_PREPEND)
+       &DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops),
+ #endif
diff --git a/target/linux/generic/backport-5.10/740-v5.13-0005-net-dsa-b53-support-legacy-tags.patch b/target/linux/generic/backport-5.10/740-v5.13-0005-net-dsa-b53-support-legacy-tags.patch
new file mode 100644 (file)
index 0000000..838e78a
--- /dev/null
@@ -0,0 +1,53 @@
+From 46c5176c586c81306bf9e7024c13b95da775490f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 17 Mar 2021 11:29:27 +0100
+Subject: [PATCH] net: dsa: b53: support legacy tags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These tags are used on BCM5325, BCM5365 and BCM63xx switches.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/Kconfig      |  1 +
+ drivers/net/dsa/b53/b53_common.c | 12 +++++++-----
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/dsa/b53/Kconfig
++++ b/drivers/net/dsa/b53/Kconfig
+@@ -3,6 +3,7 @@ menuconfig B53
+       tristate "Broadcom BCM53xx managed switch support"
+       depends on NET_DSA
+       select NET_DSA_TAG_BRCM
++      select NET_DSA_TAG_BRCM_LEGACY
+       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
+@@ -2024,15 +2024,17 @@ enum dsa_tag_protocol b53_get_tag_protoc
+ {
+       struct b53_device *dev = ds->priv;
+-      /* Older models (5325, 5365) support a different tag format that we do
+-       * not support in net/dsa/tag_brcm.c yet.
+-       */
+-      if (is5325(dev) || is5365(dev) ||
+-          !b53_can_enable_brcm_tags(ds, port, mprot)) {
++      if (!b53_can_enable_brcm_tags(ds, port, mprot)) {
+               dev->tag_protocol = DSA_TAG_PROTO_NONE;
+               goto out;
+       }
++      /* Older models require a different 6 byte tag */
++      if (is5325(dev) || is5365(dev) || is63xx(dev)) {
++              dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY;
++              goto out;
++      }
++
+       /* Broadcom BCM58xx chips have a flow accelerator on Port 8
+        * which requires us to use the prepended Broadcom tag type
+        */
diff --git a/target/linux/generic/backport-5.10/740-v5.13-0006-net-dsa-b53-mmap-Add-device-tree-support.patch b/target/linux/generic/backport-5.10/740-v5.13-0006-net-dsa-b53-mmap-Add-device-tree-support.patch
new file mode 100644 (file)
index 0000000..c1014b2
--- /dev/null
@@ -0,0 +1,92 @@
+From a5538a777b73b35750ed1ffff8c1ef539e861624 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 17 Mar 2021 10:23:17 +0100
+Subject: [PATCH] net: dsa: b53: mmap: Add device tree support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add device tree support to b53_mmap.c while keeping platform devices support.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_mmap.c | 55 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -16,6 +16,7 @@
+  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+  */
++#include <linux/bits.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/io.h>
+@@ -228,11 +229,65 @@ static const struct b53_io_ops b53_mmap_
+       .write64 = b53_mmap_write64,
+ };
++static int b53_mmap_probe_of(struct platform_device *pdev,
++                           struct b53_platform_data **ppdata)
++{
++      struct device_node *np = pdev->dev.of_node;
++      struct device_node *of_ports, *of_port;
++      struct device *dev = &pdev->dev;
++      struct b53_platform_data *pdata;
++      void __iomem *mem;
++
++      mem = devm_platform_ioremap_resource(pdev, 0);
++      if (IS_ERR(mem))
++              return PTR_ERR(mem);
++
++      pdata = devm_kzalloc(dev, sizeof(struct b53_platform_data),
++                           GFP_KERNEL);
++      if (!pdata)
++              return -ENOMEM;
++
++      pdata->regs = mem;
++      pdata->chip_id = BCM63XX_DEVICE_ID;
++      pdata->big_endian = of_property_read_bool(np, "big-endian");
++
++      of_ports = of_get_child_by_name(np, "ports");
++      if (!of_ports) {
++              dev_err(dev, "no ports child node found\n");
++              return -EINVAL;
++      }
++
++      for_each_available_child_of_node(of_ports, of_port) {
++              u32 reg;
++
++              if (of_property_read_u32(of_port, "reg", &reg))
++                      continue;
++
++              if (reg < B53_CPU_PORT)
++                      pdata->enabled_ports |= BIT(reg);
++      }
++
++      of_node_put(of_ports);
++      *ppdata = pdata;
++
++      return 0;
++}
++
+ static int b53_mmap_probe(struct platform_device *pdev)
+ {
++      struct device_node *np = pdev->dev.of_node;
+       struct b53_platform_data *pdata = pdev->dev.platform_data;
+       struct b53_mmap_priv *priv;
+       struct b53_device *dev;
++      int ret;
++
++      if (!pdata && np) {
++              ret = b53_mmap_probe_of(pdev, &pdata);
++              if (ret) {
++                      dev_err(&pdev->dev, "OF probe error\n");
++                      return ret;
++              }
++      }
+       if (!pdata)
+               return -EINVAL;
diff --git a/target/linux/generic/backport-5.10/740-v5.13-0007-net-dsa-b53-spi-add-missing-MODULE_DEVICE_TABLE.patch b/target/linux/generic/backport-5.10/740-v5.13-0007-net-dsa-b53-spi-add-missing-MODULE_DEVICE_TABLE.patch
new file mode 100644 (file)
index 0000000..ea36755
--- /dev/null
@@ -0,0 +1,27 @@
+From 866f1577ba69bde2b9f36c300f603596c7d84a62 Mon Sep 17 00:00:00 2001
+From: Qinglang Miao <miaoqinglang@huawei.com>
+Date: Thu, 25 Mar 2021 17:19:54 +0800
+Subject: [PATCH] net: dsa: b53: spi: add missing MODULE_DEVICE_TABLE
+
+This patch adds missing MODULE_DEVICE_TABLE definition which generates
+correct modalias for automatic loading of this driver when it is built
+as an external module.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Qinglang Miao <miaoqinglang@huawei.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_spi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/dsa/b53/b53_spi.c
++++ b/drivers/net/dsa/b53/b53_spi.c
+@@ -335,6 +335,7 @@ static const struct of_device_id b53_spi
+       { .compatible = "brcm,bcm53128" },
+       { /* sentinel */ }
+ };
++MODULE_DEVICE_TABLE(of, b53_spi_of_match);
+ static struct spi_driver b53_spi_driver = {
+       .driver = {
diff --git a/target/linux/generic/backport-5.10/741-v5.12-sfp-add-support-for-100-base-x-SFPs.patch b/target/linux/generic/backport-5.10/741-v5.12-sfp-add-support-for-100-base-x-SFPs.patch
deleted file mode 100644 (file)
index 7d06c23..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From 6e12f35cef6b8a458d7ecf507ae330e0bffaad8c Mon Sep 17 00:00:00 2001
-From: Bjarni Jonasson <bjarni.jonasson@microchip.com>
-Date: Wed, 13 Jan 2021 12:56:26 +0100
-Subject: [PATCH] sfp: add support for 100 base-x SFPs
-
-Add support for 100Base-FX, 100Base-LX, 100Base-PX and 100Base-BX10 modules
-This is needed for Sparx-5 switch.
-
-Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
-Reviewed-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/sfp-bus.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/drivers/net/phy/sfp-bus.c
-+++ b/drivers/net/phy/sfp-bus.c
-@@ -280,6 +280,12 @@ void sfp_parse_support(struct sfp_bus *b
-           br_min <= 1300 && br_max >= 1200)
-               phylink_set(modes, 1000baseX_Full);
-+      /* 100Base-FX, 100Base-LX, 100Base-PX, 100Base-BX10 */
-+      if (id->base.e100_base_fx || id->base.e100_base_lx)
-+              phylink_set(modes, 100baseFX_Full);
-+      if ((id->base.e_base_px || id->base.e_base_bx10) && br_nom == 100)
-+              phylink_set(modes, 100baseFX_Full);
-+
-       /* For active or passive cables, select the link modes
-        * based on the bit rates and the cable compliance bytes.
-        */
-@@ -399,6 +405,9 @@ phy_interface_t sfp_select_interface(str
-       if (phylink_test(link_modes, 1000baseX_Full))
-               return PHY_INTERFACE_MODE_1000BASEX;
-+      if (phylink_test(link_modes, 100baseFX_Full))
-+              return PHY_INTERFACE_MODE_100BASEX;
-+
-       dev_warn(bus->sfp_dev, "Unable to ascertain link mode\n");
-       return PHY_INTERFACE_MODE_NA;
diff --git a/target/linux/generic/backport-5.10/741-v5.14-0001-net-dsa-b53-Do-not-force-CPU-to-be-always-tagged.patch b/target/linux/generic/backport-5.10/741-v5.14-0001-net-dsa-b53-Do-not-force-CPU-to-be-always-tagged.patch
new file mode 100644 (file)
index 0000000..2a8def3
--- /dev/null
@@ -0,0 +1,86 @@
+From 2c32a3d3c233b855943677609fe388f82b1f0975 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Tue, 8 Jun 2021 14:22:04 -0700
+Subject: [PATCH] net: dsa: b53: Do not force CPU to be always tagged
+
+Commit ca8931948344 ("net: dsa: b53: Keep CPU port as tagged in all
+VLANs") forced the CPU port to be always tagged in any VLAN membership.
+This was necessary back then because we did not support Broadcom tags
+for all configurations so the only way to differentiate tagged and
+untagged traffic while DSA_TAG_PROTO_NONE was used was to force the CPU
+port into being always tagged.
+
+With most configurations enabling Broadcom tags, especially after
+8fab459e69ab ("net: dsa: b53: Enable Broadcom tags for 531x5/539x
+families") we do not need to apply this unconditional force tagging of
+the CPU port in all VLANs.
+
+A helper function is introduced to faciliate the encapsulation of the
+specific condition requiring the CPU port to be tagged in all VLANs and
+the dsa_switch_ops::untag_bridge_pvid boolean is moved to when
+dsa_switch_ops::setup is called when we have already determined the
+tagging protocol we will be using.
+
+Reported-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Tested-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1049,6 +1049,11 @@ static int b53_setup(struct dsa_switch *
+       unsigned int port;
+       int ret;
++      /* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set
++       * which forces the CPU port to be tagged in all VLANs.
++       */
++      ds->untag_bridge_pvid = dev->tag_protocol == DSA_TAG_PROTO_NONE;
++
+       ret = b53_reset_switch(dev);
+       if (ret) {
+               dev_err(ds->dev, "failed to reset switch\n");
+@@ -1423,6 +1428,13 @@ int b53_vlan_prepare(struct dsa_switch *
+       return 0;
+ }
+ EXPORT_SYMBOL(b53_vlan_prepare);
++ 
++static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
++{
++      struct b53_device *dev = ds->priv;
++
++      return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
++}
+ void b53_vlan_add(struct dsa_switch *ds, int port,
+                 const struct switchdev_obj_port_vlan *vlan)
+@@ -1442,7 +1454,7 @@ void b53_vlan_add(struct dsa_switch *ds,
+                       untagged = true;
+               vl->members |= BIT(port);
+-              if (untagged && !dsa_is_cpu_port(ds, port))
++              if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
+                       vl->untag |= BIT(port);
+               else
+                       vl->untag &= ~BIT(port);
+@@ -1480,7 +1492,7 @@ int b53_vlan_del(struct dsa_switch *ds,
+               if (pvid == vid)
+                       pvid = b53_default_pvid(dev);
+-              if (untagged && !dsa_is_cpu_port(ds, port))
++              if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
+                       vl->untag &= ~(BIT(port));
+               b53_set_vlan_entry(dev, vid, vl);
+@@ -2644,7 +2656,6 @@ struct b53_device *b53_switch_alloc(stru
+       dev->ops = ops;
+       ds->ops = &b53_switch_ops;
+       ds->configure_vlan_while_not_filtering = true;
+-      ds->untag_bridge_pvid = true;
+       dev->vlan_enabled = ds->configure_vlan_while_not_filtering;
+       /* Let DSA handle the case were multiple bridges span the same switch
+        * device and different VLAN awareness settings are requested, which
diff --git a/target/linux/generic/backport-5.10/741-v5.14-0002-net-dsa-b53-remove-redundant-null-check-on-dev.patch b/target/linux/generic/backport-5.10/741-v5.14-0002-net-dsa-b53-remove-redundant-null-check-on-dev.patch
new file mode 100644 (file)
index 0000000..ee3a71f
--- /dev/null
@@ -0,0 +1,30 @@
+From 11b57faf951cd3a570e3d9e463fc7c41023bc8c6 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 15 Jun 2021 10:05:16 +0100
+Subject: [PATCH] net: dsa: b53: remove redundant null check on dev
+
+The pointer dev can never be null, the null check is redundant
+and can be removed. Cleans up a static analysis warning that
+pointer priv is dereferencing dev before dev is being null
+checked.
+
+Addresses-Coverity: ("Dereference before null check")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_srab.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_srab.c
++++ b/drivers/net/dsa/b53/b53_srab.c
+@@ -632,8 +632,7 @@ static int b53_srab_remove(struct platfo
+       struct b53_srab_priv *priv = dev->priv;
+       b53_srab_intr_set(priv, false);
+-      if (dev)
+-              b53_switch_remove(dev);
++      b53_switch_remove(dev);
+       return 0;
+ }
diff --git a/target/linux/generic/backport-5.10/741-v5.14-0003-net-dsa-b53-Create-default-VLAN-entry-explicitly.patch b/target/linux/generic/backport-5.10/741-v5.14-0003-net-dsa-b53-Create-default-VLAN-entry-explicitly.patch
new file mode 100644 (file)
index 0000000..df891d6
--- /dev/null
@@ -0,0 +1,71 @@
+From 64a81b24487f0d2fba0f033029eec2abc7d82cee Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 21 Jun 2021 15:10:55 -0700
+Subject: [PATCH] net: dsa: b53: Create default VLAN entry explicitly
+
+In case CONFIG_VLAN_8021Q is not set, there will be no call down to the
+b53 driver to ensure that the default PVID VLAN entry will be configured
+with the appropriate untagged attribute towards the CPU port. We were
+implicitly relying on dsa_slave_vlan_rx_add_vid() to do that for us,
+instead make it explicit.
+
+Reported-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/b53/b53_common.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -693,6 +693,13 @@ static u16 b53_default_pvid(struct b53_d
+               return 0;
+ }
++static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
++{
++      struct b53_device *dev = ds->priv;
++
++      return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
++}
++
+ int b53_configure_vlan(struct dsa_switch *ds)
+ {
+       struct b53_device *dev = ds->priv;
+@@ -713,9 +720,20 @@ int b53_configure_vlan(struct dsa_switch
+       b53_enable_vlan(dev, -1, dev->vlan_enabled, ds->vlan_filtering);
+-      b53_for_each_port(dev, i)
++      /* Create an untagged VLAN entry for the default PVID in case
++       * CONFIG_VLAN_8021Q is disabled and there are no calls to
++       * dsa_slave_vlan_rx_add_vid() to create the default VLAN
++       * entry. Do this only when the tagging protocol is not
++       * DSA_TAG_PROTO_NONE
++       */
++      b53_for_each_port(dev, i) {
++              v = &dev->vlans[def_vid];
++              v->members |= BIT(i);
++              if (!b53_vlan_port_needs_forced_tagged(ds, i))
++                      v->untag = v->members;
+               b53_write16(dev, B53_VLAN_PAGE,
+                           B53_VLAN_PORT_DEF_TAG(i), def_vid);
++      }
+       /* Upon initial call we have not set-up any VLANs, but upon
+        * system resume, we need to restore all VLAN entries.
+@@ -1429,13 +1447,6 @@ int b53_vlan_prepare(struct dsa_switch *
+ }
+ EXPORT_SYMBOL(b53_vlan_prepare);
+  
+-static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
+-{
+-      struct b53_device *dev = ds->priv;
+-
+-      return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
+-}
+-
+ void b53_vlan_add(struct dsa_switch *ds, int port,
+                 const struct switchdev_obj_port_vlan *vlan)
+ {
diff --git a/target/linux/generic/backport-5.10/742-v5.13-net-phy-marvell-refactor-HWMON-OOP-style.patch b/target/linux/generic/backport-5.10/742-v5.13-net-phy-marvell-refactor-HWMON-OOP-style.patch
deleted file mode 100644 (file)
index 7bf5926..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-From 41d26bf4aba070dfd2ab48866cc27a48ee6228c7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
-Date: Tue, 20 Apr 2021 09:53:59 +0200
-Subject: [PATCH] net: phy: marvell: refactor HWMON OOP style
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use a structure of Marvell PHY specific HWMON methods to reduce code
-duplication. Store a pointer to this structure into the PHY driver's
-driver_data member.
-
-Signed-off-by: Marek Behún <kabel@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/marvell.c | 369 +++++++++++++-------------------------
- 1 file changed, 125 insertions(+), 244 deletions(-)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -2134,6 +2134,19 @@ static int marvell_vct7_cable_test_get_s
- }
- #ifdef CONFIG_HWMON
-+struct marvell_hwmon_ops {
-+      int (*get_temp)(struct phy_device *phydev, long *temp);
-+      int (*get_temp_critical)(struct phy_device *phydev, long *temp);
-+      int (*set_temp_critical)(struct phy_device *phydev, long temp);
-+      int (*get_temp_alarm)(struct phy_device *phydev, long *alarm);
-+};
-+
-+static const struct marvell_hwmon_ops *
-+to_marvell_hwmon_ops(const struct phy_device *phydev)
-+{
-+      return phydev->drv->driver_data;
-+}
-+
- static int m88e1121_get_temp(struct phy_device *phydev, long *temp)
- {
-       int oldpage;
-@@ -2177,75 +2190,6 @@ error:
-       return phy_restore_page(phydev, oldpage, ret);
- }
--static int m88e1121_hwmon_read(struct device *dev,
--                             enum hwmon_sensor_types type,
--                             u32 attr, int channel, long *temp)
--{
--      struct phy_device *phydev = dev_get_drvdata(dev);
--      int err;
--
--      switch (attr) {
--      case hwmon_temp_input:
--              err = m88e1121_get_temp(phydev, temp);
--              break;
--      default:
--              return -EOPNOTSUPP;
--      }
--
--      return err;
--}
--
--static umode_t m88e1121_hwmon_is_visible(const void *data,
--                                       enum hwmon_sensor_types type,
--                                       u32 attr, int channel)
--{
--      if (type != hwmon_temp)
--              return 0;
--
--      switch (attr) {
--      case hwmon_temp_input:
--              return 0444;
--      default:
--              return 0;
--      }
--}
--
--static u32 m88e1121_hwmon_chip_config[] = {
--      HWMON_C_REGISTER_TZ,
--      0
--};
--
--static const struct hwmon_channel_info m88e1121_hwmon_chip = {
--      .type = hwmon_chip,
--      .config = m88e1121_hwmon_chip_config,
--};
--
--static u32 m88e1121_hwmon_temp_config[] = {
--      HWMON_T_INPUT,
--      0
--};
--
--static const struct hwmon_channel_info m88e1121_hwmon_temp = {
--      .type = hwmon_temp,
--      .config = m88e1121_hwmon_temp_config,
--};
--
--static const struct hwmon_channel_info *m88e1121_hwmon_info[] = {
--      &m88e1121_hwmon_chip,
--      &m88e1121_hwmon_temp,
--      NULL
--};
--
--static const struct hwmon_ops m88e1121_hwmon_hwmon_ops = {
--      .is_visible = m88e1121_hwmon_is_visible,
--      .read = m88e1121_hwmon_read,
--};
--
--static const struct hwmon_chip_info m88e1121_hwmon_chip_info = {
--      .ops = &m88e1121_hwmon_hwmon_ops,
--      .info = m88e1121_hwmon_info,
--};
--
- static int m88e1510_get_temp(struct phy_device *phydev, long *temp)
- {
-       int ret;
-@@ -2308,92 +2252,6 @@ static int m88e1510_get_temp_alarm(struc
-       return 0;
- }
--static int m88e1510_hwmon_read(struct device *dev,
--                             enum hwmon_sensor_types type,
--                             u32 attr, int channel, long *temp)
--{
--      struct phy_device *phydev = dev_get_drvdata(dev);
--      int err;
--
--      switch (attr) {
--      case hwmon_temp_input:
--              err = m88e1510_get_temp(phydev, temp);
--              break;
--      case hwmon_temp_crit:
--              err = m88e1510_get_temp_critical(phydev, temp);
--              break;
--      case hwmon_temp_max_alarm:
--              err = m88e1510_get_temp_alarm(phydev, temp);
--              break;
--      default:
--              return -EOPNOTSUPP;
--      }
--
--      return err;
--}
--
--static int m88e1510_hwmon_write(struct device *dev,
--                              enum hwmon_sensor_types type,
--                              u32 attr, int channel, long temp)
--{
--      struct phy_device *phydev = dev_get_drvdata(dev);
--      int err;
--
--      switch (attr) {
--      case hwmon_temp_crit:
--              err = m88e1510_set_temp_critical(phydev, temp);
--              break;
--      default:
--              return -EOPNOTSUPP;
--      }
--      return err;
--}
--
--static umode_t m88e1510_hwmon_is_visible(const void *data,
--                                       enum hwmon_sensor_types type,
--                                       u32 attr, int channel)
--{
--      if (type != hwmon_temp)
--              return 0;
--
--      switch (attr) {
--      case hwmon_temp_input:
--      case hwmon_temp_max_alarm:
--              return 0444;
--      case hwmon_temp_crit:
--              return 0644;
--      default:
--              return 0;
--      }
--}
--
--static u32 m88e1510_hwmon_temp_config[] = {
--      HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM,
--      0
--};
--
--static const struct hwmon_channel_info m88e1510_hwmon_temp = {
--      .type = hwmon_temp,
--      .config = m88e1510_hwmon_temp_config,
--};
--
--static const struct hwmon_channel_info *m88e1510_hwmon_info[] = {
--      &m88e1121_hwmon_chip,
--      &m88e1510_hwmon_temp,
--      NULL
--};
--
--static const struct hwmon_ops m88e1510_hwmon_hwmon_ops = {
--      .is_visible = m88e1510_hwmon_is_visible,
--      .read = m88e1510_hwmon_read,
--      .write = m88e1510_hwmon_write,
--};
--
--static const struct hwmon_chip_info m88e1510_hwmon_chip_info = {
--      .ops = &m88e1510_hwmon_hwmon_ops,
--      .info = m88e1510_hwmon_info,
--};
--
- static int m88e6390_get_temp(struct phy_device *phydev, long *temp)
- {
-       int sum = 0;
-@@ -2452,63 +2310,112 @@ error:
-       return ret;
- }
--static int m88e6390_hwmon_read(struct device *dev,
--                             enum hwmon_sensor_types type,
--                             u32 attr, int channel, long *temp)
-+static int marvell_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
-+                            u32 attr, int channel, long *temp)
- {
-       struct phy_device *phydev = dev_get_drvdata(dev);
--      int err;
-+      const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
-+      int err = -EOPNOTSUPP;
-       switch (attr) {
-       case hwmon_temp_input:
--              err = m88e6390_get_temp(phydev, temp);
-+              if (ops->get_temp)
-+                      err = ops->get_temp(phydev, temp);
-+              break;
-+      case hwmon_temp_crit:
-+              if (ops->get_temp_critical)
-+                      err = ops->get_temp_critical(phydev, temp);
-+              break;
-+      case hwmon_temp_max_alarm:
-+              if (ops->get_temp_alarm)
-+                      err = ops->get_temp_alarm(phydev, temp);
-+              break;
-+      }
-+
-+      return err;
-+}
-+
-+static int marvell_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
-+                             u32 attr, int channel, long temp)
-+{
-+      struct phy_device *phydev = dev_get_drvdata(dev);
-+      const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
-+      int err = -EOPNOTSUPP;
-+
-+      switch (attr) {
-+      case hwmon_temp_crit:
-+              if (ops->set_temp_critical)
-+                      err = ops->set_temp_critical(phydev, temp);
-               break;
-       default:
--              return -EOPNOTSUPP;
-+              fallthrough;
-       }
-       return err;
- }
--static umode_t m88e6390_hwmon_is_visible(const void *data,
--                                       enum hwmon_sensor_types type,
--                                       u32 attr, int channel)
-+static umode_t marvell_hwmon_is_visible(const void *data,
-+                                      enum hwmon_sensor_types type,
-+                                      u32 attr, int channel)
- {
-+      const struct phy_device *phydev = data;
-+      const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
-+
-       if (type != hwmon_temp)
-               return 0;
-       switch (attr) {
-       case hwmon_temp_input:
--              return 0444;
-+              return ops->get_temp ? 0444 : 0;
-+      case hwmon_temp_max_alarm:
-+              return ops->get_temp_alarm ? 0444 : 0;
-+      case hwmon_temp_crit:
-+              return (ops->get_temp_critical ? 0444 : 0) |
-+                     (ops->set_temp_critical ? 0200 : 0);
-       default:
-               return 0;
-       }
- }
--static u32 m88e6390_hwmon_temp_config[] = {
--      HWMON_T_INPUT,
-+static u32 marvell_hwmon_chip_config[] = {
-+      HWMON_C_REGISTER_TZ,
-       0
- };
--static const struct hwmon_channel_info m88e6390_hwmon_temp = {
-+static const struct hwmon_channel_info marvell_hwmon_chip = {
-+      .type = hwmon_chip,
-+      .config = marvell_hwmon_chip_config,
-+};
-+
-+/* we can define HWMON_T_CRIT and HWMON_T_MAX_ALARM even though these are not
-+ * defined for all PHYs, because the hwmon code checks whether the attributes
-+ * exists via the .is_visible method
-+ */
-+static u32 marvell_hwmon_temp_config[] = {
-+      HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_MAX_ALARM,
-+      0
-+};
-+
-+static const struct hwmon_channel_info marvell_hwmon_temp = {
-       .type = hwmon_temp,
--      .config = m88e6390_hwmon_temp_config,
-+      .config = marvell_hwmon_temp_config,
- };
--static const struct hwmon_channel_info *m88e6390_hwmon_info[] = {
--      &m88e1121_hwmon_chip,
--      &m88e6390_hwmon_temp,
-+static const struct hwmon_channel_info *marvell_hwmon_info[] = {
-+      &marvell_hwmon_chip,
-+      &marvell_hwmon_temp,
-       NULL
- };
--static const struct hwmon_ops m88e6390_hwmon_hwmon_ops = {
--      .is_visible = m88e6390_hwmon_is_visible,
--      .read = m88e6390_hwmon_read,
-+static const struct hwmon_ops marvell_hwmon_hwmon_ops = {
-+      .is_visible = marvell_hwmon_is_visible,
-+      .read = marvell_hwmon_read,
-+      .write = marvell_hwmon_write,
- };
--static const struct hwmon_chip_info m88e6390_hwmon_chip_info = {
--      .ops = &m88e6390_hwmon_hwmon_ops,
--      .info = m88e6390_hwmon_info,
-+static const struct hwmon_chip_info marvell_hwmon_chip_info = {
-+      .ops = &marvell_hwmon_hwmon_ops,
-+      .info = marvell_hwmon_info,
- };
- static int marvell_hwmon_name(struct phy_device *phydev)
-@@ -2531,49 +2438,48 @@ static int marvell_hwmon_name(struct phy
-       return 0;
- }
--static int marvell_hwmon_probe(struct phy_device *phydev,
--                             const struct hwmon_chip_info *chip)
-+static int marvell_hwmon_probe(struct phy_device *phydev)
- {
-+      const struct marvell_hwmon_ops *ops = to_marvell_hwmon_ops(phydev);
-       struct marvell_priv *priv = phydev->priv;
-       struct device *dev = &phydev->mdio.dev;
-       int err;
-+      if (!ops)
-+              return 0;
-+
-       err = marvell_hwmon_name(phydev);
-       if (err)
-               return err;
-       priv->hwmon_dev = devm_hwmon_device_register_with_info(
--              dev, priv->hwmon_name, phydev, chip, NULL);
-+              dev, priv->hwmon_name, phydev, &marvell_hwmon_chip_info, NULL);
-       return PTR_ERR_OR_ZERO(priv->hwmon_dev);
- }
--static int m88e1121_hwmon_probe(struct phy_device *phydev)
--{
--      return marvell_hwmon_probe(phydev, &m88e1121_hwmon_chip_info);
--}
-+static const struct marvell_hwmon_ops m88e1121_hwmon_ops = {
-+      .get_temp = m88e1121_get_temp,
-+};
--static int m88e1510_hwmon_probe(struct phy_device *phydev)
--{
--      return marvell_hwmon_probe(phydev, &m88e1510_hwmon_chip_info);
--}
-+static const struct marvell_hwmon_ops m88e1510_hwmon_ops = {
-+      .get_temp = m88e1510_get_temp,
-+      .get_temp_critical = m88e1510_get_temp_critical,
-+      .set_temp_critical = m88e1510_set_temp_critical,
-+      .get_temp_alarm = m88e1510_get_temp_alarm,
-+};
-+
-+static const struct marvell_hwmon_ops m88e6390_hwmon_ops = {
-+      .get_temp = m88e6390_get_temp,
-+};
-+
-+#define DEF_MARVELL_HWMON_OPS(s) (&(s))
--static int m88e6390_hwmon_probe(struct phy_device *phydev)
--{
--      return marvell_hwmon_probe(phydev, &m88e6390_hwmon_chip_info);
--}
- #else
--static int m88e1121_hwmon_probe(struct phy_device *phydev)
--{
--      return 0;
--}
--static int m88e1510_hwmon_probe(struct phy_device *phydev)
--{
--      return 0;
--}
-+#define DEF_MARVELL_HWMON_OPS(s) NULL
--static int m88e6390_hwmon_probe(struct phy_device *phydev)
-+static int marvell_hwmon_probe(struct phy_device *phydev)
- {
-       return 0;
- }
-@@ -2589,40 +2495,7 @@ static int marvell_probe(struct phy_devi
-       phydev->priv = priv;
--      return 0;
--}
--
--static int m88e1121_probe(struct phy_device *phydev)
--{
--      int err;
--
--      err = marvell_probe(phydev);
--      if (err)
--              return err;
--
--      return m88e1121_hwmon_probe(phydev);
--}
--
--static int m88e1510_probe(struct phy_device *phydev)
--{
--      int err;
--
--      err = marvell_probe(phydev);
--      if (err)
--              return err;
--
--      return m88e1510_hwmon_probe(phydev);
--}
--
--static int m88e6390_probe(struct phy_device *phydev)
--{
--      int err;
--
--      err = marvell_probe(phydev);
--      if (err)
--              return err;
--
--      return m88e6390_hwmon_probe(phydev);
-+      return marvell_hwmon_probe(phydev);
- }
- static struct phy_driver marvell_drivers[] = {
-@@ -2707,8 +2580,9 @@ static struct phy_driver marvell_drivers
-               .phy_id = MARVELL_PHY_ID_88E1121R,
-               .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88E1121R",
-+              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1121_hwmon_ops),
-               /* PHY_GBIT_FEATURES */
--              .probe = m88e1121_probe,
-+              .probe = marvell_probe,
-               .config_init = marvell_config_init,
-               .config_aneg = m88e1121_config_aneg,
-               .read_status = marvell_read_status,
-@@ -2827,9 +2701,10 @@ static struct phy_driver marvell_drivers
-               .phy_id = MARVELL_PHY_ID_88E1510,
-               .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88E1510",
-+              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
-               .features = PHY_GBIT_FIBRE_FEATURES,
-               .flags = PHY_POLL_CABLE_TEST,
--              .probe = m88e1510_probe,
-+              .probe = marvell_probe,
-               .config_init = m88e1510_config_init,
-               .config_aneg = m88e1510_config_aneg,
-               .read_status = marvell_read_status,
-@@ -2856,9 +2731,10 @@ static struct phy_driver marvell_drivers
-               .phy_id = MARVELL_PHY_ID_88E1540,
-               .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88E1540",
-+              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
-               /* PHY_GBIT_FEATURES */
-               .flags = PHY_POLL_CABLE_TEST,
--              .probe = m88e1510_probe,
-+              .probe = marvell_probe,
-               .config_init = marvell_config_init,
-               .config_aneg = m88e1510_config_aneg,
-               .read_status = marvell_read_status,
-@@ -2882,7 +2758,8 @@ static struct phy_driver marvell_drivers
-               .phy_id = MARVELL_PHY_ID_88E1545,
-               .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88E1545",
--              .probe = m88e1510_probe,
-+              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
-+              .probe = marvell_probe,
-               /* PHY_GBIT_FEATURES */
-               .flags = PHY_POLL_CABLE_TEST,
-               .config_init = marvell_config_init,
-@@ -2928,9 +2805,10 @@ static struct phy_driver marvell_drivers
-               .phy_id = MARVELL_PHY_ID_88E6341_FAMILY,
-               .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88E6341 Family",
-+              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
-               /* PHY_GBIT_FEATURES */
-               .flags = PHY_POLL_CABLE_TEST,
--              .probe = m88e1510_probe,
-+              .probe = marvell_probe,
-               .config_init = marvell_config_init,
-               .config_aneg = m88e6390_config_aneg,
-               .read_status = marvell_read_status,
-@@ -2954,9 +2832,10 @@ static struct phy_driver marvell_drivers
-               .phy_id = MARVELL_PHY_ID_88E6390_FAMILY,
-               .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88E6390 Family",
-+              .driver_data = DEF_MARVELL_HWMON_OPS(m88e6390_hwmon_ops),
-               /* PHY_GBIT_FEATURES */
-               .flags = PHY_POLL_CABLE_TEST,
--              .probe = m88e6390_probe,
-+              .probe = marvell_probe,
-               .config_init = marvell_config_init,
-               .config_aneg = m88e6390_config_aneg,
-               .read_status = marvell_read_status,
-@@ -2980,7 +2859,8 @@ static struct phy_driver marvell_drivers
-               .phy_id = MARVELL_PHY_ID_88E1340S,
-               .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88E1340S",
--              .probe = m88e1510_probe,
-+              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
-+              .probe = marvell_probe,
-               /* PHY_GBIT_FEATURES */
-               .config_init = marvell_config_init,
-               .config_aneg = m88e1510_config_aneg,
-@@ -3002,7 +2882,8 @@ static struct phy_driver marvell_drivers
-               .phy_id = MARVELL_PHY_ID_88E1548P,
-               .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88E1548P",
--              .probe = m88e1510_probe,
-+              .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
-+              .probe = marvell_probe,
-               .features = PHY_GBIT_FIBRE_FEATURES,
-               .config_init = marvell_config_init,
-               .config_aneg = m88e1510_config_aneg,
diff --git a/target/linux/generic/backport-5.10/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch b/target/linux/generic/backport-5.10/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch
new file mode 100644 (file)
index 0000000..16aa071
--- /dev/null
@@ -0,0 +1,48 @@
+From 0ccf8511182436183c031e8a2f740ae91a02c625 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Tue, 14 Sep 2021 14:33:45 +0200
+Subject: net: phy: at803x: add support for qca 8327 internal phy
+
+Add support for qca8327 internal phy needed for correct init of the
+switch port. It does use the same qca8337 function and reg just with a
+different id.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Tested-by: Rosen Penev <rosenp@gmail.com>
+Tested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -1328,6 +1328,19 @@ static struct phy_driver at803x_driver[]
+       .get_sset_count = at803x_get_sset_count,
+       .get_strings = at803x_get_strings,
+       .get_stats = at803x_get_stats,
++}, {
++      /* QCA8327 */
++      .phy_id = QCA8327_PHY_ID,
++      .phy_id_mask = QCA8K_PHY_ID_MASK,
++      .name = "QCA PHY 8327",
++      /* PHY_GBIT_FEATURES */
++      .probe = at803x_probe,
++      .flags = PHY_IS_INTERNAL,
++      .config_init = qca83xx_config_init,
++      .soft_reset = genphy_soft_reset,
++      .get_sset_count = at803x_get_sset_count,
++      .get_strings = at803x_get_strings,
++      .get_stats = at803x_get_stats,
+ }, };
+ module_phy_driver(at803x_driver);
+@@ -1338,6 +1351,8 @@ static struct mdio_device_id __maybe_unu
+       { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
+       { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
+       { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
++      { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
++      { PHY_ID_MATCH_EXACT(QCA8327_PHY_ID) },
+       { }
+ };
diff --git a/target/linux/generic/backport-5.10/743-v5.15-net-phy-marvell-add-SFP-support-for-88E1510.patch b/target/linux/generic/backport-5.10/743-v5.15-net-phy-marvell-add-SFP-support-for-88E1510.patch
deleted file mode 100644 (file)
index 7fb7808..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-From b697d9d38a5a5ab405d7cc4743d39fe2c5d7517c Mon Sep 17 00:00:00 2001
-From: Ivan Bornyakov <i.bornyakov@metrotek.ru>
-Date: Thu, 12 Aug 2021 16:42:56 +0300
-Subject: [PATCH] net: phy: marvell: add SFP support for 88E1510
-
-Add support for SFP cages connected to the Marvell 88E1512 transceiver.
-88E1512 supports for SGMII/1000Base-X/100Base-FX media type with RGMII
-on system interface. Configure PHY to appropriate mode depending on the
-type of SFP inserted. On SFP removal configure PHY to the RGMII-copper
-mode so RJ-45 port can still work.
-
-Signed-off-by: Ivan Bornyakov <i.bornyakov@metrotek.ru>
-Link: https://lore.kernel.org/r/20210812134256.2436-1-i.bornyakov@metrotek.ru
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/marvell.c | 105 +++++++++++++++++++++++++++++++++++++-
- 1 file changed, 104 insertions(+), 1 deletion(-)
-
---- a/drivers/net/phy/marvell.c
-+++ b/drivers/net/phy/marvell.c
-@@ -32,6 +32,7 @@
- #include <linux/marvell_phy.h>
- #include <linux/bitfield.h>
- #include <linux/of.h>
-+#include <linux/sfp.h>
- #include <linux/io.h>
- #include <asm/irq.h>
-@@ -46,6 +47,7 @@
- #define MII_MARVELL_MISC_TEST_PAGE    0x06
- #define MII_MARVELL_VCT7_PAGE         0x07
- #define MII_MARVELL_WOL_PAGE          0x11
-+#define MII_MARVELL_MODE_PAGE         0x12
- #define MII_M1011_IEVENT              0x13
- #define MII_M1011_IEVENT_CLEAR                0x0000
-@@ -162,7 +164,14 @@
- #define MII_88E1510_GEN_CTRL_REG_1            0x14
- #define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK  0x7
-+#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII 0x0     /* RGMII to copper */
- #define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1     /* SGMII to copper */
-+/* RGMII to 1000BASE-X */
-+#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X   0x2
-+/* RGMII to 100BASE-FX */
-+#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX   0x3
-+/* RGMII to SGMII */
-+#define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII   0x4
- #define MII_88E1510_GEN_CTRL_REG_1_RESET      0x8000  /* Soft reset */
- #define MII_VCT5_TX_RX_MDI0_COUPLING  0x10
-@@ -2498,6 +2507,100 @@ static int marvell_probe(struct phy_devi
-       return marvell_hwmon_probe(phydev);
- }
-+static int m88e1510_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-+{
-+      struct phy_device *phydev = upstream;
-+      phy_interface_t interface;
-+      struct device *dev;
-+      int oldpage;
-+      int ret = 0;
-+      u16 mode;
-+
-+      __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
-+
-+      dev = &phydev->mdio.dev;
-+
-+      sfp_parse_support(phydev->sfp_bus, id, supported);
-+      interface = sfp_select_interface(phydev->sfp_bus, supported);
-+
-+      dev_info(dev, "%s SFP module inserted\n", phy_modes(interface));
-+
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_1000BASEX:
-+              mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_1000X;
-+
-+              break;
-+      case PHY_INTERFACE_MODE_100BASEX:
-+              mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_100FX;
-+
-+              break;
-+      case PHY_INTERFACE_MODE_SGMII:
-+              mode = MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII;
-+
-+              break;
-+      default:
-+              dev_err(dev, "Incompatible SFP module inserted\n");
-+
-+              return -EINVAL;
-+      }
-+
-+      oldpage = phy_select_page(phydev, MII_MARVELL_MODE_PAGE);
-+      if (oldpage < 0)
-+              goto error;
-+
-+      ret = __phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
-+                         MII_88E1510_GEN_CTRL_REG_1_MODE_MASK, mode);
-+      if (ret < 0)
-+              goto error;
-+
-+      ret = __phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
-+                           MII_88E1510_GEN_CTRL_REG_1_RESET);
-+
-+error:
-+      return phy_restore_page(phydev, oldpage, ret);
-+}
-+
-+static void m88e1510_sfp_remove(void *upstream)
-+{
-+      struct phy_device *phydev = upstream;
-+      int oldpage;
-+      int ret = 0;
-+
-+      oldpage = phy_select_page(phydev, MII_MARVELL_MODE_PAGE);
-+      if (oldpage < 0)
-+              goto error;
-+
-+      ret = __phy_modify(phydev, MII_88E1510_GEN_CTRL_REG_1,
-+                         MII_88E1510_GEN_CTRL_REG_1_MODE_MASK,
-+                         MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII);
-+      if (ret < 0)
-+              goto error;
-+
-+      ret = __phy_set_bits(phydev, MII_88E1510_GEN_CTRL_REG_1,
-+                           MII_88E1510_GEN_CTRL_REG_1_RESET);
-+
-+error:
-+      phy_restore_page(phydev, oldpage, ret);
-+}
-+
-+static const struct sfp_upstream_ops m88e1510_sfp_ops = {
-+      .module_insert = m88e1510_sfp_insert,
-+      .module_remove = m88e1510_sfp_remove,
-+      .attach = phy_sfp_attach,
-+      .detach = phy_sfp_detach,
-+};
-+
-+static int m88e1510_probe(struct phy_device *phydev)
-+{
-+      int err;
-+
-+      err = marvell_probe(phydev);
-+      if (err)
-+              return err;
-+
-+      return phy_sfp_probe(phydev, &m88e1510_sfp_ops);
-+}
-+
- static struct phy_driver marvell_drivers[] = {
-       {
-               .phy_id = MARVELL_PHY_ID_88E1101,
-@@ -2704,7 +2807,7 @@ static struct phy_driver marvell_drivers
-               .driver_data = DEF_MARVELL_HWMON_OPS(m88e1510_hwmon_ops),
-               .features = PHY_GBIT_FIBRE_FEATURES,
-               .flags = PHY_POLL_CABLE_TEST,
--              .probe = marvell_probe,
-+              .probe = m88e1510_probe,
-               .config_init = m88e1510_config_init,
-               .config_aneg = m88e1510_config_aneg,
-               .read_status = marvell_read_status,
diff --git a/target/linux/generic/backport-5.10/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch b/target/linux/generic/backport-5.10/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch
new file mode 100644 (file)
index 0000000..d80b5db
--- /dev/null
@@ -0,0 +1,131 @@
+From 983d96a9116a328668601555d96736261d33170c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 16 Sep 2021 14:03:51 +0200
+Subject: [PATCH] net: dsa: b53: Include all ports in "enabled_ports"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Make "enabled_ports" bitfield contain all available switch ports
+including a CPU port. This way there is no need for fixup during
+initialization.
+
+For BCM53010, BCM53018 and BCM53019 include also other available ports.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Tested-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2288,7 +2288,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM5325_DEVICE_ID,
+               .dev_name = "BCM5325",
+               .vlans = 16,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x3f,
+               .arl_bins = 2,
+               .arl_buckets = 1024,
+               .imp_port = 5,
+@@ -2299,7 +2299,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM5365_DEVICE_ID,
+               .dev_name = "BCM5365",
+               .vlans = 256,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x3f,
+               .arl_bins = 2,
+               .arl_buckets = 1024,
+               .imp_port = 5,
+@@ -2310,7 +2310,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM5389_DEVICE_ID,
+               .dev_name = "BCM5389",
+               .vlans = 4096,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x11f,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+@@ -2324,7 +2324,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM5395_DEVICE_ID,
+               .dev_name = "BCM5395",
+               .vlans = 4096,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x11f,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+@@ -2338,7 +2338,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM5397_DEVICE_ID,
+               .dev_name = "BCM5397",
+               .vlans = 4096,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x11f,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+@@ -2352,7 +2352,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM5398_DEVICE_ID,
+               .dev_name = "BCM5398",
+               .vlans = 4096,
+-              .enabled_ports = 0x7f,
++              .enabled_ports = 0x17f,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+@@ -2366,7 +2366,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM53115_DEVICE_ID,
+               .dev_name = "BCM53115",
+               .vlans = 4096,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x11f,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .vta_regs = B53_VTA_REGS,
+@@ -2380,7 +2380,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM53125_DEVICE_ID,
+               .dev_name = "BCM53125",
+               .vlans = 4096,
+-              .enabled_ports = 0xff,
++              .enabled_ports = 0x1ff,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+@@ -2422,7 +2422,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM53010_DEVICE_ID,
+               .dev_name = "BCM53010",
+               .vlans = 4096,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x1bf,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+@@ -2464,7 +2464,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM53018_DEVICE_ID,
+               .dev_name = "BCM53018",
+               .vlans = 4096,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x1bf,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+@@ -2478,7 +2478,7 @@ static const struct b53_chip_data b53_sw
+               .chip_id = BCM53019_DEVICE_ID,
+               .dev_name = "BCM53019",
+               .vlans = 4096,
+-              .enabled_ports = 0x1f,
++              .enabled_ports = 0x1bf,
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+@@ -2605,7 +2605,6 @@ static int b53_switch_init(struct b53_de
+                       dev->cpu_port = 5;
+       }
+-      dev->enabled_ports |= BIT(dev->cpu_port);
+       dev->num_ports = fls(dev->enabled_ports);
+       dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS);
diff --git a/target/linux/generic/backport-5.10/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch b/target/linux/generic/backport-5.10/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch
new file mode 100644 (file)
index 0000000..4a4f8e9
--- /dev/null
@@ -0,0 +1,42 @@
+From b290c6384afabbca5ae6e2af72fb1b2bc37922be Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 16 Sep 2021 14:03:52 +0200
+Subject: [PATCH] net: dsa: b53: Drop BCM5301x workaround for a wrong CPU/IMP
+ port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+On BCM5301x port 8 requires a fixed link when used.
+
+Years ago when b53 was an OpenWrt downstream driver (with configuration
+based on sometimes bugged NVRAM) there was a need for a fixup. In case
+of forcing fixed link for (incorrectly specified) port 5 the code had to
+actually setup port 8 link.
+
+For upstream b53 driver with setup based on DT there is no need for that
+workaround. In DT we have and require correct ports setup.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Tested-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1256,12 +1256,6 @@ static void b53_adjust_link(struct dsa_s
+                               return;
+                       }
+               }
+-      } else if (is5301x(dev)) {
+-              if (port != dev->cpu_port) {
+-                      b53_force_port_config(dev, dev->cpu_port, 2000,
+-                                            DUPLEX_FULL, true, true);
+-                      b53_force_link(dev, dev->cpu_port, 1);
+-              }
+       }
+       /* Re-negotiate EEE if it was enabled already */
diff --git a/target/linux/generic/backport-5.10/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch b/target/linux/generic/backport-5.10/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch
new file mode 100644 (file)
index 0000000..3954ee4
--- /dev/null
@@ -0,0 +1,32 @@
+From 3ff26b29230c54fea2353b63124c589b61953e14 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 16 Sep 2021 14:03:53 +0200
+Subject: [PATCH] net: dsa: b53: Improve flow control setup on BCM5301x
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+According to the Broadcom's reference driver flow control needs to be
+enabled for any CPU switch port (5, 7 or 8 - depending on which one is
+used). Current code makes it work only for the port 5. Use
+dsa_is_cpu_port() which solved that problem.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Tested-by: Florian Fainelli <f.fainelli@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
+@@ -1187,7 +1187,7 @@ static void b53_adjust_link(struct dsa_s
+               return;
+       /* Enable flow control on BCM5301x's CPU port */
+-      if (is5301x(dev) && port == dev->cpu_port)
++      if (is5301x(dev) && dsa_is_cpu_port(ds, port))
+               tx_pause = rx_pause = true;
+       if (phydev->pause) {
diff --git a/target/linux/generic/backport-5.10/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch b/target/linux/generic/backport-5.10/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch
new file mode 100644 (file)
index 0000000..9e687b1
--- /dev/null
@@ -0,0 +1,205 @@
+From 7d5af56418d7d01e43247a33b6fe6492ea871923 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 16 Sep 2021 14:03:54 +0200
+Subject: [PATCH] net: dsa: b53: Drop unused "cpu_port" field
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It's set but never used anymore.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Tested-by: Florian Fainelli <f.fainelli@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 -
+ 2 files changed, 29 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2286,7 +2286,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 2,
+               .arl_buckets = 1024,
+               .imp_port = 5,
+-              .cpu_port = B53_CPU_PORT_25,
+               .duplex_reg = B53_DUPLEX_STAT_FE,
+       },
+       {
+@@ -2297,7 +2296,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 2,
+               .arl_buckets = 1024,
+               .imp_port = 5,
+-              .cpu_port = B53_CPU_PORT_25,
+               .duplex_reg = B53_DUPLEX_STAT_FE,
+       },
+       {
+@@ -2308,7 +2306,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2322,7 +2319,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2336,7 +2332,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS_9798,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2350,7 +2345,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS_9798,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2365,7 +2359,6 @@ static const struct b53_chip_data b53_sw
+               .arl_buckets = 1024,
+               .vta_regs = B53_VTA_REGS,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+@@ -2378,7 +2371,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2392,7 +2384,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2406,7 +2397,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS_63XX,
+               .duplex_reg = B53_DUPLEX_STAT_63XX,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
+@@ -2420,7 +2410,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2434,7 +2423,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2448,7 +2436,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2462,7 +2449,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2476,7 +2462,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2490,7 +2475,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2504,7 +2488,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2518,7 +2501,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 1024,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2532,7 +2514,6 @@ static const struct b53_chip_data b53_sw
+               .arl_bins = 4,
+               .arl_buckets = 256,
+               .imp_port = 8,
+-              .cpu_port = B53_CPU_PORT,
+               .vta_regs = B53_VTA_REGS,
+               .duplex_reg = B53_DUPLEX_STAT_GE,
+               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+@@ -2558,7 +2539,6 @@ static int b53_switch_init(struct b53_de
+                       dev->vta_regs[2] = chip->vta_regs[2];
+                       dev->jumbo_pm_reg = chip->jumbo_pm_reg;
+                       dev->imp_port = chip->imp_port;
+-                      dev->cpu_port = chip->cpu_port;
+                       dev->num_vlans = chip->vlans;
+                       dev->num_arl_bins = chip->arl_bins;
+                       dev->num_arl_buckets = chip->arl_buckets;
+@@ -2590,13 +2570,6 @@ static int b53_switch_init(struct b53_de
+                       break;
+ #endif
+               }
+-      } else if (dev->chip_id == BCM53115_DEVICE_ID) {
+-              u64 strap_value;
+-
+-              b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value);
+-              /* use second IMP port if GMII is enabled */
+-              if (strap_value & SV_GMII_CTRL_115)
+-                      dev->cpu_port = 5;
+       }
+       dev->num_ports = fls(dev->enabled_ports);
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -123,7 +123,6 @@ struct b53_device {
+       /* used ports mask */
+       u16 enabled_ports;
+       unsigned int imp_port;
+-      unsigned int cpu_port;
+       /* connect specific data */
+       u8 current_page;
diff --git a/target/linux/generic/backport-5.10/744-v5.15-net-dsa-don-t-set-skb-offload_fwd_mark-when-not-offl.patch b/target/linux/generic/backport-5.10/744-v5.15-net-dsa-don-t-set-skb-offload_fwd_mark-when-not-offl.patch
new file mode 100644 (file)
index 0000000..ab4fdf8
--- /dev/null
@@ -0,0 +1,138 @@
+From bea7907837c57a0aaac009931eb14efb056dafab Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Thu, 29 Jul 2021 17:56:00 +0300
+Subject: [PATCH] net: dsa: don't set skb->offload_fwd_mark when not offloading
+ the bridge
+
+DSA has gained the recent ability to deal gracefully with upper
+interfaces it cannot offload, such as the bridge, bonding or team
+drivers. When such uppers exist, the ports are still in standalone mode
+as far as the hardware is concerned.
+
+But when we deliver packets to the software bridge in order for that to
+do the forwarding, there is an unpleasant surprise in that the bridge
+will refuse to forward them. This is because we unconditionally set
+skb->offload_fwd_mark = true, meaning that the bridge thinks the frames
+were already forwarded in hardware by us.
+
+Since dp->bridge_dev is populated only when there is hardware offload
+for it, but not in the software fallback case, let's introduce a new
+helper that can be called from the tagger data path which sets the
+skb->offload_fwd_mark accordingly to zero when there is no hardware
+offload for bridging. This lets the bridge forward packets back to other
+interfaces of our switch, if needed.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Tobias Waldekranz <tobias@waldekranz.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/dsa/dsa_priv.h         | 14 ++++++++++++++
+ net/dsa/tag_brcm.c         |  4 ++--
+ net/dsa/tag_dsa.c          | 15 +++++++++++----
+ net/dsa/tag_ksz.c          |  2 +-
+ net/dsa/tag_lan9303.c      |  3 ++-
+ net/dsa/tag_mtk.c          |  2 +-
+ net/dsa/tag_ocelot.c       |  2 +-
+ net/dsa/tag_rtl4_a.c       |  2 +-
+ net/dsa/tag_sja1105.c      | 20 ++++++++++++++------
+ 9 files changed, 47 insertions(+), 17 deletions(-)
+
+--- a/net/dsa/dsa_priv.h
++++ b/net/dsa/dsa_priv.h
+@@ -266,6 +266,20 @@ static inline struct sk_buff *dsa_untag_
+       return skb;
+ }
++/* If the ingress port offloads the bridge, we mark the frame as autonomously
++ * forwarded by hardware, so the software bridge doesn't forward in twice, back
++ * to us, because we already did. However, if we're in fallback mode and we do
++ * software bridging, we are not offloading it, therefore the dp->bridge_dev
++ * pointer is not populated, and flooding needs to be done by software (we are
++ * effectively operating in standalone ports mode).
++ */
++static inline void dsa_default_offload_fwd_mark(struct sk_buff *skb)
++{
++      struct dsa_port *dp = dsa_slave_to_port(skb->dev);
++
++      skb->offload_fwd_mark = !!(dp->bridge_dev);
++}
++
+ /* switch.c */
+ int dsa_switch_register_notifier(struct dsa_switch *ds);
+ void dsa_switch_unregister_notifier(struct dsa_switch *ds);
+--- a/net/dsa/tag_brcm.c
++++ b/net/dsa/tag_brcm.c
+@@ -166,7 +166,7 @@ static struct sk_buff *brcm_tag_rcv_ll(s
+       /* Remove Broadcom tag and update checksum */
+       skb_pull_rcsum(skb, BRCM_TAG_LEN);
+-      skb->offload_fwd_mark = 1;
++      dsa_default_offload_fwd_mark(skb);
+       return skb;
+ }
+@@ -270,7 +270,7 @@ static struct sk_buff *brcm_leg_tag_rcv(
+       /* Remove Broadcom tag and update checksum */
+       skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
+-      skb->offload_fwd_mark = 1;
++      dsa_default_offload_fwd_mark(skb);
+       /* Move the Ethernet DA and SA */
+       memmove(skb->data - ETH_HLEN,
+--- a/net/dsa/tag_ksz.c
++++ b/net/dsa/tag_ksz.c
+@@ -24,7 +24,7 @@ static struct sk_buff *ksz_common_rcv(st
+       pskb_trim_rcsum(skb, skb->len - len);
+-      skb->offload_fwd_mark = true;
++      dsa_default_offload_fwd_mark(skb);
+       return skb;
+ }
+--- a/net/dsa/tag_lan9303.c
++++ b/net/dsa/tag_lan9303.c
+@@ -115,7 +115,8 @@ static struct sk_buff *lan9303_rcv(struc
+       skb_pull_rcsum(skb, 2 + 2);
+       memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
+               2 * ETH_ALEN);
+-      skb->offload_fwd_mark = !(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU);
++      if (!(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU))
++              dsa_default_offload_fwd_mark(skb);
+       return skb;
+ }
+--- a/net/dsa/tag_mtk.c
++++ b/net/dsa/tag_mtk.c
+@@ -104,7 +104,7 @@ static struct sk_buff *mtk_tag_rcv(struc
+       /* Only unicast or broadcast frames are offloaded */
+       if (likely(!is_multicast_skb))
+-              skb->offload_fwd_mark = 1;
++              dsa_default_offload_fwd_mark(skb);
+       return skb;
+ }
+--- a/net/dsa/tag_ocelot.c
++++ b/net/dsa/tag_ocelot.c
+@@ -225,7 +225,7 @@ static struct sk_buff *ocelot_rcv(struct
+                */
+               return NULL;
+-      skb->offload_fwd_mark = 1;
++      dsa_default_offload_fwd_mark(skb);
+       skb->priority = qos_class;
+       /* Ocelot switches copy frames unmodified to the CPU. However, it is
+--- a/net/dsa/tag_rtl4_a.c
++++ b/net/dsa/tag_rtl4_a.c
+@@ -115,7 +115,7 @@ static struct sk_buff *rtl4a_tag_rcv(str
+               skb->data - ETH_HLEN - RTL4_A_HDR_LEN,
+               2 * ETH_ALEN);
+-      skb->offload_fwd_mark = 1;
++      dsa_default_offload_fwd_mark(skb);
+       return skb;
+ }
diff --git a/target/linux/generic/backport-5.10/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch b/target/linux/generic/backport-5.10/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch
new file mode 100644 (file)
index 0000000..c82bf91
--- /dev/null
@@ -0,0 +1,65 @@
+From b4df02b562f4aa14ff6811f30e1b4d2159585c59 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 19 Sep 2021 18:28:15 +0200
+Subject: net: phy: at803x: add support for qca 8327 A variant internal phy
+
+For qca8327 internal phy there are 2 different switch variant with 2
+different phy id. Add this missing variant so the internal phy can be
+correctly identified and fixed.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -148,7 +148,8 @@
+ #define AT803X_PAGE_FIBER             0
+ #define AT803X_PAGE_COPPER            1
+-#define QCA8327_PHY_ID                                0x004dd034
++#define QCA8327_A_PHY_ID                      0x004dd033
++#define QCA8327_B_PHY_ID                      0x004dd034
+ #define QCA8337_PHY_ID                                0x004dd036
+ #define QCA8K_PHY_ID_MASK                     0xffffffff
+@@ -1329,10 +1330,23 @@ static struct phy_driver at803x_driver[]
+       .get_strings = at803x_get_strings,
+       .get_stats = at803x_get_stats,
+ }, {
+-      /* QCA8327 */
+-      .phy_id = QCA8327_PHY_ID,
++      /* QCA8327-A from switch QCA8327-AL1A */
++      .phy_id = QCA8327_A_PHY_ID,
+       .phy_id_mask = QCA8K_PHY_ID_MASK,
+-      .name = "QCA PHY 8327",
++      .name = "QCA PHY 8327-A",
++      /* PHY_GBIT_FEATURES */
++      .probe = at803x_probe,
++      .flags = PHY_IS_INTERNAL,
++      .config_init = qca83xx_config_init,
++      .soft_reset = genphy_soft_reset,
++      .get_sset_count = at803x_get_sset_count,
++      .get_strings = at803x_get_strings,
++      .get_stats = at803x_get_stats,
++}, {
++      /* QCA8327-B from switch QCA8327-BL1A */
++      .phy_id = QCA8327_B_PHY_ID,
++      .phy_id_mask = QCA8K_PHY_ID_MASK,
++      .name = "QCA PHY 8327-B",
+       /* PHY_GBIT_FEATURES */
+       .probe = at803x_probe,
+       .flags = PHY_IS_INTERNAL,
+@@ -1352,7 +1366,8 @@ static struct mdio_device_id __maybe_unu
+       { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
+       { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
+       { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
+-      { PHY_ID_MATCH_EXACT(QCA8327_PHY_ID) },
++      { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
++      { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
+       { }
+ };
diff --git a/target/linux/generic/backport-5.10/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch b/target/linux/generic/backport-5.10/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch
new file mode 100644 (file)
index 0000000..be24fd5
--- /dev/null
@@ -0,0 +1,45 @@
+From 15b9df4ece17d084f14eb0ca1cf05f2ad497e425 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 19 Sep 2021 18:28:16 +0200
+Subject: net: phy: at803x: add resume/suspend function to qca83xx phy
+
+Add resume/suspend function to qca83xx internal phy.
+We can't use the at803x generic function as the documentation lacks of
+any support for WoL regs.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -1329,6 +1329,8 @@ static struct phy_driver at803x_driver[]
+       .get_sset_count = at803x_get_sset_count,
+       .get_strings = at803x_get_strings,
+       .get_stats = at803x_get_stats,
++      .suspend                = genphy_suspend,
++      .resume                 = genphy_resume,
+ }, {
+       /* QCA8327-A from switch QCA8327-AL1A */
+       .phy_id = QCA8327_A_PHY_ID,
+@@ -1342,6 +1344,8 @@ static struct phy_driver at803x_driver[]
+       .get_sset_count = at803x_get_sset_count,
+       .get_strings = at803x_get_strings,
+       .get_stats = at803x_get_stats,
++      .suspend                = genphy_suspend,
++      .resume                 = genphy_resume,
+ }, {
+       /* QCA8327-B from switch QCA8327-BL1A */
+       .phy_id = QCA8327_B_PHY_ID,
+@@ -1355,6 +1359,8 @@ static struct phy_driver at803x_driver[]
+       .get_sset_count = at803x_get_sset_count,
+       .get_strings = at803x_get_strings,
+       .get_stats = at803x_get_stats,
++      .suspend                = genphy_suspend,
++      .resume                 = genphy_resume,
+ }, };
+ module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-5.10/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch b/target/linux/generic/backport-5.10/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch
new file mode 100644 (file)
index 0000000..23f574c
--- /dev/null
@@ -0,0 +1,95 @@
+From d44fd8604a4ab92119adb35f05fd87612af722b5 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 19 Sep 2021 18:28:17 +0200
+Subject: net: phy: at803x: fix spacing and improve name for 83xx phy
+
+Fix spacing and improve name for 83xx phy following other phy in the
+same driver.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 60 ++++++++++++++++++++++++------------------------
+ 1 file changed, 30 insertions(+), 30 deletions(-)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -1318,47 +1318,47 @@ static struct phy_driver at803x_driver[]
+       .config_aneg            = at803x_config_aneg,
+ }, {
+       /* QCA8337 */
+-      .phy_id = QCA8337_PHY_ID,
+-      .phy_id_mask = QCA8K_PHY_ID_MASK,
+-      .name = "QCA PHY 8337",
++      .phy_id                 = QCA8337_PHY_ID,
++      .phy_id_mask            = QCA8K_PHY_ID_MASK,
++      .name                   = "Qualcomm Atheros 8337 internal PHY",
+       /* PHY_GBIT_FEATURES */
+-      .probe = at803x_probe,
+-      .flags = PHY_IS_INTERNAL,
+-      .config_init = qca83xx_config_init,
+-      .soft_reset = genphy_soft_reset,
+-      .get_sset_count = at803x_get_sset_count,
+-      .get_strings = at803x_get_strings,
+-      .get_stats = at803x_get_stats,
++      .probe                  = at803x_probe,
++      .flags                  = PHY_IS_INTERNAL,
++      .config_init            = qca83xx_config_init,
++      .soft_reset             = genphy_soft_reset,
++      .get_sset_count         = at803x_get_sset_count,
++      .get_strings            = at803x_get_strings,
++      .get_stats              = at803x_get_stats,
+       .suspend                = genphy_suspend,
+       .resume                 = genphy_resume,
+ }, {
+       /* QCA8327-A from switch QCA8327-AL1A */
+-      .phy_id = QCA8327_A_PHY_ID,
+-      .phy_id_mask = QCA8K_PHY_ID_MASK,
+-      .name = "QCA PHY 8327-A",
++      .phy_id                 = QCA8327_A_PHY_ID,
++      .phy_id_mask            = QCA8K_PHY_ID_MASK,
++      .name                   = "Qualcomm Atheros 8327-A internal PHY",
+       /* PHY_GBIT_FEATURES */
+-      .probe = at803x_probe,
+-      .flags = PHY_IS_INTERNAL,
+-      .config_init = qca83xx_config_init,
+-      .soft_reset = genphy_soft_reset,
+-      .get_sset_count = at803x_get_sset_count,
+-      .get_strings = at803x_get_strings,
+-      .get_stats = at803x_get_stats,
++      .probe                  = at803x_probe,
++      .flags                  = PHY_IS_INTERNAL,
++      .config_init            = qca83xx_config_init,
++      .soft_reset             = genphy_soft_reset,
++      .get_sset_count         = at803x_get_sset_count,
++      .get_strings            = at803x_get_strings,
++      .get_stats              = at803x_get_stats,
+       .suspend                = genphy_suspend,
+       .resume                 = genphy_resume,
+ }, {
+       /* QCA8327-B from switch QCA8327-BL1A */
+-      .phy_id = QCA8327_B_PHY_ID,
+-      .phy_id_mask = QCA8K_PHY_ID_MASK,
+-      .name = "QCA PHY 8327-B",
++      .phy_id                 = QCA8327_B_PHY_ID,
++      .phy_id_mask            = QCA8K_PHY_ID_MASK,
++      .name                   = "Qualcomm Atheros 8327-B internal PHY",
+       /* PHY_GBIT_FEATURES */
+-      .probe = at803x_probe,
+-      .flags = PHY_IS_INTERNAL,
+-      .config_init = qca83xx_config_init,
+-      .soft_reset = genphy_soft_reset,
+-      .get_sset_count = at803x_get_sset_count,
+-      .get_strings = at803x_get_strings,
+-      .get_stats = at803x_get_stats,
++      .probe                  = at803x_probe,
++      .flags                  = PHY_IS_INTERNAL,
++      .config_init            = qca83xx_config_init,
++      .soft_reset             = genphy_soft_reset,
++      .get_sset_count         = at803x_get_sset_count,
++      .get_strings            = at803x_get_strings,
++      .get_stats              = at803x_get_stats,
+       .suspend                = genphy_suspend,
+       .resume                 = genphy_resume,
+ }, };
diff --git a/target/linux/generic/backport-5.10/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch b/target/linux/generic/backport-5.10/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch
new file mode 100644 (file)
index 0000000..5dfe27d
--- /dev/null
@@ -0,0 +1,131 @@
+From ba3c01ee02ed0d821c9f241f179bbc9457542b8f Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 10 Oct 2021 00:46:15 +0200
+Subject: net: phy: at803x: fix resume for QCA8327 phy
+
+From Documentation phy resume triggers phy reset and restart
+auto-negotiation. Add a dedicated function to wait reset to finish as
+it was notice a regression where port sometime are not reliable after a
+suspend/resume session. The reset wait logic is copied from phy_poll_reset.
+Add dedicated suspend function to use genphy_suspend only with QCA8337
+phy and set only additional debug settings for QCA8327. With more test
+it was reported that QCA8327 doesn't proprely support this mode and
+using this cause the unreliability of the switch ports, especially the
+malfunction of the port0.
+
+Fixes: 15b9df4ece17 ("net: phy: at803x: add resume/suspend function to qca83xx phy")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 69 +++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 63 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -92,9 +92,14 @@
+ #define AT803X_DEBUG_REG_5                    0x05
+ #define AT803X_DEBUG_TX_CLK_DLY_EN            BIT(8)
++#define AT803X_DEBUG_REG_HIB_CTRL             0x0b
++#define   AT803X_DEBUG_HIB_CTRL_SEL_RST_80U   BIT(10)
++#define   AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
++
+ #define AT803X_DEBUG_REG_3C                   0x3C
+ #define AT803X_DEBUG_REG_3D                   0x3D
++#define   AT803X_DEBUG_GATE_CLK_IN1000                BIT(6)
+ #define AT803X_DEBUG_REG_1F                   0x1F
+ #define AT803X_DEBUG_PLL_ON                   BIT(2)
+@@ -1220,6 +1225,58 @@ static int qca83xx_config_init(struct ph
+       return 0;
+ }
++static int qca83xx_resume(struct phy_device *phydev)
++{
++      int ret, val;
++
++      /* Skip reset if not suspended */
++      if (!phydev->suspended)
++              return 0;
++
++      /* Reinit the port, reset values set by suspend */
++      qca83xx_config_init(phydev);
++
++      /* Reset the port on port resume */
++      phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
++
++      /* On resume from suspend the switch execute a reset and
++       * restart auto-negotiation. Wait for reset to complete.
++       */
++      ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
++                                  50000, 600000, true);
++      if (ret)
++              return ret;
++
++      msleep(1);
++
++      return 0;
++}
++
++static int qca83xx_suspend(struct phy_device *phydev)
++{
++      u16 mask = 0;
++
++      /* Only QCA8337 support actual suspend.
++       * QCA8327 cause port unreliability when phy suspend
++       * is set.
++       */
++      if (phydev->drv->phy_id == QCA8337_PHY_ID) {
++              genphy_suspend(phydev);
++      } else {
++              mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
++              phy_modify(phydev, MII_BMCR, mask, 0);
++      }
++
++      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D,
++                            AT803X_DEBUG_GATE_CLK_IN1000, 0);
++
++      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
++                            AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE |
++                            AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0);
++
++      return 0;
++}
++
+ static struct phy_driver at803x_driver[] = {
+ {
+       /* Qualcomm Atheros AR8035 */
+@@ -1329,8 +1386,8 @@ static struct phy_driver at803x_driver[]
+       .get_sset_count         = at803x_get_sset_count,
+       .get_strings            = at803x_get_strings,
+       .get_stats              = at803x_get_stats,
+-      .suspend                = genphy_suspend,
+-      .resume                 = genphy_resume,
++      .suspend                = qca83xx_suspend,
++      .resume                 = qca83xx_resume,
+ }, {
+       /* QCA8327-A from switch QCA8327-AL1A */
+       .phy_id                 = QCA8327_A_PHY_ID,
+@@ -1344,8 +1401,8 @@ static struct phy_driver at803x_driver[]
+       .get_sset_count         = at803x_get_sset_count,
+       .get_strings            = at803x_get_strings,
+       .get_stats              = at803x_get_stats,
+-      .suspend                = genphy_suspend,
+-      .resume                 = genphy_resume,
++      .suspend                = qca83xx_suspend,
++      .resume                 = qca83xx_resume,
+ }, {
+       /* QCA8327-B from switch QCA8327-BL1A */
+       .phy_id                 = QCA8327_B_PHY_ID,
+@@ -1359,8 +1416,8 @@ static struct phy_driver at803x_driver[]
+       .get_sset_count         = at803x_get_sset_count,
+       .get_strings            = at803x_get_strings,
+       .get_stats              = at803x_get_stats,
+-      .suspend                = genphy_suspend,
+-      .resume                 = genphy_resume,
++      .suspend                = qca83xx_suspend,
++      .resume                 = qca83xx_resume,
+ }, };
+ module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-5.10/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch b/target/linux/generic/backport-5.10/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch
new file mode 100644 (file)
index 0000000..aeb43e2
--- /dev/null
@@ -0,0 +1,91 @@
+From 1ca8311949aec5c9447645731ef1c6bc5bd71350 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 10 Oct 2021 00:46:16 +0200
+Subject: net: phy: at803x: add DAC amplitude fix for 8327 phy
+
+QCA8327 internal phy require DAC amplitude adjustement set to +6% with
+100m speed. Also add additional define to report a change of the same
+reg in QCA8337. (different scope it does set 1000m voltage)
+Add link_change_notify function to set the proper amplitude adjustement
+on PHY_RUNNING state and disable on any other state.
+
+Fixes: b4df02b562f4 ("net: phy: at803x: add support for qca 8327 A variant internal phy")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -87,6 +87,8 @@
+ #define AT803X_PSSR_MR_AN_COMPLETE    0x0200
+ #define AT803X_DEBUG_REG_0                    0x00
++#define QCA8327_DEBUG_MANU_CTRL_EN            BIT(2)
++#define QCA8337_DEBUG_MANU_CTRL_EN            GENMASK(3, 2)
+ #define AT803X_DEBUG_RX_CLK_DLY_EN            BIT(15)
+ #define AT803X_DEBUG_REG_5                    0x05
+@@ -1222,9 +1224,37 @@ static int qca83xx_config_init(struct ph
+               break;
+       }
++      /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
++       * Disable on init and enable only with 100m speed following
++       * qca original source code.
++       */
++      if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
++          phydev->drv->phy_id == QCA8327_B_PHY_ID)
++              at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
++                                    QCA8327_DEBUG_MANU_CTRL_EN, 0);
++
+       return 0;
+ }
++static void qca83xx_link_change_notify(struct phy_device *phydev)
++{
++      /* QCA8337 doesn't require DAC Amplitude adjustement */
++      if (phydev->drv->phy_id == QCA8337_PHY_ID)
++              return;
++
++      /* Set DAC Amplitude adjustment to +6% for 100m on link running */
++      if (phydev->state == PHY_RUNNING) {
++              if (phydev->speed == SPEED_100)
++                      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
++                                            QCA8327_DEBUG_MANU_CTRL_EN,
++                                            QCA8327_DEBUG_MANU_CTRL_EN);
++      } else {
++              /* Reset DAC Amplitude adjustment */
++              at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
++                                    QCA8327_DEBUG_MANU_CTRL_EN, 0);
++      }
++}
++
+ static int qca83xx_resume(struct phy_device *phydev)
+ {
+       int ret, val;
+@@ -1379,6 +1409,7 @@ static struct phy_driver at803x_driver[]
+       .phy_id_mask            = QCA8K_PHY_ID_MASK,
+       .name                   = "Qualcomm Atheros 8337 internal PHY",
+       /* PHY_GBIT_FEATURES */
++      .link_change_notify     = qca83xx_link_change_notify,
+       .probe                  = at803x_probe,
+       .flags                  = PHY_IS_INTERNAL,
+       .config_init            = qca83xx_config_init,
+@@ -1394,6 +1425,7 @@ static struct phy_driver at803x_driver[]
+       .phy_id_mask            = QCA8K_PHY_ID_MASK,
+       .name                   = "Qualcomm Atheros 8327-A internal PHY",
+       /* PHY_GBIT_FEATURES */
++      .link_change_notify     = qca83xx_link_change_notify,
+       .probe                  = at803x_probe,
+       .flags                  = PHY_IS_INTERNAL,
+       .config_init            = qca83xx_config_init,
+@@ -1409,6 +1441,7 @@ static struct phy_driver at803x_driver[]
+       .phy_id_mask            = QCA8K_PHY_ID_MASK,
+       .name                   = "Qualcomm Atheros 8327-B internal PHY",
+       /* PHY_GBIT_FEATURES */
++      .link_change_notify     = qca83xx_link_change_notify,
+       .probe                  = at803x_probe,
+       .flags                  = PHY_IS_INTERNAL,
+       .config_init            = qca83xx_config_init,
diff --git a/target/linux/generic/backport-5.10/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch b/target/linux/generic/backport-5.10/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch
new file mode 100644 (file)
index 0000000..2352fa0
--- /dev/null
@@ -0,0 +1,27 @@
+From 9d1c29b4028557a496be9c5eb2b4b86063700636 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 10 Oct 2021 00:46:17 +0200
+Subject: net: phy: at803x: enable prefer master for 83xx internal phy
+
+From original QCA source code the port was set to prefer master as port
+type in 1000BASE-T mode. Apply the same settings also here.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -1233,6 +1233,9 @@ static int qca83xx_config_init(struct ph
+               at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
+                                     QCA8327_DEBUG_MANU_CTRL_EN, 0);
++      /* Following original QCA sourcecode set port to prefer master */
++      phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
++
+       return 0;
+ }
diff --git a/target/linux/generic/backport-5.10/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch b/target/linux/generic/backport-5.10/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch
new file mode 100644 (file)
index 0000000..9c28a89
--- /dev/null
@@ -0,0 +1,127 @@
+From 67999555ff42e91de7654488d9a7735bd9e84555 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 10 Oct 2021 00:46:18 +0200
+Subject: net: phy: at803x: better describe debug regs
+
+Give a name to known debug regs from Documentation instead of using
+unknown hex values.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/at803x.c | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -86,12 +86,12 @@
+ #define AT803X_PSSR                   0x11    /*PHY-Specific Status Register*/
+ #define AT803X_PSSR_MR_AN_COMPLETE    0x0200
+-#define AT803X_DEBUG_REG_0                    0x00
++#define AT803X_DEBUG_ANALOG_TEST_CTRL         0x00
+ #define QCA8327_DEBUG_MANU_CTRL_EN            BIT(2)
+ #define QCA8337_DEBUG_MANU_CTRL_EN            GENMASK(3, 2)
+ #define AT803X_DEBUG_RX_CLK_DLY_EN            BIT(15)
+-#define AT803X_DEBUG_REG_5                    0x05
++#define AT803X_DEBUG_SYSTEM_CTRL_MODE         0x05
+ #define AT803X_DEBUG_TX_CLK_DLY_EN            BIT(8)
+ #define AT803X_DEBUG_REG_HIB_CTRL             0x0b
+@@ -100,7 +100,7 @@
+ #define AT803X_DEBUG_REG_3C                   0x3C
+-#define AT803X_DEBUG_REG_3D                   0x3D
++#define AT803X_DEBUG_REG_GREEN                        0x3D
+ #define   AT803X_DEBUG_GATE_CLK_IN1000                BIT(6)
+ #define AT803X_DEBUG_REG_1F                   0x1F
+@@ -274,25 +274,25 @@ static int at803x_read_page(struct phy_d
+ static int at803x_enable_rx_delay(struct phy_device *phydev)
+ {
+-      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
++      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0,
+                                    AT803X_DEBUG_RX_CLK_DLY_EN);
+ }
+ static int at803x_enable_tx_delay(struct phy_device *phydev)
+ {
+-      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
++      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0,
+                                    AT803X_DEBUG_TX_CLK_DLY_EN);
+ }
+ static int at803x_disable_rx_delay(struct phy_device *phydev)
+ {
+-      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
++      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
+                                    AT803X_DEBUG_RX_CLK_DLY_EN, 0);
+ }
+ static int at803x_disable_tx_delay(struct phy_device *phydev)
+ {
+-      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
++      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE,
+                                    AT803X_DEBUG_TX_CLK_DLY_EN, 0);
+ }
+@@ -1208,9 +1208,9 @@ static int qca83xx_config_init(struct ph
+       switch (switch_revision) {
+       case 1:
+               /* For 100M waveform */
+-              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_0, 0x02ea);
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea);
+               /* Turn on Gigabit clock */
+-              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x68a0);
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0);
+               break;
+       case 2:
+@@ -1218,8 +1218,8 @@ static int qca83xx_config_init(struct ph
+               fallthrough;
+       case 4:
+               phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
+-              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x6860);
+-              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_5, 0x2c46);
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860);
++              at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46);
+               at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
+               break;
+       }
+@@ -1230,7 +1230,7 @@ static int qca83xx_config_init(struct ph
+        */
+       if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
+           phydev->drv->phy_id == QCA8327_B_PHY_ID)
+-              at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
++              at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
+                                     QCA8327_DEBUG_MANU_CTRL_EN, 0);
+       /* Following original QCA sourcecode set port to prefer master */
+@@ -1248,12 +1248,12 @@ static void qca83xx_link_change_notify(s
+       /* Set DAC Amplitude adjustment to +6% for 100m on link running */
+       if (phydev->state == PHY_RUNNING) {
+               if (phydev->speed == SPEED_100)
+-                      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
++                      at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
+                                             QCA8327_DEBUG_MANU_CTRL_EN,
+                                             QCA8327_DEBUG_MANU_CTRL_EN);
+       } else {
+               /* Reset DAC Amplitude adjustment */
+-              at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
++              at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
+                                     QCA8327_DEBUG_MANU_CTRL_EN, 0);
+       }
+ }
+@@ -1300,7 +1300,7 @@ static int qca83xx_suspend(struct phy_de
+               phy_modify(phydev, MII_BMCR, mask, 0);
+       }
+-      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D,
++      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
+                             AT803X_DEBUG_GATE_CLK_IN1000, 0);
+       at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
diff --git a/target/linux/generic/backport-5.10/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch b/target/linux/generic/backport-5.10/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch
new file mode 100644 (file)
index 0000000..c8d424d
--- /dev/null
@@ -0,0 +1,80 @@
+From d8b6f5bae6d3b648a67b6958cb98e4e97256d652 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:06 +0200
+Subject: dsa: qca8k: add mac_power_sel support
+
+Add missing mac power sel support needed for ipq8064/5 SoC that require
+1.8v for the internal regulator port instead of the default 1.5v.
+If other device needs this, consider adding a dedicated binding to
+support this.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 31 +++++++++++++++++++++++++++++++
+ drivers/net/dsa/qca8k.h |  5 +++++
+ 2 files changed, 36 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -951,6 +951,33 @@ qca8k_setup_of_rgmii_delay(struct qca8k_
+ }
+ static int
++qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
++{
++      u32 mask = 0;
++      int ret = 0;
++
++      /* SoC specific settings for ipq8064.
++       * If more device require this consider adding
++       * a dedicated binding.
++       */
++      if (of_machine_is_compatible("qcom,ipq8064"))
++              mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
++
++      /* SoC specific settings for ipq8065 */
++      if (of_machine_is_compatible("qcom,ipq8065"))
++              mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
++
++      if (mask) {
++              ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
++                              QCA8K_MAC_PWR_RGMII0_1_8V |
++                              QCA8K_MAC_PWR_RGMII1_1_8V,
++                              mask);
++      }
++
++      return ret;
++}
++
++static int
+ qca8k_setup(struct dsa_switch *ds)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+@@ -979,6 +1006,10 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               return ret;
++      ret = qca8k_setup_mac_pwr_sel(priv);
++      if (ret)
++              return ret;
++
+       /* Enable CPU Port */
+       ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
+                           QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -100,6 +100,11 @@
+ #define   QCA8K_SGMII_MODE_CTRL_PHY                   (1 << 22)
+ #define   QCA8K_SGMII_MODE_CTRL_MAC                   (2 << 22)
++/* MAC_PWR_SEL registers */
++#define QCA8K_REG_MAC_PWR_SEL                         0x0e4
++#define   QCA8K_MAC_PWR_RGMII1_1_8V                   BIT(18)
++#define   QCA8K_MAC_PWR_RGMII0_1_8V                   BIT(19)
++
+ /* EEE control registers */
+ #define QCA8K_REG_EEE_CTRL                            0x100
+ #define  QCA8K_REG_EEE_CTRL_LPI_EN(_i)                        ((_i + 1) * 2)
diff --git a/target/linux/generic/backport-5.10/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch b/target/linux/generic/backport-5.10/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch
new file mode 100644 (file)
index 0000000..bd768ec
--- /dev/null
@@ -0,0 +1,30 @@
+From fdbf35df9c091db9c46e57e9938e3f7a4f603a7c Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:07 +0200
+Subject: dt-bindings: net: dsa: qca8k: Add SGMII clock phase properties
+
+Add names and descriptions of additional PORT0_PAD_CTRL properties.
+qca,sgmii-(rx|tx)clk-falling-edge are for setting the respective clock
+phase to failling edge.
+
+Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -37,6 +37,10 @@ A CPU port node has the following option
+                           managed entity. See
+                           Documentation/devicetree/bindings/net/fixed-link.txt
+                           for details.
++- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
++                                Mostly used in qca8327 with CPU port 0 set to
++                                sgmii.
++- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
+ For QCA8K the 'fixed-link' sub-node supports only the following properties:
diff --git a/target/linux/generic/backport-5.10/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch b/target/linux/generic/backport-5.10/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch
new file mode 100644 (file)
index 0000000..e464452
--- /dev/null
@@ -0,0 +1,127 @@
+From 6c43809bf1bee76c434e365a26546a92a5fbec14 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:08 +0200
+Subject: net: dsa: qca8k: add support for sgmii falling edge
+
+Add support for this in the qca8k driver. Also add support for SGMII
+rx/tx clock falling edge. This is only present for pad0, pad5 and
+pad6 have these bit reserved from Documentation. Add a comment that this
+is hardcoded to PAD0 as qca8327/28/34/37 have an unique sgmii line and
+setting falling in port0 applies to both configuration with sgmii used
+for port0 or port6.
+
+Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/qca8k.h |  4 ++++
+ 2 files changed, 67 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -978,6 +978,42 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
+ }
+ static int
++qca8k_parse_port_config(struct qca8k_priv *priv)
++{
++      struct device_node *port_dn;
++      phy_interface_t mode;
++      struct dsa_port *dp;
++      int port, ret;
++
++      /* We have 2 CPU port. Check them */
++      for (port = 0; port < QCA8K_NUM_PORTS; port++) {
++              /* Skip every other port */
++              if (port != 0 && port != 6)
++                      continue;
++
++              dp = dsa_to_port(priv->ds, port);
++              port_dn = dp->dn;
++
++              if (!of_device_is_available(port_dn))
++                      continue;
++
++              ret = of_get_phy_mode(port_dn, &mode);
++              if (ret)
++                      continue;
++
++              if (mode == PHY_INTERFACE_MODE_SGMII) {
++                      if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
++                              priv->sgmii_tx_clk_falling_edge = true;
++
++                      if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
++                              priv->sgmii_rx_clk_falling_edge = true;
++              }
++      }
++
++      return 0;
++}
++
++static int
+ qca8k_setup(struct dsa_switch *ds)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+@@ -990,6 +1026,11 @@ qca8k_setup(struct dsa_switch *ds)
+               return -EINVAL;
+       }
++      /* Parse CPU port config to be later used in phy_link mac_config */
++      ret = qca8k_parse_port_config(priv);
++      if (ret)
++              return ret;
++
+       mutex_init(&priv->reg_mutex);
+       /* Start by setting up the register mapping */
+@@ -1274,6 +1315,28 @@ qca8k_phylink_mac_config(struct dsa_swit
+               }
+               qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
++
++              /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
++               * falling edge is set writing in the PORT0 PAD reg
++               */
++              if (priv->switch_id == QCA8K_ID_QCA8327 ||
++                  priv->switch_id == QCA8K_ID_QCA8337)
++                      reg = QCA8K_REG_PORT0_PAD_CTRL;
++
++              val = 0;
++
++              /* SGMII Clock phase configuration */
++              if (priv->sgmii_rx_clk_falling_edge)
++                      val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
++
++              if (priv->sgmii_tx_clk_falling_edge)
++                      val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
++
++              if (val)
++                      ret = qca8k_rmw(priv, reg,
++                                      QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
++                                      QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
++                                      val);
+               break;
+       default:
+               dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -35,6 +35,8 @@
+ #define   QCA8K_MASK_CTRL_DEVICE_ID_MASK              GENMASK(15, 8)
+ #define   QCA8K_MASK_CTRL_DEVICE_ID(x)                        ((x) >> 8)
+ #define QCA8K_REG_PORT0_PAD_CTRL                      0x004
++#define   QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE    BIT(19)
++#define   QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE    BIT(18)
+ #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
+ #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
+ #define   QCA8K_PORT_PAD_RGMII_EN                     BIT(26)
+@@ -260,6 +262,8 @@ struct qca8k_priv {
+       u8 switch_revision;
+       u8 rgmii_tx_delay;
+       u8 rgmii_rx_delay;
++      bool sgmii_rx_clk_falling_edge;
++      bool sgmii_tx_clk_falling_edge;
+       bool legacy_phy_port_mapping;
+       struct regmap *regmap;
+       struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.10/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch b/target/linux/generic/backport-5.10/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch
new file mode 100644 (file)
index 0000000..606ac0a
--- /dev/null
@@ -0,0 +1,29 @@
+From 731d613338ec6de482053ffa3f71be2325b0f8eb Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:09 +0200
+Subject: dt-bindings: net: dsa: qca8k: Document support for CPU port 6
+
+The switch now support CPU port to be set 6 instead of be hardcoded to
+0. Document support for it and describe logic selection.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -29,7 +29,11 @@ the mdio MASTER is used as communication
+ Don't use mixed external and internal mdio-bus configurations, as this is
+ not supported by the hardware.
+-The CPU port of this switch is always port 0.
++This switch support 2 CPU port. Normally and advised configuration is with
++CPU port set to port 0. It is also possible to set the CPU port to port 6
++if the device requires it. The driver will configure the switch to the defined
++port. With both CPU port declared the first CPU port is selected as primary
++and the secondary CPU ignored.
+ A CPU port node has the following optional node:
diff --git a/target/linux/generic/backport-5.10/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch b/target/linux/generic/backport-5.10/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch
new file mode 100644 (file)
index 0000000..320db8f
--- /dev/null
@@ -0,0 +1,153 @@
+From 3fcf734aa482487df83cf8f18608438fcf59127f Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:10 +0200
+Subject: net: dsa: qca8k: add support for cpu port 6
+
+Currently CPU port is always hardcoded to port 0. This switch have 2 CPU
+ports. The original intention of this driver seems to be use the
+mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration
+where device have connected only the CPU port 6. To skip the
+introduction of a new binding, rework the driver to address the
+secondary CPU port as primary and drop any reference of hardcoded port.
+With configuration of mac06 exchange, just skip the definition of port0
+and define the CPU port as a secondary. The driver will autoconfigure
+the switch to use that as the primary CPU port.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 51 ++++++++++++++++++++++++++++++++++---------------
+ drivers/net/dsa/qca8k.h |  2 --
+ 2 files changed, 36 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
+       return ret;
+ }
++static int qca8k_find_cpu_port(struct dsa_switch *ds)
++{
++      struct qca8k_priv *priv = ds->priv;
++
++      /* Find the connected cpu port. Valid port are 0 or 6 */
++      if (dsa_is_cpu_port(ds, 0))
++              return 0;
++
++      dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
++
++      if (dsa_is_cpu_port(ds, 6))
++              return 6;
++
++      return -EINVAL;
++}
++
+ static int
+ qca8k_parse_port_config(struct qca8k_priv *priv)
+ {
+@@ -1017,13 +1033,13 @@ static int
+ qca8k_setup(struct dsa_switch *ds)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+-      int ret, i;
++      int cpu_port, ret, i;
+       u32 mask;
+-      /* Make sure that port 0 is the cpu port */
+-      if (!dsa_is_cpu_port(ds, 0)) {
+-              dev_err(priv->dev, "port 0 is not the CPU port");
+-              return -EINVAL;
++      cpu_port = qca8k_find_cpu_port(ds);
++      if (cpu_port < 0) {
++              dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
++              return cpu_port;
+       }
+       /* Parse CPU port config to be later used in phy_link mac_config */
+@@ -1065,7 +1081,7 @@ qca8k_setup(struct dsa_switch *ds)
+               dev_warn(priv->dev, "mib init failed");
+       /* Enable QCA header mode on the cpu port */
+-      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
++      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
+                         QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
+                         QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
+       if (ret) {
+@@ -1087,10 +1103,10 @@ qca8k_setup(struct dsa_switch *ds)
+       /* Forward all unknown frames to CPU port for Linux processing */
+       ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
+-                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
+-                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
+-                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
+-                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
++                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
++                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
++                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
++                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
+       if (ret)
+               return ret;
+@@ -1098,7 +1114,7 @@ qca8k_setup(struct dsa_switch *ds)
+       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+               /* CPU port gets connected to all user ports of the switch */
+               if (dsa_is_cpu_port(ds, i)) {
+-                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
++                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
+                                       QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
+                       if (ret)
+                               return ret;
+@@ -1110,7 +1126,7 @@ qca8k_setup(struct dsa_switch *ds)
+                       ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
+                                       QCA8K_PORT_LOOKUP_MEMBER,
+-                                      BIT(QCA8K_CPU_PORT));
++                                      BIT(cpu_port));
+                       if (ret)
+                               return ret;
+@@ -1616,9 +1632,12 @@ static int
+ qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+-      int port_mask = BIT(QCA8K_CPU_PORT);
++      int port_mask, cpu_port;
+       int i, ret;
++      cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
++      port_mask = BIT(cpu_port);
++
+       for (i = 1; i < QCA8K_NUM_PORTS; i++) {
+               if (dsa_to_port(ds, i)->bridge_dev != br)
+                       continue;
+@@ -1645,7 +1664,9 @@ static void
+ qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
+ {
+       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+-      int i;
++      int cpu_port, i;
++
++      cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
+       for (i = 1; i < QCA8K_NUM_PORTS; i++) {
+               if (dsa_to_port(ds, i)->bridge_dev != br)
+@@ -1662,7 +1683,7 @@ qca8k_port_bridge_leave(struct dsa_switc
+        * this port
+        */
+       qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
+-                QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT));
++                QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
+ }
+ static int
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -24,8 +24,6 @@
+ #define QCA8K_NUM_FDB_RECORDS                         2048
+-#define QCA8K_CPU_PORT                                        0
+-
+ #define QCA8K_PORT_VID_DEF                            1
+ /* Global control registers */
diff --git a/target/linux/generic/backport-5.10/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch b/target/linux/generic/backport-5.10/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch
new file mode 100644 (file)
index 0000000..de20176
--- /dev/null
@@ -0,0 +1,295 @@
+From 5654ec78dd7e64b1e04777b24007344329e6a63b Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:11 +0200
+Subject: net: dsa: qca8k: rework rgmii delay logic and scan for cpu port 6
+
+Future proof commit. This switch have 2 CPU ports and one valid
+configuration is first CPU port set to sgmii and second CPU port set to
+rgmii-id. The current implementation detects delay only for CPU port
+zero set to rgmii and doesn't count any delay set in a secondary CPU
+port. Drop the current delay scan function and move it to the sgmii
+parser function to generalize and implicitly add support for secondary
+CPU port set to rgmii-id. Introduce new logic where delay is enabled
+also with internal delay binding declared and rgmii set as PHY mode.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 165 ++++++++++++++++++++++++------------------------
+ drivers/net/dsa/qca8k.h |  10 ++-
+ 2 files changed, 89 insertions(+), 86 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -889,68 +889,6 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
+ }
+ static int
+-qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv)
+-{
+-      struct device_node *port_dn;
+-      phy_interface_t mode;
+-      struct dsa_port *dp;
+-      u32 val;
+-
+-      /* CPU port is already checked */
+-      dp = dsa_to_port(priv->ds, 0);
+-
+-      port_dn = dp->dn;
+-
+-      /* Check if port 0 is set to the correct type */
+-      of_get_phy_mode(port_dn, &mode);
+-      if (mode != PHY_INTERFACE_MODE_RGMII_ID &&
+-          mode != PHY_INTERFACE_MODE_RGMII_RXID &&
+-          mode != PHY_INTERFACE_MODE_RGMII_TXID) {
+-              return 0;
+-      }
+-
+-      switch (mode) {
+-      case PHY_INTERFACE_MODE_RGMII_ID:
+-      case PHY_INTERFACE_MODE_RGMII_RXID:
+-              if (of_property_read_u32(port_dn, "rx-internal-delay-ps", &val))
+-                      val = 2;
+-              else
+-                      /* Switch regs accept value in ns, convert ps to ns */
+-                      val = val / 1000;
+-
+-              if (val > QCA8K_MAX_DELAY) {
+-                      dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
+-                      val = 3;
+-              }
+-
+-              priv->rgmii_rx_delay = val;
+-              /* Stop here if we need to check only for rx delay */
+-              if (mode != PHY_INTERFACE_MODE_RGMII_ID)
+-                      break;
+-
+-              fallthrough;
+-      case PHY_INTERFACE_MODE_RGMII_TXID:
+-              if (of_property_read_u32(port_dn, "tx-internal-delay-ps", &val))
+-                      val = 1;
+-              else
+-                      /* Switch regs accept value in ns, convert ps to ns */
+-                      val = val / 1000;
+-
+-              if (val > QCA8K_MAX_DELAY) {
+-                      dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
+-                      val = 3;
+-              }
+-
+-              priv->rgmii_tx_delay = val;
+-              break;
+-      default:
+-              return 0;
+-      }
+-
+-      return 0;
+-}
+-
+-static int
+ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
+ {
+       u32 mask = 0;
+@@ -996,19 +934,21 @@ static int qca8k_find_cpu_port(struct ds
+ static int
+ qca8k_parse_port_config(struct qca8k_priv *priv)
+ {
++      int port, cpu_port_index = 0, ret;
+       struct device_node *port_dn;
+       phy_interface_t mode;
+       struct dsa_port *dp;
+-      int port, ret;
++      u32 delay;
+       /* We have 2 CPU port. Check them */
+-      for (port = 0; port < QCA8K_NUM_PORTS; port++) {
++      for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) {
+               /* Skip every other port */
+               if (port != 0 && port != 6)
+                       continue;
+               dp = dsa_to_port(priv->ds, port);
+               port_dn = dp->dn;
++              cpu_port_index++;
+               if (!of_device_is_available(port_dn))
+                       continue;
+@@ -1017,12 +957,54 @@ qca8k_parse_port_config(struct qca8k_pri
+               if (ret)
+                       continue;
+-              if (mode == PHY_INTERFACE_MODE_SGMII) {
++              switch (mode) {
++              case PHY_INTERFACE_MODE_RGMII:
++              case PHY_INTERFACE_MODE_RGMII_ID:
++              case PHY_INTERFACE_MODE_RGMII_TXID:
++              case PHY_INTERFACE_MODE_RGMII_RXID:
++                      delay = 0;
++
++                      if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
++                              /* Switch regs accept value in ns, convert ps to ns */
++                              delay = delay / 1000;
++                      else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
++                               mode == PHY_INTERFACE_MODE_RGMII_TXID)
++                              delay = 1;
++
++                      if (delay > QCA8K_MAX_DELAY) {
++                              dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
++                              delay = 3;
++                      }
++
++                      priv->rgmii_tx_delay[cpu_port_index] = delay;
++
++                      delay = 0;
++
++                      if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
++                              /* Switch regs accept value in ns, convert ps to ns */
++                              delay = delay / 1000;
++                      else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
++                               mode == PHY_INTERFACE_MODE_RGMII_RXID)
++                              delay = 2;
++
++                      if (delay > QCA8K_MAX_DELAY) {
++                              dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
++                              delay = 3;
++                      }
++
++                      priv->rgmii_rx_delay[cpu_port_index] = delay;
++
++                      break;
++              case PHY_INTERFACE_MODE_SGMII:
+                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
+                               priv->sgmii_tx_clk_falling_edge = true;
+                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
+                               priv->sgmii_rx_clk_falling_edge = true;
++
++                      break;
++              default:
++                      continue;
+               }
+       }
+@@ -1059,10 +1041,6 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               return ret;
+-      ret = qca8k_setup_of_rgmii_delay(priv);
+-      if (ret)
+-              return ret;
+-
+       ret = qca8k_setup_mac_pwr_sel(priv);
+       if (ret)
+               return ret;
+@@ -1229,8 +1207,8 @@ qca8k_phylink_mac_config(struct dsa_swit
+                        const struct phylink_link_state *state)
+ {
+       struct qca8k_priv *priv = ds->priv;
+-      u32 reg, val;
+-      int ret;
++      int cpu_port_index, ret;
++      u32 reg, val, delay;
+       switch (port) {
+       case 0: /* 1st CPU port */
+@@ -1242,6 +1220,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+                       return;
+               reg = QCA8K_REG_PORT0_PAD_CTRL;
++              cpu_port_index = QCA8K_CPU_PORT0;
+               break;
+       case 1:
+       case 2:
+@@ -1260,6 +1239,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+                       return;
+               reg = QCA8K_REG_PORT6_PAD_CTRL;
++              cpu_port_index = QCA8K_CPU_PORT6;
+               break;
+       default:
+               dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
+@@ -1274,23 +1254,40 @@ qca8k_phylink_mac_config(struct dsa_swit
+       switch (state->interface) {
+       case PHY_INTERFACE_MODE_RGMII:
+-              /* RGMII mode means no delay so don't enable the delay */
+-              qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
+-              break;
+       case PHY_INTERFACE_MODE_RGMII_ID:
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+-              /* RGMII_ID needs internal delay. This is enabled through
+-               * PORT5_PAD_CTRL for all ports, rather than individual port
+-               * registers
++              val = QCA8K_PORT_PAD_RGMII_EN;
++
++              /* Delay can be declared in 3 different way.
++               * Mode to rgmii and internal-delay standard binding defined
++               * rgmii-id or rgmii-tx/rx phy mode set.
++               * The parse logic set a delay different than 0 only when one
++               * of the 3 different way is used. In all other case delay is
++               * not enabled. With ID or TX/RXID delay is enabled and set
++               * to the default and recommended value.
++               */
++              if (priv->rgmii_tx_delay[cpu_port_index]) {
++                      delay = priv->rgmii_tx_delay[cpu_port_index];
++
++                      val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
++                             QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
++              }
++
++              if (priv->rgmii_rx_delay[cpu_port_index]) {
++                      delay = priv->rgmii_rx_delay[cpu_port_index];
++
++                      val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
++                             QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
++              }
++
++              /* Set RGMII delay based on the selected values */
++              qca8k_write(priv, reg, val);
++
++              /* QCA8337 requires to set rgmii rx delay for all ports.
++               * This is enabled through PORT5_PAD_CTRL for all ports,
++               * rather than individual port registers.
+                */
+-              qca8k_write(priv, reg,
+-                          QCA8K_PORT_PAD_RGMII_EN |
+-                          QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay) |
+-                          QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay) |
+-                          QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
+-                          QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
+-              /* QCA8337 requires to set rgmii rx delay */
+               if (priv->switch_id == QCA8K_ID_QCA8337)
+                       qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
+                                   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -13,6 +13,7 @@
+ #include <linux/gpio.h>
+ #define QCA8K_NUM_PORTS                                       7
++#define QCA8K_NUM_CPU_PORTS                           2
+ #define QCA8K_MAX_MTU                                 9000
+ #define PHY_ID_QCA8327                                        0x004dd034
+@@ -255,13 +256,18 @@ struct qca8k_match_data {
+       u8 id;
+ };
++enum {
++      QCA8K_CPU_PORT0,
++      QCA8K_CPU_PORT6,
++};
++
+ struct qca8k_priv {
+       u8 switch_id;
+       u8 switch_revision;
+-      u8 rgmii_tx_delay;
+-      u8 rgmii_rx_delay;
+       bool sgmii_rx_clk_falling_edge;
+       bool sgmii_tx_clk_falling_edge;
++      u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
++      u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
+       bool legacy_phy_port_mapping;
+       struct regmap *regmap;
+       struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.10/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch b/target/linux/generic/backport-5.10/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch
new file mode 100644 (file)
index 0000000..8abd264
--- /dev/null
@@ -0,0 +1,33 @@
+From 13ad5ccc093ff448b99ac7e138e91e78796adb48 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:12 +0200
+Subject: dt-bindings: net: dsa: qca8k: Document qca,sgmii-enable-pll
+
+Document qca,sgmii-enable-pll binding used in the CPU nodes to
+enable SGMII PLL on MAC config.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -45,6 +45,16 @@ A CPU port node has the following option
+                                 Mostly used in qca8327 with CPU port 0 set to
+                                 sgmii.
+ - qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
++- qca,sgmii-enable-pll  : For SGMII CPU port, explicitly enable PLL, TX and RX
++                          chain along with Signal Detection.
++                          This should NOT be enabled for qca8327. If enabled with
++                          qca8327 the sgmii port won't correctly init and an err
++                          is printed.
++                          This can be required for qca8337 switch with revision 2.
++                          A warning is displayed when used with revision greater
++                          2.
++                          With CPU port set to sgmii and qca8337 it is advised
++                          to set this unless a communication problem is observed.
+ For QCA8K the 'fixed-link' sub-node supports only the following properties:
diff --git a/target/linux/generic/backport-5.10/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch b/target/linux/generic/backport-5.10/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch
new file mode 100644 (file)
index 0000000..2b5a84a
--- /dev/null
@@ -0,0 +1,65 @@
+From bbc4799e8bb6c397e3b3fec13de68e179f5db9ff Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:13 +0200
+Subject: net: dsa: qca8k: add explicit SGMII PLL enable
+
+Support enabling PLL on the SGMII CPU port. Some device require this
+special configuration or no traffic is transmitted and the switch
+doesn't work at all. A dedicated binding is added to the CPU node
+port to apply the correct reg on mac config.
+Fail to correctly configure sgmii with qca8327 switch and warn if pll is
+used on qca8337 with a revision greater than 1.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 19 +++++++++++++++++--
+ drivers/net/dsa/qca8k.h |  1 +
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1002,6 +1002,18 @@ qca8k_parse_port_config(struct qca8k_pri
+                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
+                               priv->sgmii_rx_clk_falling_edge = true;
++                      if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
++                              priv->sgmii_enable_pll = true;
++
++                              if (priv->switch_id == QCA8K_ID_QCA8327) {
++                                      dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
++                                      priv->sgmii_enable_pll = false;
++                              }
++
++                              if (priv->switch_revision < 2)
++                                      dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
++                      }
++
+                       break;
+               default:
+                       continue;
+@@ -1312,8 +1324,11 @@ qca8k_phylink_mac_config(struct dsa_swit
+               if (ret)
+                       return;
+-              val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+-                      QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
++              val |= QCA8K_SGMII_EN_SD;
++
++              if (priv->sgmii_enable_pll)
++                      val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
++                             QCA8K_SGMII_EN_TX;
+               if (dsa_is_cpu_port(ds, port)) {
+                       /* CPU port, we're talking to the CPU MAC, be a PHY */
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -266,6 +266,7 @@ struct qca8k_priv {
+       u8 switch_revision;
+       bool sgmii_rx_clk_falling_edge;
+       bool sgmii_tx_clk_falling_edge;
++      bool sgmii_enable_pll;
+       u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
+       u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
+       bool legacy_phy_port_mapping;
diff --git a/target/linux/generic/backport-5.10/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch b/target/linux/generic/backport-5.10/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch
new file mode 100644 (file)
index 0000000..38dc954
--- /dev/null
@@ -0,0 +1,37 @@
+From 924087c5c3d41553700b0eb83ca2a53b91643dca Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:14 +0200
+Subject: dt-bindings: net: dsa: qca8k: Document qca,led-open-drain binding
+
+Document new binding qca,ignore-power-on-sel used to ignore
+power on strapping and use sw regs instead.
+Document qca,led-open.drain to set led to open drain mode, the
+qca,ignore-power-on-sel is mandatory with this enabled or an error will
+be reported.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -13,6 +13,17 @@ Required properties:
+ Optional properties:
+ - reset-gpios: GPIO to be used to reset the whole device
++- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
++                           drain or eeprom presence. This is needed for broken
++                           devices that have wrong configuration or when the oem
++                           decided to not use pin strapping and fallback to sw
++                           regs.
++- qca,led-open-drain: Set leds to open-drain mode. This requires the
++                      qca,ignore-power-on-sel to be set or the driver will fail
++                      to probe. This is needed if the oem doesn't use pin
++                      strapping to set this mode and prefers to set it using sw
++                      regs. The pin strapping related to led open drain mode is
++                      the pin B68 for QCA832x and B49 for QCA833x
+ Subnodes:
diff --git a/target/linux/generic/backport-5.10/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch b/target/linux/generic/backport-5.10/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch
new file mode 100644 (file)
index 0000000..aa5d92a
--- /dev/null
@@ -0,0 +1,92 @@
+From 362bb238d8bf1470424214a8a5968d9c6cce68fa Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:15 +0200
+Subject: net: dsa: qca8k: add support for pws config reg
+
+Some qca8327 switch require to force the ignore of power on sel
+strapping. Some switch require to set the led open drain mode in regs
+instead of using strapping. While most of the device implements this
+using the correct way using pin strapping, there are still some broken
+device that require to be set using sw regs.
+Introduce a new binding and support these special configuration.
+As led open drain require to ignore pin strapping to work, the probe
+fails with EINVAL error with incorrect configuration.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 39 +++++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/qca8k.h |  6 ++++++
+ 2 files changed, 45 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -932,6 +932,41 @@ static int qca8k_find_cpu_port(struct ds
+ }
+ static int
++qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
++{
++      struct device_node *node = priv->dev->of_node;
++      u32 val = 0;
++      int ret;
++
++      /* QCA8327 require to set to the correct mode.
++       * His bigger brother QCA8328 have the 172 pin layout.
++       * Should be applied by default but we set this just to make sure.
++       */
++      if (priv->switch_id == QCA8K_ID_QCA8327) {
++              ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
++                              QCA8327_PWS_PACKAGE148_EN);
++              if (ret)
++                      return ret;
++      }
++
++      if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
++              val |= QCA8K_PWS_POWER_ON_SEL;
++
++      if (of_property_read_bool(node, "qca,led-open-drain")) {
++              if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
++                      dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
++                      return -EINVAL;
++              }
++
++              val |= QCA8K_PWS_LED_OPEN_EN_CSR;
++      }
++
++      return qca8k_rmw(priv, QCA8K_REG_PWS,
++                      QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
++                      val);
++}
++
++static int
+ qca8k_parse_port_config(struct qca8k_priv *priv)
+ {
+       int port, cpu_port_index = 0, ret;
+@@ -1053,6 +1088,10 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               return ret;
++      ret = qca8k_setup_of_pws_reg(priv);
++      if (ret)
++              return ret;
++
+       ret = qca8k_setup_mac_pwr_sel(priv);
+       if (ret)
+               return ret;
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -46,6 +46,12 @@
+ #define   QCA8K_MAX_DELAY                             3
+ #define   QCA8K_PORT_PAD_SGMII_EN                     BIT(7)
+ #define QCA8K_REG_PWS                                 0x010
++#define   QCA8K_PWS_POWER_ON_SEL                      BIT(31)
++/* This reg is only valid for QCA832x and toggle the package
++ * type from 176 pin (by default) to 148 pin used on QCA8327
++ */
++#define   QCA8327_PWS_PACKAGE148_EN                   BIT(30)
++#define   QCA8K_PWS_LED_OPEN_EN_CSR                   BIT(24)
+ #define   QCA8K_PWS_SERDES_AEN_DIS                    BIT(7)
+ #define QCA8K_REG_MODULE_EN                           0x030
+ #define   QCA8K_MODULE_EN_MIB                         BIT(0)
diff --git a/target/linux/generic/backport-5.10/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch b/target/linux/generic/backport-5.10/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch
new file mode 100644 (file)
index 0000000..1bfb00c
--- /dev/null
@@ -0,0 +1,32 @@
+From ed7988d77fbfb79366b68f9e7fa60a6080da23d4 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:16 +0200
+Subject: dt-bindings: net: dsa: qca8k: document support for qca8328
+
+QCA8328 is the bigger brother of qca8327. Document the new compatible
+binding and add some information to understand the various switch
+compatible.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/dsa/qca8k.txt | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+@@ -3,9 +3,10 @@
+ Required properties:
+ - compatible: should be one of:
+-    "qca,qca8327"
+-    "qca,qca8334"
+-    "qca,qca8337"
++    "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
++    "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
++    "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
++    "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
+ - #size-cells: must be 0
+ - #address-cells: must be 1
diff --git a/target/linux/generic/backport-5.10/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch b/target/linux/generic/backport-5.10/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch
new file mode 100644 (file)
index 0000000..6e118f5
--- /dev/null
@@ -0,0 +1,78 @@
+From f477d1c8bdbef4f400718238e350f16f521d2a3e Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:17 +0200
+Subject: net: dsa: qca8k: add support for QCA8328
+
+QCA8328 switch is the bigger brother of the qca8327. Same regs different
+chip. Change the function to set the correct pin layout and introduce a
+new match_data to differentiate the 2 switch as they have the same ID
+and their internal PHY have the same ID.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 19 ++++++++++++++++---
+ drivers/net/dsa/qca8k.h |  1 +
+ 2 files changed, 17 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -935,6 +935,7 @@ static int
+ qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
+ {
+       struct device_node *node = priv->dev->of_node;
++      const struct qca8k_match_data *data;
+       u32 val = 0;
+       int ret;
+@@ -943,8 +944,14 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
+        * Should be applied by default but we set this just to make sure.
+        */
+       if (priv->switch_id == QCA8K_ID_QCA8327) {
++              data = of_device_get_match_data(priv->dev);
++
++              /* Set the correct package of 148 pin for QCA8327 */
++              if (data->reduced_package)
++                      val |= QCA8327_PWS_PACKAGE148_EN;
++
+               ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
+-                              QCA8327_PWS_PACKAGE148_EN);
++                              val);
+               if (ret)
+                       return ret;
+       }
+@@ -2098,7 +2105,12 @@ static int qca8k_resume(struct device *d
+ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
+                        qca8k_suspend, qca8k_resume);
+-static const struct qca8k_match_data qca832x = {
++static const struct qca8k_match_data qca8327 = {
++      .id = QCA8K_ID_QCA8327,
++      .reduced_package = true,
++};
++
++static const struct qca8k_match_data qca8328 = {
+       .id = QCA8K_ID_QCA8327,
+ };
+@@ -2107,7 +2119,8 @@ static const struct qca8k_match_data qca
+ };
+ static const struct of_device_id qca8k_of_match[] = {
+-      { .compatible = "qca,qca8327", .data = &qca832x },
++      { .compatible = "qca,qca8327", .data = &qca8327 },
++      { .compatible = "qca,qca8328", .data = &qca8328 },
+       { .compatible = "qca,qca8334", .data = &qca833x },
+       { .compatible = "qca,qca8337", .data = &qca833x },
+       { /* sentinel */ },
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -260,6 +260,7 @@ struct ar8xxx_port_status {
+ struct qca8k_match_data {
+       u8 id;
++      bool reduced_package;
+ };
+ enum {
diff --git a/target/linux/generic/backport-5.10/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch b/target/linux/generic/backport-5.10/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch
new file mode 100644 (file)
index 0000000..27f94dc
--- /dev/null
@@ -0,0 +1,159 @@
+From cef08115846e581f80ff99abf7bf218da1840616 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:18 +0200
+Subject: net: dsa: qca8k: set internal delay also for sgmii
+
+QCA original code report port instability and sa that SGMII also require
+to set internal delay. Generalize the rgmii delay function and apply the
+advised value if they are not defined in DT.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 88 +++++++++++++++++++++++++++++++++----------------
+ drivers/net/dsa/qca8k.h |  2 ++
+ 2 files changed, 62 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1004,6 +1004,7 @@ qca8k_parse_port_config(struct qca8k_pri
+               case PHY_INTERFACE_MODE_RGMII_ID:
+               case PHY_INTERFACE_MODE_RGMII_TXID:
+               case PHY_INTERFACE_MODE_RGMII_RXID:
++              case PHY_INTERFACE_MODE_SGMII:
+                       delay = 0;
+                       if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
+@@ -1036,8 +1037,13 @@ qca8k_parse_port_config(struct qca8k_pri
+                       priv->rgmii_rx_delay[cpu_port_index] = delay;
+-                      break;
+-              case PHY_INTERFACE_MODE_SGMII:
++                      /* Skip sgmii parsing for rgmii* mode */
++                      if (mode == PHY_INTERFACE_MODE_RGMII ||
++                          mode == PHY_INTERFACE_MODE_RGMII_ID ||
++                          mode == PHY_INTERFACE_MODE_RGMII_TXID ||
++                          mode == PHY_INTERFACE_MODE_RGMII_RXID)
++                              break;
++
+                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
+                               priv->sgmii_tx_clk_falling_edge = true;
+@@ -1261,12 +1267,53 @@ qca8k_setup(struct dsa_switch *ds)
+ }
+ static void
++qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
++                                    u32 reg)
++{
++      u32 delay, val = 0;
++      int ret;
++
++      /* Delay can be declared in 3 different way.
++       * Mode to rgmii and internal-delay standard binding defined
++       * rgmii-id or rgmii-tx/rx phy mode set.
++       * The parse logic set a delay different than 0 only when one
++       * of the 3 different way is used. In all other case delay is
++       * not enabled. With ID or TX/RXID delay is enabled and set
++       * to the default and recommended value.
++       */
++      if (priv->rgmii_tx_delay[cpu_port_index]) {
++              delay = priv->rgmii_tx_delay[cpu_port_index];
++
++              val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
++                      QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
++      }
++
++      if (priv->rgmii_rx_delay[cpu_port_index]) {
++              delay = priv->rgmii_rx_delay[cpu_port_index];
++
++              val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
++                      QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
++      }
++
++      /* Set RGMII delay based on the selected values */
++      ret = qca8k_rmw(priv, reg,
++                      QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
++                      QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
++                      QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
++                      QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
++                      val);
++      if (ret)
++              dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
++                      cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
++}
++
++static void
+ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
+                        const struct phylink_link_state *state)
+ {
+       struct qca8k_priv *priv = ds->priv;
+       int cpu_port_index, ret;
+-      u32 reg, val, delay;
++      u32 reg, val;
+       switch (port) {
+       case 0: /* 1st CPU port */
+@@ -1315,32 +1362,10 @@ qca8k_phylink_mac_config(struct dsa_swit
+       case PHY_INTERFACE_MODE_RGMII_ID:
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+-              val = QCA8K_PORT_PAD_RGMII_EN;
+-
+-              /* Delay can be declared in 3 different way.
+-               * Mode to rgmii and internal-delay standard binding defined
+-               * rgmii-id or rgmii-tx/rx phy mode set.
+-               * The parse logic set a delay different than 0 only when one
+-               * of the 3 different way is used. In all other case delay is
+-               * not enabled. With ID or TX/RXID delay is enabled and set
+-               * to the default and recommended value.
+-               */
+-              if (priv->rgmii_tx_delay[cpu_port_index]) {
+-                      delay = priv->rgmii_tx_delay[cpu_port_index];
+-
+-                      val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
+-                             QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
+-              }
+-
+-              if (priv->rgmii_rx_delay[cpu_port_index]) {
+-                      delay = priv->rgmii_rx_delay[cpu_port_index];
+-
+-                      val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
+-                             QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
+-              }
++              qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
+-              /* Set RGMII delay based on the selected values */
+-              qca8k_write(priv, reg, val);
++              /* Configure rgmii delay */
++              qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
+               /* QCA8337 requires to set rgmii rx delay for all ports.
+                * This is enabled through PORT5_PAD_CTRL for all ports,
+@@ -1411,6 +1436,13 @@ qca8k_phylink_mac_config(struct dsa_swit
+                                       QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
+                                       QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
+                                       val);
++
++              /* From original code is reported port instability as SGMII also
++               * require delay set. Apply advised values here or take them from DT.
++               */
++              if (state->interface == PHY_INTERFACE_MODE_SGMII)
++                      qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
++
+               break;
+       default:
+               dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -39,7 +39,9 @@
+ #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
+ #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
+ #define   QCA8K_PORT_PAD_RGMII_EN                     BIT(26)
++#define   QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK          GENMASK(23, 22)
+ #define   QCA8K_PORT_PAD_RGMII_TX_DELAY(x)            ((x) << 22)
++#define   QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK          GENMASK(21, 20)
+ #define   QCA8K_PORT_PAD_RGMII_RX_DELAY(x)            ((x) << 20)
+ #define         QCA8K_PORT_PAD_RGMII_TX_DELAY_EN              BIT(25)
+ #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN            BIT(24)
diff --git a/target/linux/generic/backport-5.10/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch b/target/linux/generic/backport-5.10/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch
new file mode 100644 (file)
index 0000000..b991798
--- /dev/null
@@ -0,0 +1,124 @@
+From fd0bb28c547f7c8affb1691128cece38f5b626a1 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:19 +0200
+Subject: net: dsa: qca8k: move port config to dedicated struct
+
+Move ports related config to dedicated struct to keep things organized.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 26 +++++++++++++-------------
+ drivers/net/dsa/qca8k.h | 10 +++++++---
+ 2 files changed, 20 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1019,7 +1019,7 @@ qca8k_parse_port_config(struct qca8k_pri
+                               delay = 3;
+                       }
+-                      priv->rgmii_tx_delay[cpu_port_index] = delay;
++                      priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
+                       delay = 0;
+@@ -1035,7 +1035,7 @@ qca8k_parse_port_config(struct qca8k_pri
+                               delay = 3;
+                       }
+-                      priv->rgmii_rx_delay[cpu_port_index] = delay;
++                      priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
+                       /* Skip sgmii parsing for rgmii* mode */
+                       if (mode == PHY_INTERFACE_MODE_RGMII ||
+@@ -1045,17 +1045,17 @@ qca8k_parse_port_config(struct qca8k_pri
+                               break;
+                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
+-                              priv->sgmii_tx_clk_falling_edge = true;
++                              priv->ports_config.sgmii_tx_clk_falling_edge = true;
+                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
+-                              priv->sgmii_rx_clk_falling_edge = true;
++                              priv->ports_config.sgmii_rx_clk_falling_edge = true;
+                       if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
+-                              priv->sgmii_enable_pll = true;
++                              priv->ports_config.sgmii_enable_pll = true;
+                               if (priv->switch_id == QCA8K_ID_QCA8327) {
+                                       dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
+-                                      priv->sgmii_enable_pll = false;
++                                      priv->ports_config.sgmii_enable_pll = false;
+                               }
+                               if (priv->switch_revision < 2)
+@@ -1281,15 +1281,15 @@ qca8k_mac_config_setup_internal_delay(st
+        * not enabled. With ID or TX/RXID delay is enabled and set
+        * to the default and recommended value.
+        */
+-      if (priv->rgmii_tx_delay[cpu_port_index]) {
+-              delay = priv->rgmii_tx_delay[cpu_port_index];
++      if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
++              delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];
+               val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
+                       QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
+       }
+-      if (priv->rgmii_rx_delay[cpu_port_index]) {
+-              delay = priv->rgmii_rx_delay[cpu_port_index];
++      if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
++              delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
+               val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
+                       QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
+@@ -1397,7 +1397,7 @@ qca8k_phylink_mac_config(struct dsa_swit
+               val |= QCA8K_SGMII_EN_SD;
+-              if (priv->sgmii_enable_pll)
++              if (priv->ports_config.sgmii_enable_pll)
+                       val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+                              QCA8K_SGMII_EN_TX;
+@@ -1425,10 +1425,10 @@ qca8k_phylink_mac_config(struct dsa_swit
+               val = 0;
+               /* SGMII Clock phase configuration */
+-              if (priv->sgmii_rx_clk_falling_edge)
++              if (priv->ports_config.sgmii_rx_clk_falling_edge)
+                       val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
+-              if (priv->sgmii_tx_clk_falling_edge)
++              if (priv->ports_config.sgmii_tx_clk_falling_edge)
+                       val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
+               if (val)
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -270,15 +270,19 @@ enum {
+       QCA8K_CPU_PORT6,
+ };
+-struct qca8k_priv {
+-      u8 switch_id;
+-      u8 switch_revision;
++struct qca8k_ports_config {
+       bool sgmii_rx_clk_falling_edge;
+       bool sgmii_tx_clk_falling_edge;
+       bool sgmii_enable_pll;
+       u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
+       u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
++};
++
++struct qca8k_priv {
++      u8 switch_id;
++      u8 switch_revision;
+       bool legacy_phy_port_mapping;
++      struct qca8k_ports_config ports_config;
+       struct regmap *regmap;
+       struct mii_bus *bus;
+       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch b/target/linux/generic/backport-5.10/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch
new file mode 100644 (file)
index 0000000..f7cb514
--- /dev/null
@@ -0,0 +1,26 @@
+From e52073a8e3086046a098b8a7cbeb282ff0cdb424 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:20 +0200
+Subject: dt-bindings: net: ipq8064-mdio: fix warning with new qca8k switch
+
+Fix warning now that we have qca8k switch Documentation using yaml.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
++++ b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
+@@ -51,6 +51,9 @@ examples:
+         switch@10 {
+             compatible = "qca,qca8337";
+             reg = <0x10>;
+-            /* ... */
++
++            ports {
++              /* ... */
++            };
+         };
+     };
diff --git a/target/linux/generic/backport-5.10/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch b/target/linux/generic/backport-5.10/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch
new file mode 100644 (file)
index 0000000..b9bce97
--- /dev/null
@@ -0,0 +1,631 @@
+From d291fbb8245d5ba04979fed85575860a5cea7196 Mon Sep 17 00:00:00 2001
+From: Matthew Hagan <mnhagan88@gmail.com>
+Date: Thu, 14 Oct 2021 00:39:21 +0200
+Subject: dt-bindings: net: dsa: qca8k: convert to YAML schema
+
+Convert the qca8k bindings to YAML format.
+
+Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
+Co-developed-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../devicetree/bindings/net/dsa/qca8k.txt          | 245 --------------
+ .../devicetree/bindings/net/dsa/qca8k.yaml         | 362 +++++++++++++++++++++
+ 2 files changed, 362 insertions(+), 245 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.txt
+ create mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.yaml
+
+--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
++++ /dev/null
+@@ -1,245 +0,0 @@
+-* Qualcomm Atheros QCA8xxx switch family
+-
+-Required properties:
+-
+-- compatible: should be one of:
+-    "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
+-    "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
+-    "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
+-    "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
+-
+-- #size-cells: must be 0
+-- #address-cells: must be 1
+-
+-Optional properties:
+-
+-- reset-gpios: GPIO to be used to reset the whole device
+-- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
+-                           drain or eeprom presence. This is needed for broken
+-                           devices that have wrong configuration or when the oem
+-                           decided to not use pin strapping and fallback to sw
+-                           regs.
+-- qca,led-open-drain: Set leds to open-drain mode. This requires the
+-                      qca,ignore-power-on-sel to be set or the driver will fail
+-                      to probe. This is needed if the oem doesn't use pin
+-                      strapping to set this mode and prefers to set it using sw
+-                      regs. The pin strapping related to led open drain mode is
+-                      the pin B68 for QCA832x and B49 for QCA833x
+-
+-Subnodes:
+-
+-The integrated switch subnode should be specified according to the binding
+-described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external
+-mdio-bus each subnode describing a port needs to have a valid phandle
+-referencing the internal PHY it is connected to. This is because there's no
+-N:N mapping of port and PHY id.
+-To declare the internal mdio-bus configuration, declare a mdio node in the
+-switch node and declare the phandle for the port referencing the internal
+-PHY is connected to. In this config a internal mdio-bus is registered and
+-the mdio MASTER is used as communication.
+-
+-Don't use mixed external and internal mdio-bus configurations, as this is
+-not supported by the hardware.
+-
+-This switch support 2 CPU port. Normally and advised configuration is with
+-CPU port set to port 0. It is also possible to set the CPU port to port 6
+-if the device requires it. The driver will configure the switch to the defined
+-port. With both CPU port declared the first CPU port is selected as primary
+-and the secondary CPU ignored.
+-
+-A CPU port node has the following optional node:
+-
+-- fixed-link            : Fixed-link subnode describing a link to a non-MDIO
+-                          managed entity. See
+-                          Documentation/devicetree/bindings/net/fixed-link.txt
+-                          for details.
+-- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
+-                                Mostly used in qca8327 with CPU port 0 set to
+-                                sgmii.
+-- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
+-- qca,sgmii-enable-pll  : For SGMII CPU port, explicitly enable PLL, TX and RX
+-                          chain along with Signal Detection.
+-                          This should NOT be enabled for qca8327. If enabled with
+-                          qca8327 the sgmii port won't correctly init and an err
+-                          is printed.
+-                          This can be required for qca8337 switch with revision 2.
+-                          A warning is displayed when used with revision greater
+-                          2.
+-                          With CPU port set to sgmii and qca8337 it is advised
+-                          to set this unless a communication problem is observed.
+-
+-For QCA8K the 'fixed-link' sub-node supports only the following properties:
+-
+-- 'speed' (integer, mandatory), to indicate the link speed. Accepted
+-  values are 10, 100 and 1000
+-- 'full-duplex' (boolean, optional), to indicate that full duplex is
+-  used. When absent, half duplex is assumed.
+-
+-Examples:
+-
+-for the external mdio-bus configuration:
+-
+-      &mdio0 {
+-              phy_port1: phy@0 {
+-                      reg = <0>;
+-              };
+-
+-              phy_port2: phy@1 {
+-                      reg = <1>;
+-              };
+-
+-              phy_port3: phy@2 {
+-                      reg = <2>;
+-              };
+-
+-              phy_port4: phy@3 {
+-                      reg = <3>;
+-              };
+-
+-              phy_port5: phy@4 {
+-                      reg = <4>;
+-              };
+-
+-              switch@10 {
+-                      compatible = "qca,qca8337";
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-
+-                      reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+-                      reg = <0x10>;
+-
+-                      ports {
+-                              #address-cells = <1>;
+-                              #size-cells = <0>;
+-                              port@0 {
+-                                      reg = <0>;
+-                                      label = "cpu";
+-                                      ethernet = <&gmac1>;
+-                                      phy-mode = "rgmii";
+-                                      fixed-link {
+-                                              speed = 1000;
+-                                              full-duplex;
+-                                      };
+-                              };
+-
+-                              port@1 {
+-                                      reg = <1>;
+-                                      label = "lan1";
+-                                      phy-handle = <&phy_port1>;
+-                              };
+-
+-                              port@2 {
+-                                      reg = <2>;
+-                                      label = "lan2";
+-                                      phy-handle = <&phy_port2>;
+-                              };
+-
+-                              port@3 {
+-                                      reg = <3>;
+-                                      label = "lan3";
+-                                      phy-handle = <&phy_port3>;
+-                              };
+-
+-                              port@4 {
+-                                      reg = <4>;
+-                                      label = "lan4";
+-                                      phy-handle = <&phy_port4>;
+-                              };
+-
+-                              port@5 {
+-                                      reg = <5>;
+-                                      label = "wan";
+-                                      phy-handle = <&phy_port5>;
+-                              };
+-                      };
+-              };
+-      };
+-
+-for the internal master mdio-bus configuration:
+-
+-      &mdio0 {
+-              switch@10 {
+-                      compatible = "qca,qca8337";
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-
+-                      reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+-                      reg = <0x10>;
+-
+-                      ports {
+-                              #address-cells = <1>;
+-                              #size-cells = <0>;
+-
+-                              port@0 {
+-                                      reg = <0>;
+-                                      label = "cpu";
+-                                      ethernet = <&gmac1>;
+-                                      phy-mode = "rgmii";
+-                                      fixed-link {
+-                                              speed = 1000;
+-                                              full-duplex;
+-                                      };
+-                              };
+-
+-                              port@1 {
+-                                      reg = <1>;
+-                                      label = "lan1";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port1>;
+-                              };
+-
+-                              port@2 {
+-                                      reg = <2>;
+-                                      label = "lan2";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port2>;
+-                              };
+-
+-                              port@3 {
+-                                      reg = <3>;
+-                                      label = "lan3";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port3>;
+-                              };
+-
+-                              port@4 {
+-                                      reg = <4>;
+-                                      label = "lan4";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port4>;
+-                              };
+-
+-                              port@5 {
+-                                      reg = <5>;
+-                                      label = "wan";
+-                                      phy-mode = "internal";
+-                                      phy-handle = <&phy_port5>;
+-                              };
+-                      };
+-
+-                      mdio {
+-                              #address-cells = <1>;
+-                              #size-cells = <0>;
+-
+-                              phy_port1: phy@0 {
+-                                      reg = <0>;
+-                              };
+-
+-                              phy_port2: phy@1 {
+-                                      reg = <1>;
+-                              };
+-
+-                              phy_port3: phy@2 {
+-                                      reg = <2>;
+-                              };
+-
+-                              phy_port4: phy@3 {
+-                                      reg = <3>;
+-                              };
+-
+-                              phy_port5: phy@4 {
+-                                      reg = <4>;
+-                              };
+-                      };
+-              };
+-      };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml
+@@ -0,0 +1,362 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/net/dsa/qca8k.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Qualcomm Atheros QCA83xx switch family
++
++maintainers:
++  - John Crispin <john@phrozen.org>
++
++description:
++  If the QCA8K switch is connect to an SoC's external mdio-bus, each subnode
++  describing a port needs to have a valid phandle referencing the internal PHY
++  it is connected to. This is because there is no N:N mapping of port and PHY
++  ID. To declare the internal mdio-bus configuration, declare an MDIO node in
++  the switch node and declare the phandle for the port, referencing the internal
++  PHY it is connected to. In this config, an internal mdio-bus is registered and
++  the MDIO master is used for communication. Mixed external and internal
++  mdio-bus configurations are not supported by the hardware.
++
++properties:
++  compatible:
++    oneOf:
++      - enum:
++          - qca,qca8327
++          - qca,qca8328
++          - qca,qca8334
++          - qca,qca8337
++    description: |
++      qca,qca8328: referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
++      qca,qca8327: referenced as AR8327(N)-AL1A DR-QFN 148 pin package
++      qca,qca8334: referenced as QCA8334-AL3C QFN 88 pin package
++      qca,qca8337: referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
++
++  reg:
++    maxItems: 1
++
++  reset-gpios:
++    description:
++      GPIO to be used to reset the whole device
++    maxItems: 1
++
++  qca,ignore-power-on-sel:
++    $ref: /schemas/types.yaml#/definitions/flag
++    description:
++      Ignore power-on pin strapping to configure LED open-drain or EEPROM
++      presence. This is needed for devices with incorrect configuration or when
++      the OEM has decided not to use pin strapping and falls back to SW regs.
++
++  qca,led-open-drain:
++    $ref: /schemas/types.yaml#/definitions/flag
++    description:
++      Set LEDs to open-drain mode. This requires the qca,ignore-power-on-sel to
++      be set, otherwise the driver will fail at probe. This is required if the
++      OEM does not use pin strapping to set this mode and prefers to set it
++      using SW regs. The pin strappings related to LED open-drain mode are
++      B68 on the QCA832x and B49 on the QCA833x.
++
++  mdio:
++    type: object
++    description: Qca8k switch have an internal mdio to access switch port.
++                 If this is not present, the legacy mapping is used and the
++                 internal mdio access is used.
++                 With the legacy mapping the reg corresponding to the internal
++                 mdio is the switch reg with an offset of -1.
++
++    properties:
++      '#address-cells':
++        const: 1
++      '#size-cells':
++        const: 0
++
++    patternProperties:
++      "^(ethernet-)?phy@[0-4]$":
++        type: object
++
++        allOf:
++          - $ref: "http://devicetree.org/schemas/net/mdio.yaml#"
++
++        properties:
++          reg:
++            maxItems: 1
++
++        required:
++          - reg
++
++patternProperties:
++  "^(ethernet-)?ports$":
++    type: object
++    properties:
++      '#address-cells':
++        const: 1
++      '#size-cells':
++        const: 0
++
++    patternProperties:
++      "^(ethernet-)?port@[0-6]$":
++        type: object
++        description: Ethernet switch ports
++
++        properties:
++          reg:
++            description: Port number
++
++          label:
++            description:
++              Describes the label associated with this port, which will become
++              the netdev name
++            $ref: /schemas/types.yaml#/definitions/string
++
++          link:
++            description:
++              Should be a list of phandles to other switch's DSA port. This
++              port is used as the outgoing port towards the phandle ports. The
++              full routing information must be given, not just the one hop
++              routes to neighbouring switches
++            $ref: /schemas/types.yaml#/definitions/phandle-array
++
++          ethernet:
++            description:
++              Should be a phandle to a valid Ethernet device node.  This host
++              device is what the switch port is connected to
++            $ref: /schemas/types.yaml#/definitions/phandle
++
++          phy-handle: true
++
++          phy-mode: true
++
++          fixed-link: true
++
++          mac-address: true
++
++          sfp: true
++
++          qca,sgmii-rxclk-falling-edge:
++            $ref: /schemas/types.yaml#/definitions/flag
++            description:
++              Set the receive clock phase to falling edge. Mostly commonly used on
++              the QCA8327 with CPU port 0 set to SGMII.
++
++          qca,sgmii-txclk-falling-edge:
++            $ref: /schemas/types.yaml#/definitions/flag
++            description:
++              Set the transmit clock phase to falling edge.
++
++          qca,sgmii-enable-pll:
++            $ref: /schemas/types.yaml#/definitions/flag
++            description:
++              For SGMII CPU port, explicitly enable PLL, TX and RX chain along with
++              Signal Detection. On the QCA8327 this should not be enabled, otherwise
++              the SGMII port will not initialize. When used on the QCA8337, revision 3
++              or greater, a warning will be displayed. When the CPU port is set to
++              SGMII on the QCA8337, it is advised to set this unless a communication
++              issue is observed.
++
++        required:
++          - reg
++
++        additionalProperties: false
++
++oneOf:
++  - required:
++      - ports
++  - required:
++      - ethernet-ports
++
++required:
++  - compatible
++  - reg
++
++additionalProperties: true
++
++examples:
++  - |
++    #include <dt-bindings/gpio/gpio.h>
++
++    mdio {
++        #address-cells = <1>;
++        #size-cells = <0>;
++
++        external_phy_port1: ethernet-phy@0 {
++            reg = <0>;
++        };
++
++        external_phy_port2: ethernet-phy@1 {
++            reg = <1>;
++        };
++
++        external_phy_port3: ethernet-phy@2 {
++            reg = <2>;
++        };
++
++        external_phy_port4: ethernet-phy@3 {
++            reg = <3>;
++        };
++
++        external_phy_port5: ethernet-phy@4 {
++            reg = <4>;
++        };
++
++        switch@10 {
++            compatible = "qca,qca8337";
++            #address-cells = <1>;
++            #size-cells = <0>;
++            reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
++            reg = <0x10>;
++
++            ports {
++                #address-cells = <1>;
++                #size-cells = <0>;
++
++                port@0 {
++                    reg = <0>;
++                    label = "cpu";
++                    ethernet = <&gmac1>;
++                    phy-mode = "rgmii";
++
++                    fixed-link {
++                        speed = <1000>;
++                        full-duplex;
++                    };
++                };
++
++                port@1 {
++                    reg = <1>;
++                    label = "lan1";
++                    phy-handle = <&external_phy_port1>;
++                };
++
++                port@2 {
++                    reg = <2>;
++                    label = "lan2";
++                    phy-handle = <&external_phy_port2>;
++                };
++
++                port@3 {
++                    reg = <3>;
++                    label = "lan3";
++                    phy-handle = <&external_phy_port3>;
++                };
++
++                port@4 {
++                    reg = <4>;
++                    label = "lan4";
++                    phy-handle = <&external_phy_port4>;
++                };
++
++                port@5 {
++                    reg = <5>;
++                    label = "wan";
++                    phy-handle = <&external_phy_port5>;
++                };
++            };
++        };
++    };
++  - |
++    #include <dt-bindings/gpio/gpio.h>
++
++    mdio {
++        #address-cells = <1>;
++        #size-cells = <0>;
++
++        switch@10 {
++            compatible = "qca,qca8337";
++            #address-cells = <1>;
++            #size-cells = <0>;
++            reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
++            reg = <0x10>;
++
++            ports {
++                #address-cells = <1>;
++                #size-cells = <0>;
++
++                port@0 {
++                    reg = <0>;
++                    label = "cpu";
++                    ethernet = <&gmac1>;
++                    phy-mode = "rgmii";
++
++                    fixed-link {
++                        speed = <1000>;
++                        full-duplex;
++                    };
++                };
++
++                port@1 {
++                    reg = <1>;
++                    label = "lan1";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port1>;
++                };
++
++                port@2 {
++                    reg = <2>;
++                    label = "lan2";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port2>;
++                };
++
++                port@3 {
++                    reg = <3>;
++                    label = "lan3";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port3>;
++                };
++
++                port@4 {
++                    reg = <4>;
++                    label = "lan4";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port4>;
++                };
++
++                port@5 {
++                    reg = <5>;
++                    label = "wan";
++                    phy-mode = "internal";
++                    phy-handle = <&internal_phy_port5>;
++                };
++
++                port@6 {
++                    reg = <0>;
++                    label = "cpu";
++                    ethernet = <&gmac1>;
++                    phy-mode = "sgmii";
++
++                    qca,sgmii-rxclk-falling-edge;
++
++                    fixed-link {
++                        speed = <1000>;
++                        full-duplex;
++                    };
++                };
++            };
++
++            mdio {
++                #address-cells = <1>;
++                #size-cells = <0>;
++
++                internal_phy_port1: ethernet-phy@0 {
++                    reg = <0>;
++                };
++
++                internal_phy_port2: ethernet-phy@1 {
++                    reg = <1>;
++                };
++
++                internal_phy_port3: ethernet-phy@2 {
++                    reg = <2>;
++                };
++
++                internal_phy_port4: ethernet-phy@3 {
++                    reg = <3>;
++                };
++
++                internal_phy_port5: ethernet-phy@4 {
++                    reg = <4>;
++                };
++            };
++        };
++    };
diff --git a/target/linux/generic/backport-5.10/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch b/target/linux/generic/backport-5.10/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch
new file mode 100644 (file)
index 0000000..a510cfd
--- /dev/null
@@ -0,0 +1,28 @@
+From 06dd34a628ae5b6a839b757e746de165d6789ca8 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 17 Oct 2021 16:56:46 +0200
+Subject: net: dsa: qca8k: fix delay applied to wrong cpu in parse_port_config
+
+Fix delay settings applied to wrong cpu in parse_port_config. The delay
+values is set to the wrong index as the cpu_port_index is incremented
+too early. Start the cpu_port_index to -1 so the correct value is
+applied to address also the case with invalid phy mode and not available
+port.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -976,7 +976,7 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
+ static int
+ qca8k_parse_port_config(struct qca8k_priv *priv)
+ {
+-      int port, cpu_port_index = 0, ret;
++      int port, cpu_port_index = -1, ret;
+       struct device_node *port_dn;
+       phy_interface_t mode;
+       struct dsa_port *dp;
diff --git a/target/linux/generic/backport-5.10/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch b/target/linux/generic/backport-5.10/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch
new file mode 100644 (file)
index 0000000..71fa302
--- /dev/null
@@ -0,0 +1,151 @@
+From 040e926f5813a5f4cc18dbff7c942d1e52f368f2 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Tue, 19 Oct 2021 02:08:50 +0200
+Subject: net: dsa: qca8k: tidy for loop in setup and add cpu port check
+
+Tidy and organize qca8k setup function from multiple for loop.
+Change for loop in bridge leave/join to scan all port and skip cpu port.
+No functional change intended.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 74 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 44 insertions(+), 30 deletions(-)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1122,28 +1122,34 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               dev_warn(priv->dev, "mib init failed");
+-      /* Enable QCA header mode on the cpu port */
+-      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
+-                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
+-                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
+-      if (ret) {
+-              dev_err(priv->dev, "failed enabling QCA header mode");
+-              return ret;
+-      }
+-
+-      /* Disable forwarding by default on all ports */
++      /* Initial setup of all ports */
+       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
++              /* Disable forwarding by default on all ports */
+               ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
+                               QCA8K_PORT_LOOKUP_MEMBER, 0);
+               if (ret)
+                       return ret;
+-      }
+-      /* Disable MAC by default on all ports */
+-      for (i = 1; i < QCA8K_NUM_PORTS; i++)
+-              qca8k_port_set_status(priv, i, 0);
++              /* Enable QCA header mode on all cpu ports */
++              if (dsa_is_cpu_port(ds, i)) {
++                      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
++                                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
++                                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
++                      if (ret) {
++                              dev_err(priv->dev, "failed enabling QCA header mode");
++                              return ret;
++                      }
++              }
++
++              /* Disable MAC by default on all user ports */
++              if (dsa_is_user_port(ds, i))
++                      qca8k_port_set_status(priv, i, 0);
++      }
+-      /* Forward all unknown frames to CPU port for Linux processing */
++      /* Forward all unknown frames to CPU port for Linux processing
++       * Notice that in multi-cpu config only one port should be set
++       * for igmp, unknown, multicast and broadcast packet
++       */
+       ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
+                         BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
+                         BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
+@@ -1152,11 +1158,13 @@ qca8k_setup(struct dsa_switch *ds)
+       if (ret)
+               return ret;
+-      /* Setup connection between CPU port & user ports */
++      /* Setup connection between CPU port & user ports
++       * Configure specific switch configuration for ports
++       */
+       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+               /* CPU port gets connected to all user ports of the switch */
+               if (dsa_is_cpu_port(ds, i)) {
+-                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
++                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
+                                       QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
+                       if (ret)
+                               return ret;
+@@ -1193,16 +1201,14 @@ qca8k_setup(struct dsa_switch *ds)
+                       if (ret)
+                               return ret;
+               }
+-      }
+-      /* The port 5 of the qca8337 have some problem in flood condition. The
+-       * original legacy driver had some specific buffer and priority settings
+-       * for the different port suggested by the QCA switch team. Add this
+-       * missing settings to improve switch stability under load condition.
+-       * This problem is limited to qca8337 and other qca8k switch are not affected.
+-       */
+-      if (priv->switch_id == QCA8K_ID_QCA8337) {
+-              for (i = 0; i < QCA8K_NUM_PORTS; i++) {
++              /* The port 5 of the qca8337 have some problem in flood condition. The
++               * original legacy driver had some specific buffer and priority settings
++               * for the different port suggested by the QCA switch team. Add this
++               * missing settings to improve switch stability under load condition.
++               * This problem is limited to qca8337 and other qca8k switch are not affected.
++               */
++              if (priv->switch_id == QCA8K_ID_QCA8337) {
+                       switch (i) {
+                       /* The 2 CPU port and port 5 requires some different
+                        * priority than any other ports.
+@@ -1238,6 +1244,12 @@ qca8k_setup(struct dsa_switch *ds)
+                                 QCA8K_PORT_HOL_CTRL1_WRED_EN,
+                                 mask);
+               }
++
++              /* Set initial MTU for every port.
++               * We have only have a general MTU setting. So track
++               * every port and set the max across all port.
++               */
++              priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+       }
+       /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
+@@ -1251,8 +1263,6 @@ qca8k_setup(struct dsa_switch *ds)
+       }
+       /* Setup our port MTUs to match power on defaults */
+-      for (i = 0; i < QCA8K_NUM_PORTS; i++)
+-              priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+       ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
+       if (ret)
+               dev_warn(priv->dev, "failed setting MTU settings");
+@@ -1728,7 +1738,9 @@ qca8k_port_bridge_join(struct dsa_switch
+       cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
+       port_mask = BIT(cpu_port);
+-      for (i = 1; i < QCA8K_NUM_PORTS; i++) {
++      for (i = 0; i < QCA8K_NUM_PORTS; i++) {
++              if (dsa_is_cpu_port(ds, i))
++                      continue;
+               if (dsa_to_port(ds, i)->bridge_dev != br)
+                       continue;
+               /* Add this port to the portvlan mask of the other ports
+@@ -1758,7 +1770,9 @@ qca8k_port_bridge_leave(struct dsa_switc
+       cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
+-      for (i = 1; i < QCA8K_NUM_PORTS; i++) {
++      for (i = 0; i < QCA8K_NUM_PORTS; i++) {
++              if (dsa_is_cpu_port(ds, i))
++                      continue;
+               if (dsa_to_port(ds, i)->bridge_dev != br)
+                       continue;
+               /* Remove this port to the portvlan mask of the other ports
diff --git a/target/linux/generic/backport-5.10/765-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch b/target/linux/generic/backport-5.10/765-v5.12-net-dsa-automatically-bring-up-DSA-master-when-openi.patch
deleted file mode 100644 (file)
index 3b63037..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From 9d5ef190e5615a7b63af89f88c4106a5bc127974 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Fri, 5 Feb 2021 15:37:10 +0200
-Subject: [PATCH] net: dsa: automatically bring up DSA master when opening user
- port
-
-DSA wants the master interface to be open before the user port is due to
-historical reasons. The promiscuity of interfaces that are down used to
-have issues, as referenced Lennert Buytenhek in commit df02c6ff2e39
-("dsa: fix master interface allmulti/promisc handling").
-
-The bugfix mentioned there, commit b6c40d68ff64 ("net: only invoke
-dev->change_rx_flags when device is UP"), was basically a "don't do
-that" approach to working around the promiscuity while down issue.
-
-Further work done by Vlad Yasevich in commit d2615bf45069 ("net: core:
-Always propagate flag changes to interfaces") has resolved the
-underlying issue, and it is strictly up to the DSA and 8021q drivers
-now, it is no longer mandated by the networking core that the master
-interface must be up when changing its promiscuity.
-
-From DSA's point of view, deciding to error out in dsa_slave_open
-because the master isn't up is
-(a) a bad user experience and
-(b) knocking at an open door.
-Even if there still was an issue with promiscuity while down, DSA could
-still just open the master and avoid it.
-
-Doing it this way has the additional benefit that user space can now
-remove DSA-specific workarounds, like systemd-networkd with BindCarrier:
-https://github.com/systemd/systemd/issues/7478
-
-And we can finally remove one of the 2 bullets in the "Common pitfalls
-using DSA setups" chapter.
-
-Tested with two cascaded DSA switches:
-
-$ ip link set sw0p2 up
-fsl_enetc 0000:00:00.2 eno2: configuring for fixed/internal link mode
-fsl_enetc 0000:00:00.2 eno2: Link is Up - 1Gbps/Full - flow control rx/tx
-mscc_felix 0000:00:00.5 swp0: configuring for fixed/sgmii link mode
-mscc_felix 0000:00:00.5 swp0: Link is Up - 1Gbps/Full - flow control off
-8021q: adding VLAN 0 to HW filter on device swp0
-sja1105 spi2.0 sw0p2: configuring for phy/rgmii-id link mode
-IPv6: ADDRCONF(NETDEV_CHANGE): eno2: link becomes ready
-IPv6: ADDRCONF(NETDEV_CHANGE): swp0: link becomes ready
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- Documentation/networking/dsa/dsa.rst | 4 ----
- net/dsa/slave.c                      | 7 +++++--
- 2 files changed, 5 insertions(+), 6 deletions(-)
-
---- a/Documentation/networking/dsa/dsa.rst
-+++ b/Documentation/networking/dsa/dsa.rst
-@@ -273,10 +273,6 @@ will not make us go through the switch t
- the Ethernet switch on the other end, expecting a tag will typically drop this
- frame.
--Slave network devices check that the master network device is UP before allowing
--you to administratively bring UP these slave network devices. A common
--configuration mistake is forgetting to bring UP the master network device first.
--
- Interactions with other subsystems
- ==================================
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -68,8 +68,11 @@ static int dsa_slave_open(struct net_dev
-       struct dsa_port *dp = dsa_slave_to_port(dev);
-       int err;
--      if (!(master->flags & IFF_UP))
--              return -ENETDOWN;
-+      err = dev_open(master, NULL);
-+      if (err < 0) {
-+              netdev_err(dev, "failed to open master %s\n", master->name);
-+              goto out;
-+      }
-       if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) {
-               err = dev_uc_add(master, dev->dev_addr);
diff --git a/target/linux/generic/backport-5.10/770-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch b/target/linux/generic/backport-5.10/770-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch
deleted file mode 100644 (file)
index c43cb4d..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-From 90dc8fd36078a536671adae884d0b929cce6480a Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 6 Jan 2021 11:51:30 +0200
-Subject: [PATCH] net: bridge: notify switchdev of disappearance of old FDB
- entry upon migration
-
-Currently the bridge emits atomic switchdev notifications for
-dynamically learnt FDB entries. Monitoring these notifications works
-wonders for switchdev drivers that want to keep their hardware FDB in
-sync with the bridge's FDB.
-
-For example station A wants to talk to station B in the diagram below,
-and we are concerned with the behavior of the bridge on the DUT device:
-
-                   DUT
- +-------------------------------------+
- |                 br0                 |
- | +------+ +------+ +------+ +------+ |
- | |      | |      | |      | |      | |
- | | swp0 | | swp1 | | swp2 | | eth0 | |
- +-------------------------------------+
-      |        |                  |
-  Station A    |                  |
-               |                  |
-         +--+------+--+    +--+------+--+
-         |  |      |  |    |  |      |  |
-         |  | swp0 |  |    |  | swp0 |  |
- Another |  +------+  |    |  +------+  | Another
-  switch |     br0    |    |     br0    | switch
-         |  +------+  |    |  +------+  |
-         |  |      |  |    |  |      |  |
-         |  | swp1 |  |    |  | swp1 |  |
-         +--+------+--+    +--+------+--+
-                                  |
-                              Station B
-
-Interfaces swp0, swp1, swp2 are handled by a switchdev driver that has
-the following property: frames injected from its control interface bypass
-the internal address analyzer logic, and therefore, this hardware does
-not learn from the source address of packets transmitted by the network
-stack through it. So, since bridging between eth0 (where Station B is
-attached) and swp0 (where Station A is attached) is done in software,
-the switchdev hardware will never learn the source address of Station B.
-So the traffic towards that destination will be treated as unknown, i.e.
-flooded.
-
-This is where the bridge notifications come in handy. When br0 on the
-DUT sees frames with Station B's MAC address on eth0, the switchdev
-driver gets these notifications and can install a rule to send frames
-towards Station B's address that are incoming from swp0, swp1, swp2,
-only towards the control interface. This is all switchdev driver private
-business, which the notification makes possible.
-
-All is fine until someone unplugs Station B's cable and moves it to the
-other switch:
-
-                   DUT
- +-------------------------------------+
- |                 br0                 |
- | +------+ +------+ +------+ +------+ |
- | |      | |      | |      | |      | |
- | | swp0 | | swp1 | | swp2 | | eth0 | |
- +-------------------------------------+
-      |        |                  |
-  Station A    |                  |
-               |                  |
-         +--+------+--+    +--+------+--+
-         |  |      |  |    |  |      |  |
-         |  | swp0 |  |    |  | swp0 |  |
- Another |  +------+  |    |  +------+  | Another
-  switch |     br0    |    |     br0    | switch
-         |  +------+  |    |  +------+  |
-         |  |      |  |    |  |      |  |
-         |  | swp1 |  |    |  | swp1 |  |
-         +--+------+--+    +--+------+--+
-               |
-           Station B
-
-Luckily for the use cases we care about, Station B is noisy enough that
-the DUT hears it (on swp1 this time). swp1 receives the frames and
-delivers them to the bridge, who enters the unlikely path in br_fdb_update
-of updating an existing entry. It moves the entry in the software bridge
-to swp1 and emits an addition notification towards that.
-
-As far as the switchdev driver is concerned, all that it needs to ensure
-is that traffic between Station A and Station B is not forever broken.
-If it does nothing, then the stale rule to send frames for Station B
-towards the control interface remains in place. But Station B is no
-longer reachable via the control interface, but via a port that can
-offload the bridge port learning attribute. It's just that the port is
-prevented from learning this address, since the rule overrides FDB
-updates. So the rule needs to go. The question is via what mechanism.
-
-It sure would be possible for this switchdev driver to keep track of all
-addresses which are sent to the control interface, and then also listen
-for bridge notifier events on its own ports, searching for the ones that
-have a MAC address which was previously sent to the control interface.
-But this is cumbersome and inefficient. Instead, with one small change,
-the bridge could notify of the address deletion from the old port, in a
-symmetrical manner with how it did for the insertion. Then the switchdev
-driver would not be required to monitor learn/forget events for its own
-ports. It could just delete the rule towards the control interface upon
-bridge entry migration. This would make hardware address learning be
-possible again. Then it would take a few more packets until the hardware
-and software FDB would be in sync again.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
-Reviewed-by: Ido Schimmel <idosch@nvidia.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/bridge/br_fdb.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/net/bridge/br_fdb.c
-+++ b/net/bridge/br_fdb.c
-@@ -602,6 +602,7 @@ void br_fdb_update(struct net_bridge *br
-                       /* fastpath: update of existing entry */
-                       if (unlikely(source != fdb->dst &&
-                                    !test_bit(BR_FDB_STICKY, &fdb->flags))) {
-+                              br_switchdev_fdb_notify(fdb, RTM_DELNEIGH);
-                               fdb->dst = source;
-                               fdb_modified = true;
-                               /* Take over HW learned entry */
diff --git a/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch b/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch
deleted file mode 100644 (file)
index f933759..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From 2fd186501b1cff155cc4a755c210793cfc0dffb5 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 6 Jan 2021 11:51:31 +0200
-Subject: [PATCH] net: dsa: be louder when a non-legacy FDB operation fails
-
-The dev_close() call was added in commit c9eb3e0f8701 ("net: dsa: Add
-support for learning FDB through notification") "to indicate inconsistent
-situation" when we could not delete an FDB entry from the port.
-
-bridge fdb del d8:58:d7:00:ca:6d dev swp0 self master
-
-It is a bit drastic and at the same time not helpful if the above fails
-to only print with netdev_dbg log level, but on the other hand to bring
-the interface down.
-
-So increase the verbosity of the error message, and drop dev_close().
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/dsa/slave.c | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
-
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -2112,7 +2112,9 @@ static void dsa_slave_switchdev_event_wo
-               err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid);
-               if (err) {
--                      netdev_dbg(dev, "fdb add failed err=%d\n", err);
-+                      netdev_err(dev,
-+                                 "failed to add %pM vid %d to fdb: %d\n",
-+                                 fdb_info->addr, fdb_info->vid, err);
-                       break;
-               }
-               fdb_info->offloaded = true;
-@@ -2127,9 +2129,11 @@ static void dsa_slave_switchdev_event_wo
-               err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid);
-               if (err) {
--                      netdev_dbg(dev, "fdb del failed err=%d\n", err);
--                      dev_close(dev);
-+                      netdev_err(dev,
-+                                 "failed to delete %pM vid %d from fdb: %d\n",
-+                                 fdb_info->addr, fdb_info->vid, err);
-               }
-+
-               break;
-       }
-       rtnl_unlock();
diff --git a/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch b/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch
deleted file mode 100644 (file)
index c1aa8fd..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-From c4bb76a9a0ef87c4cc1f636defed5f12deb9f5a7 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 6 Jan 2021 11:51:32 +0200
-Subject: [PATCH] net: dsa: don't use switchdev_notifier_fdb_info in
- dsa_switchdev_event_work
-
-Currently DSA doesn't add FDB entries on the CPU port, because it only
-does so through switchdev, which is associated with a net_device, and
-there are none of those for the CPU port.
-
-But actually FDB addresses on the CPU port have some use cases of their
-own, if the switchdev operations are initiated from within the DSA
-layer. There is just one problem with the existing code: it passes a
-structure in dsa_switchdev_event_work which was retrieved directly from
-switchdev, so it contains a net_device. We need to generalize the
-contents to something that covers the CPU port as well: the "ds, port"
-tuple is fine for that.
-
-Note that the new procedure for notifying the successful FDB offload is
-inspired from the rocker model.
-
-Also, nothing was being done if added_by_user was false. Let's check for
-that a lot earlier, and don't actually bother to schedule the worker
-for nothing.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/dsa/dsa_priv.h |  12 +++++
- net/dsa/slave.c    | 106 ++++++++++++++++++++++-----------------------
- 2 files changed, 65 insertions(+), 53 deletions(-)
-
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -73,6 +73,18 @@ struct dsa_notifier_mtu_info {
-       int mtu;
- };
-+struct dsa_switchdev_event_work {
-+      struct dsa_switch *ds;
-+      int port;
-+      struct work_struct work;
-+      unsigned long event;
-+      /* Specific for SWITCHDEV_FDB_ADD_TO_DEVICE and
-+       * SWITCHDEV_FDB_DEL_TO_DEVICE
-+       */
-+      unsigned char addr[ETH_ALEN];
-+      u16 vid;
-+};
-+
- struct dsa_slave_priv {
-       /* Copy of CPU port xmit for faster access in slave transmit hot path */
-       struct sk_buff *        (*xmit)(struct sk_buff *skb,
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -2087,76 +2087,66 @@ static int dsa_slave_netdevice_event(str
-       return NOTIFY_DONE;
- }
--struct dsa_switchdev_event_work {
--      struct work_struct work;
--      struct switchdev_notifier_fdb_info fdb_info;
--      struct net_device *dev;
--      unsigned long event;
--};
-+static void
-+dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work)
-+{
-+      struct dsa_switch *ds = switchdev_work->ds;
-+      struct switchdev_notifier_fdb_info info;
-+      struct dsa_port *dp;
-+
-+      if (!dsa_is_user_port(ds, switchdev_work->port))
-+              return;
-+
-+      info.addr = switchdev_work->addr;
-+      info.vid = switchdev_work->vid;
-+      info.offloaded = true;
-+      dp = dsa_to_port(ds, switchdev_work->port);
-+      call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED,
-+                               dp->slave, &info.info, NULL);
-+}
- static void dsa_slave_switchdev_event_work(struct work_struct *work)
- {
-       struct dsa_switchdev_event_work *switchdev_work =
-               container_of(work, struct dsa_switchdev_event_work, work);
--      struct net_device *dev = switchdev_work->dev;
--      struct switchdev_notifier_fdb_info *fdb_info;
--      struct dsa_port *dp = dsa_slave_to_port(dev);
-+      struct dsa_switch *ds = switchdev_work->ds;
-+      struct dsa_port *dp;
-       int err;
-+      dp = dsa_to_port(ds, switchdev_work->port);
-+
-       rtnl_lock();
-       switch (switchdev_work->event) {
-       case SWITCHDEV_FDB_ADD_TO_DEVICE:
--              fdb_info = &switchdev_work->fdb_info;
--              if (!fdb_info->added_by_user)
--                      break;
--
--              err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid);
-+              err = dsa_port_fdb_add(dp, switchdev_work->addr,
-+                                     switchdev_work->vid);
-               if (err) {
--                      netdev_err(dev,
--                                 "failed to add %pM vid %d to fdb: %d\n",
--                                 fdb_info->addr, fdb_info->vid, err);
-+                      dev_err(ds->dev,
-+                              "port %d failed to add %pM vid %d to fdb: %d\n",
-+                              dp->index, switchdev_work->addr,
-+                              switchdev_work->vid, err);
-                       break;
-               }
--              fdb_info->offloaded = true;
--              call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, dev,
--                                       &fdb_info->info, NULL);
-+              dsa_fdb_offload_notify(switchdev_work);
-               break;
-       case SWITCHDEV_FDB_DEL_TO_DEVICE:
--              fdb_info = &switchdev_work->fdb_info;
--              if (!fdb_info->added_by_user)
--                      break;
--
--              err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid);
-+              err = dsa_port_fdb_del(dp, switchdev_work->addr,
-+                                     switchdev_work->vid);
-               if (err) {
--                      netdev_err(dev,
--                                 "failed to delete %pM vid %d from fdb: %d\n",
--                                 fdb_info->addr, fdb_info->vid, err);
-+                      dev_err(ds->dev,
-+                              "port %d failed to delete %pM vid %d from fdb: %d\n",
-+                              dp->index, switchdev_work->addr,
-+                              switchdev_work->vid, err);
-               }
-               break;
-       }
-       rtnl_unlock();
--      kfree(switchdev_work->fdb_info.addr);
-       kfree(switchdev_work);
--      dev_put(dev);
--}
--
--static int
--dsa_slave_switchdev_fdb_work_init(struct dsa_switchdev_event_work *
--                                switchdev_work,
--                                const struct switchdev_notifier_fdb_info *
--                                fdb_info)
--{
--      memcpy(&switchdev_work->fdb_info, fdb_info,
--             sizeof(switchdev_work->fdb_info));
--      switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
--      if (!switchdev_work->fdb_info.addr)
--              return -ENOMEM;
--      ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
--                      fdb_info->addr);
--      return 0;
-+      if (dsa_is_user_port(ds, dp->index))
-+              dev_put(dp->slave);
- }
- /* Called under rcu_read_lock() */
-@@ -2164,7 +2154,9 @@ static int dsa_slave_switchdev_event(str
-                                    unsigned long event, void *ptr)
- {
-       struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
-+      const struct switchdev_notifier_fdb_info *fdb_info;
-       struct dsa_switchdev_event_work *switchdev_work;
-+      struct dsa_port *dp;
-       int err;
-       if (event == SWITCHDEV_PORT_ATTR_SET) {
-@@ -2177,20 +2169,32 @@ static int dsa_slave_switchdev_event(str
-       if (!dsa_slave_dev_check(dev))
-               return NOTIFY_DONE;
-+      dp = dsa_slave_to_port(dev);
-+
-       switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
-       if (!switchdev_work)
-               return NOTIFY_BAD;
-       INIT_WORK(&switchdev_work->work,
-                 dsa_slave_switchdev_event_work);
--      switchdev_work->dev = dev;
-+      switchdev_work->ds = dp->ds;
-+      switchdev_work->port = dp->index;
-       switchdev_work->event = event;
-       switch (event) {
-       case SWITCHDEV_FDB_ADD_TO_DEVICE:
-       case SWITCHDEV_FDB_DEL_TO_DEVICE:
--              if (dsa_slave_switchdev_fdb_work_init(switchdev_work, ptr))
--                      goto err_fdb_work_init;
-+              fdb_info = ptr;
-+
-+              if (!fdb_info->added_by_user) {
-+                      kfree(switchdev_work);
-+                      return NOTIFY_OK;
-+              }
-+
-+              ether_addr_copy(switchdev_work->addr,
-+                              fdb_info->addr);
-+              switchdev_work->vid = fdb_info->vid;
-+
-               dev_hold(dev);
-               break;
-       default:
-@@ -2200,10 +2204,6 @@ static int dsa_slave_switchdev_event(str
-       dsa_schedule_work(&switchdev_work->work);
-       return NOTIFY_OK;
--
--err_fdb_work_init:
--      kfree(switchdev_work);
--      return NOTIFY_BAD;
- }
- static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
diff --git a/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch b/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch
deleted file mode 100644 (file)
index 9131df7..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From 447d290a58bd335d68f665713842365d3d6447df Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 6 Jan 2021 11:51:33 +0200
-Subject: [PATCH] net: dsa: move switchdev event implementation under the same
- switch/case statement
-
-We'll need to start listening to SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE
-events even for interfaces where dsa_slave_dev_check returns false, so
-we need that check inside the switch-case statement for SWITCHDEV_FDB_*.
-
-This movement also avoids a useless allocation / free of switchdev_work
-on the untreated "default event" case.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/dsa/slave.c | 35 ++++++++++++++++-------------------
- 1 file changed, 16 insertions(+), 19 deletions(-)
-
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -2159,31 +2159,29 @@ static int dsa_slave_switchdev_event(str
-       struct dsa_port *dp;
-       int err;
--      if (event == SWITCHDEV_PORT_ATTR_SET) {
-+      switch (event) {
-+      case SWITCHDEV_PORT_ATTR_SET:
-               err = switchdev_handle_port_attr_set(dev, ptr,
-                                                    dsa_slave_dev_check,
-                                                    dsa_slave_port_attr_set);
-               return notifier_from_errno(err);
--      }
--
--      if (!dsa_slave_dev_check(dev))
--              return NOTIFY_DONE;
-+      case SWITCHDEV_FDB_ADD_TO_DEVICE:
-+      case SWITCHDEV_FDB_DEL_TO_DEVICE:
-+              if (!dsa_slave_dev_check(dev))
-+                      return NOTIFY_DONE;
--      dp = dsa_slave_to_port(dev);
-+              dp = dsa_slave_to_port(dev);
--      switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
--      if (!switchdev_work)
--              return NOTIFY_BAD;
--
--      INIT_WORK(&switchdev_work->work,
--                dsa_slave_switchdev_event_work);
--      switchdev_work->ds = dp->ds;
--      switchdev_work->port = dp->index;
--      switchdev_work->event = event;
-+              switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
-+              if (!switchdev_work)
-+                      return NOTIFY_BAD;
-+
-+              INIT_WORK(&switchdev_work->work,
-+                        dsa_slave_switchdev_event_work);
-+              switchdev_work->ds = dp->ds;
-+              switchdev_work->port = dp->index;
-+              switchdev_work->event = event;
--      switch (event) {
--      case SWITCHDEV_FDB_ADD_TO_DEVICE:
--      case SWITCHDEV_FDB_DEL_TO_DEVICE:
-               fdb_info = ptr;
-               if (!fdb_info->added_by_user) {
-@@ -2196,13 +2194,12 @@ static int dsa_slave_switchdev_event(str
-               switchdev_work->vid = fdb_info->vid;
-               dev_hold(dev);
-+              dsa_schedule_work(&switchdev_work->work);
-               break;
-       default:
--              kfree(switchdev_work);
-               return NOTIFY_DONE;
-       }
--      dsa_schedule_work(&switchdev_work->work);
-       return NOTIFY_OK;
- }
diff --git a/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch b/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch
deleted file mode 100644 (file)
index b7b6ebe..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From 5fb4a451a87d8ed3363d28b63a3295399373d6c4 Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 6 Jan 2021 11:51:34 +0200
-Subject: [PATCH] net: dsa: exit early in dsa_slave_switchdev_event if we can't
- program the FDB
-
-Right now, the following would happen for a switch driver that does not
-implement .port_fdb_add or .port_fdb_del.
-
-dsa_slave_switchdev_event returns NOTIFY_OK and schedules:
--> dsa_slave_switchdev_event_work
-   -> dsa_port_fdb_add
-      -> dsa_port_notify(DSA_NOTIFIER_FDB_ADD)
-         -> dsa_switch_fdb_add
-            -> if (!ds->ops->port_fdb_add) return -EOPNOTSUPP;
-   -> an error is printed with dev_dbg, and
-      dsa_fdb_offload_notify(switchdev_work) is not called.
-
-We can avoid scheduling the worker for nothing and say NOTIFY_DONE.
-Because we don't call dsa_fdb_offload_notify, the static FDB entry will
-remain just in the software bridge.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/dsa/slave.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -2172,6 +2172,9 @@ static int dsa_slave_switchdev_event(str
-               dp = dsa_slave_to_port(dev);
-+              if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del)
-+                      return NOTIFY_DONE;
-+
-               switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
-               if (!switchdev_work)
-                       return NOTIFY_BAD;
diff --git a/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch b/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch
deleted file mode 100644 (file)
index e7b9af1..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-From d5f19486cee79d04c054427577ac96ed123706db Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Wed, 6 Jan 2021 11:51:35 +0200
-Subject: [PATCH] net: dsa: listen for SWITCHDEV_{FDB,DEL}_ADD_TO_DEVICE on
- foreign bridge neighbors
-
-Some DSA switches (and not only) cannot learn source MAC addresses from
-packets injected from the CPU. They only perform hardware address
-learning from inbound traffic.
-
-This can be problematic when we have a bridge spanning some DSA switch
-ports and some non-DSA ports (which we'll call "foreign interfaces" from
-DSA's perspective).
-
-There are 2 classes of problems created by the lack of learning on
-CPU-injected traffic:
-- excessive flooding, due to the fact that DSA treats those addresses as
-  unknown
-- the risk of stale routes, which can lead to temporary packet loss
-
-To illustrate the second class, consider the following situation, which
-is common in production equipment (wireless access points, where there
-is a WLAN interface and an Ethernet switch, and these form a single
-bridging domain).
-
- AP 1:
- +------------------------------------------------------------------------+
- |                                          br0                           |
- +------------------------------------------------------------------------+
- +------------+ +------------+ +------------+ +------------+ +------------+
- |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
- +------------+ +------------+ +------------+ +------------+ +------------+
-       |                                                       ^        ^
-       |                                                       |        |
-       |                                                       |        |
-       |                                                    Client A  Client B
-       |
-       |
-       |
- +------------+ +------------+ +------------+ +------------+ +------------+
- |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
- +------------+ +------------+ +------------+ +------------+ +------------+
- +------------------------------------------------------------------------+
- |                                          br0                           |
- +------------------------------------------------------------------------+
- AP 2
-
-- br0 of AP 1 will know that Clients A and B are reachable via wlan0
-- the hardware fdb of a DSA switch driver today is not kept in sync with
-  the software entries on other bridge ports, so it will not know that
-  clients A and B are reachable via the CPU port UNLESS the hardware
-  switch itself performs SA learning from traffic injected from the CPU.
-  Nonetheless, a substantial number of switches don't.
-- the hardware fdb of the DSA switch on AP 2 may autonomously learn that
-  Client A and B are reachable through swp0. Therefore, the software br0
-  of AP 2 also may or may not learn this. In the example we're
-  illustrating, some Ethernet traffic has been going on, and br0 from AP
-  2 has indeed learnt that it can reach Client B through swp0.
-
-One of the wireless clients, say Client B, disconnects from AP 1 and
-roams to AP 2. The topology now looks like this:
-
- AP 1:
- +------------------------------------------------------------------------+
- |                                          br0                           |
- +------------------------------------------------------------------------+
- +------------+ +------------+ +------------+ +------------+ +------------+
- |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
- +------------+ +------------+ +------------+ +------------+ +------------+
-       |                                                            ^
-       |                                                            |
-       |                                                         Client A
-       |
-       |
-       |                                                         Client B
-       |                                                            |
-       |                                                            v
- +------------+ +------------+ +------------+ +------------+ +------------+
- |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
- +------------+ +------------+ +------------+ +------------+ +------------+
- +------------------------------------------------------------------------+
- |                                          br0                           |
- +------------------------------------------------------------------------+
- AP 2
-
-- br0 of AP 1 still knows that Client A is reachable via wlan0 (no change)
-- br0 of AP 1 will (possibly) know that Client B has left wlan0. There
-  are cases where it might never find out though. Either way, DSA today
-  does not process that notification in any way.
-- the hardware FDB of the DSA switch on AP 1 may learn autonomously that
-  Client B can be reached via swp0, if it receives any packet with
-  Client 1's source MAC address over Ethernet.
-- the hardware FDB of the DSA switch on AP 2 still thinks that Client B
-  can be reached via swp0. It does not know that it has roamed to wlan0,
-  because it doesn't perform SA learning from the CPU port.
-
-Now Client A contacts Client B.
-AP 1 routes the packet fine towards swp0 and delivers it on the Ethernet
-segment.
-AP 2 sees a frame on swp0 and its fdb says that the destination is swp0.
-Hairpinning is disabled => drop.
-
-This problem comes from the fact that these switches have a 'blind spot'
-for addresses coming from software bridging. The generic solution is not
-to assume that hardware learning can be enabled somehow, but to listen
-to more bridge learning events. It turns out that the bridge driver does
-learn in software from all inbound frames, in __br_handle_local_finish.
-A proper SWITCHDEV_FDB_ADD_TO_DEVICE notification is emitted for the
-addresses serviced by the bridge on 'foreign' interfaces. The software
-bridge also does the right thing on migration, by notifying that the old
-entry is deleted, so that does not need to be special-cased in DSA. When
-it is deleted, we just need to delete our static FDB entry towards the
-CPU too, and wait.
-
-The problem is that DSA currently only cares about SWITCHDEV_FDB_ADD_TO_DEVICE
-events received on its own interfaces, such as static FDB entries.
-
-Luckily we can change that, and DSA can listen to all switchdev FDB
-add/del events in the system and figure out if those events were emitted
-by a bridge that spans at least one of DSA's own ports. In case that is
-true, DSA will also offload that address towards its own CPU port, in
-the eventuality that there might be bridge clients attached to the DSA
-switch who want to talk to the station connected to the foreign
-interface.
-
-In terms of implementation, we need to keep the fdb_info->added_by_user
-check for the case where the switchdev event was targeted directly at a
-DSA switch port. But we don't need to look at that flag for snooped
-events. So the check is currently too late, we need to move it earlier.
-This also simplifies the code a bit, since we avoid uselessly allocating
-and freeing switchdev_work.
-
-We could probably do some improvements in the future. For example,
-multi-bridge support is rudimentary at the moment. If there are two
-bridges spanning a DSA switch's ports, and both of them need to service
-the same MAC address, then what will happen is that the migration of one
-of those stations will trigger the deletion of the FDB entry from the
-CPU port while it is still used by other bridge. That could be improved
-with reference counting but is left for another time.
-
-This behavior needs to be enabled at driver level by setting
-ds->assisted_learning_on_cpu_port = true. This is because we don't want
-to inflict a potential performance penalty (accesses through
-MDIO/I2C/SPI are expensive) to hardware that really doesn't need it
-because address learning on the CPU port works there.
-
-Reported-by: DENG Qingfang <dqfext@gmail.com>
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- include/net/dsa.h |  5 +++++
- net/dsa/slave.c   | 66 +++++++++++++++++++++++++++++++++++++++++++++----------
- 2 files changed, 60 insertions(+), 11 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -317,6 +317,11 @@ struct dsa_switch {
-        */
-       bool                    untag_bridge_pvid;
-+      /* Let DSA manage the FDB entries towards the CPU, based on the
-+       * software bridge database.
-+       */
-+      bool                    assisted_learning_on_cpu_port;
-+
-       /* In case vlan_filtering_is_global is set, the VLAN awareness state
-        * should be retrieved from here and not from the per-port settings.
-        */
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -2149,6 +2149,28 @@ static void dsa_slave_switchdev_event_wo
-               dev_put(dp->slave);
- }
-+static int dsa_lower_dev_walk(struct net_device *lower_dev,
-+                            struct netdev_nested_priv *priv)
-+{
-+      if (dsa_slave_dev_check(lower_dev)) {
-+              priv->data = (void *)netdev_priv(lower_dev);
-+              return 1;
-+      }
-+
-+      return 0;
-+}
-+
-+static struct dsa_slave_priv *dsa_slave_dev_lower_find(struct net_device *dev)
-+{
-+      struct netdev_nested_priv priv = {
-+              .data = NULL,
-+      };
-+
-+      netdev_walk_all_lower_dev_rcu(dev, dsa_lower_dev_walk, &priv);
-+
-+      return (struct dsa_slave_priv *)priv.data;
-+}
-+
- /* Called under rcu_read_lock() */
- static int dsa_slave_switchdev_event(struct notifier_block *unused,
-                                    unsigned long event, void *ptr)
-@@ -2167,10 +2189,37 @@ static int dsa_slave_switchdev_event(str
-               return notifier_from_errno(err);
-       case SWITCHDEV_FDB_ADD_TO_DEVICE:
-       case SWITCHDEV_FDB_DEL_TO_DEVICE:
--              if (!dsa_slave_dev_check(dev))
--                      return NOTIFY_DONE;
-+              fdb_info = ptr;
-+
-+              if (dsa_slave_dev_check(dev)) {
-+                      if (!fdb_info->added_by_user)
-+                              return NOTIFY_OK;
-+
-+                      dp = dsa_slave_to_port(dev);
-+              } else {
-+                      /* Snoop addresses learnt on foreign interfaces
-+                       * bridged with us, for switches that don't
-+                       * automatically learn SA from CPU-injected traffic
-+                       */
-+                      struct net_device *br_dev;
-+                      struct dsa_slave_priv *p;
-+
-+                      br_dev = netdev_master_upper_dev_get_rcu(dev);
-+                      if (!br_dev)
-+                              return NOTIFY_DONE;
-+
-+                      if (!netif_is_bridge_master(br_dev))
-+                              return NOTIFY_DONE;
-+
-+                      p = dsa_slave_dev_lower_find(br_dev);
-+                      if (!p)
-+                              return NOTIFY_DONE;
--              dp = dsa_slave_to_port(dev);
-+                      dp = p->dp->cpu_dp;
-+
-+                      if (!dp->ds->assisted_learning_on_cpu_port)
-+                              return NOTIFY_DONE;
-+              }
-               if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del)
-                       return NOTIFY_DONE;
-@@ -2185,18 +2234,13 @@ static int dsa_slave_switchdev_event(str
-               switchdev_work->port = dp->index;
-               switchdev_work->event = event;
--              fdb_info = ptr;
--
--              if (!fdb_info->added_by_user) {
--                      kfree(switchdev_work);
--                      return NOTIFY_OK;
--              }
--
-               ether_addr_copy(switchdev_work->addr,
-                               fdb_info->addr);
-               switchdev_work->vid = fdb_info->vid;
--              dev_hold(dev);
-+              /* Hold a reference on the slave for dsa_fdb_offload_notify */
-+              if (dsa_is_user_port(dp->ds, dp->index))
-+                      dev_hold(dev);
-               dsa_schedule_work(&switchdev_work->work);
-               break;
-       default:
diff --git a/target/linux/generic/backport-5.10/780-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch b/target/linux/generic/backport-5.10/780-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch
deleted file mode 100644 (file)
index f3a6f94..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-From c3b8e07909dbe67b0d580416c1a5257643a73be7 Mon Sep 17 00:00:00 2001
-From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Date: Fri, 12 Mar 2021 00:07:03 -0800
-Subject: [PATCH] net: dsa: mt7530: setup core clock even in TRGMII mode
-
-A recent change to MIPS ralink reset logic made it so mt7530 actually
-resets the switch on platforms such as mt7621 (where bit 2 is the reset
-line for the switch). That exposed an issue where the switch would not
-function properly in TRGMII mode after a reset.
-
-Reconfigure core clock in TRGMII mode to fix the issue.
-
-Tested on Ubiquiti ER-X (MT7621) with TRGMII mode enabled.
-
-Fixes: 3f9ef7785a9c ("MIPS: ralink: manage low reset lines")
-Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 52 +++++++++++++++++++---------------------
- 1 file changed, 25 insertions(+), 27 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -436,34 +436,32 @@ mt7530_pad_clk_setup(struct dsa_switch *
-                            TD_DM_DRVP(8) | TD_DM_DRVN(8));
-       /* Setup core clock for MT7530 */
--      if (!trgint) {
--              /* Disable MT7530 core clock */
--              core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
--
--              /* Disable PLL, since phy_device has not yet been created
--               * provided for phy_[read,write]_mmd_indirect is called, we
--               * provide our own core_write_mmd_indirect to complete this
--               * function.
--               */
--              core_write_mmd_indirect(priv,
--                                      CORE_GSWPLL_GRP1,
--                                      MDIO_MMD_VEND2,
--                                      0);
--
--              /* Set core clock into 500Mhz */
--              core_write(priv, CORE_GSWPLL_GRP2,
--                         RG_GSWPLL_POSDIV_500M(1) |
--                         RG_GSWPLL_FBKDIV_500M(25));
--
--              /* Enable PLL */
--              core_write(priv, CORE_GSWPLL_GRP1,
--                         RG_GSWPLL_EN_PRE |
--                         RG_GSWPLL_POSDIV_200M(2) |
--                         RG_GSWPLL_FBKDIV_200M(32));
--
--              /* Enable MT7530 core clock */
--              core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
--      }
-+      /* Disable MT7530 core clock */
-+      core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
-+
-+      /* Disable PLL, since phy_device has not yet been created
-+       * provided for phy_[read,write]_mmd_indirect is called, we
-+       * provide our own core_write_mmd_indirect to complete this
-+       * function.
-+       */
-+      core_write_mmd_indirect(priv,
-+                              CORE_GSWPLL_GRP1,
-+                              MDIO_MMD_VEND2,
-+                              0);
-+
-+      /* Set core clock into 500Mhz */
-+      core_write(priv, CORE_GSWPLL_GRP2,
-+                 RG_GSWPLL_POSDIV_500M(1) |
-+                 RG_GSWPLL_FBKDIV_500M(25));
-+
-+      /* Enable PLL */
-+      core_write(priv, CORE_GSWPLL_GRP1,
-+                 RG_GSWPLL_EN_PRE |
-+                 RG_GSWPLL_POSDIV_200M(2) |
-+                 RG_GSWPLL_FBKDIV_200M(32));
-+
-+      /* Enable MT7530 core clock */
-+      core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
-       /* Setup the MT7530 TRGMII Tx Clock */
-       core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
diff --git a/target/linux/generic/backport-5.10/781-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch b/target/linux/generic/backport-5.10/781-v5.12-net-dsa-mt7530-MT7530-optional-GPIO-support.patch
deleted file mode 100644 (file)
index 9e5047a..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-From 429a0edeefd88cbfca5c417dfb8561047bb50769 Mon Sep 17 00:00:00 2001
-From: DENG Qingfang <dqfext@gmail.com>
-Date: Mon, 25 Jan 2021 12:43:22 +0800
-Subject: [PATCH] net: dsa: mt7530: MT7530 optional GPIO support
-
-MT7530's LED controller can drive up to 15 LED/GPIOs.
-
-Add support for GPIO control and allow users to use its GPIOs by
-setting gpio-controller property in device tree.
-
-Signed-off-by: DENG Qingfang <dqfext@gmail.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/mt7530.c | 110 +++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/mt7530.h |  20 +++++++
- 2 files changed, 130 insertions(+)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -18,6 +18,7 @@
- #include <linux/regulator/consumer.h>
- #include <linux/reset.h>
- #include <linux/gpio/consumer.h>
-+#include <linux/gpio/driver.h>
- #include <net/dsa.h>
- #include "mt7530.h"
-@@ -1534,6 +1535,109 @@ mtk_get_tag_protocol(struct dsa_switch *
-       }
- }
-+static inline u32
-+mt7530_gpio_to_bit(unsigned int offset)
-+{
-+      /* Map GPIO offset to register bit
-+       * [ 2: 0]  port 0 LED 0..2 as GPIO 0..2
-+       * [ 6: 4]  port 1 LED 0..2 as GPIO 3..5
-+       * [10: 8]  port 2 LED 0..2 as GPIO 6..8
-+       * [14:12]  port 3 LED 0..2 as GPIO 9..11
-+       * [18:16]  port 4 LED 0..2 as GPIO 12..14
-+       */
-+      return BIT(offset + offset / 3);
-+}
-+
-+static int
-+mt7530_gpio_get(struct gpio_chip *gc, unsigned int offset)
-+{
-+      struct mt7530_priv *priv = gpiochip_get_data(gc);
-+      u32 bit = mt7530_gpio_to_bit(offset);
-+
-+      return !!(mt7530_read(priv, MT7530_LED_GPIO_DATA) & bit);
-+}
-+
-+static void
-+mt7530_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
-+{
-+      struct mt7530_priv *priv = gpiochip_get_data(gc);
-+      u32 bit = mt7530_gpio_to_bit(offset);
-+
-+      if (value)
-+              mt7530_set(priv, MT7530_LED_GPIO_DATA, bit);
-+      else
-+              mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit);
-+}
-+
-+static int
-+mt7530_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
-+{
-+      struct mt7530_priv *priv = gpiochip_get_data(gc);
-+      u32 bit = mt7530_gpio_to_bit(offset);
-+
-+      return (mt7530_read(priv, MT7530_LED_GPIO_DIR) & bit) ?
-+              GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
-+}
-+
-+static int
-+mt7530_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
-+{
-+      struct mt7530_priv *priv = gpiochip_get_data(gc);
-+      u32 bit = mt7530_gpio_to_bit(offset);
-+
-+      mt7530_clear(priv, MT7530_LED_GPIO_OE, bit);
-+      mt7530_clear(priv, MT7530_LED_GPIO_DIR, bit);
-+
-+      return 0;
-+}
-+
-+static int
-+mt7530_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value)
-+{
-+      struct mt7530_priv *priv = gpiochip_get_data(gc);
-+      u32 bit = mt7530_gpio_to_bit(offset);
-+
-+      mt7530_set(priv, MT7530_LED_GPIO_DIR, bit);
-+
-+      if (value)
-+              mt7530_set(priv, MT7530_LED_GPIO_DATA, bit);
-+      else
-+              mt7530_clear(priv, MT7530_LED_GPIO_DATA, bit);
-+
-+      mt7530_set(priv, MT7530_LED_GPIO_OE, bit);
-+
-+      return 0;
-+}
-+
-+static int
-+mt7530_setup_gpio(struct mt7530_priv *priv)
-+{
-+      struct device *dev = priv->dev;
-+      struct gpio_chip *gc;
-+
-+      gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
-+      if (!gc)
-+              return -ENOMEM;
-+
-+      mt7530_write(priv, MT7530_LED_GPIO_OE, 0);
-+      mt7530_write(priv, MT7530_LED_GPIO_DIR, 0);
-+      mt7530_write(priv, MT7530_LED_IO_MODE, 0);
-+
-+      gc->label = "mt7530";
-+      gc->parent = dev;
-+      gc->owner = THIS_MODULE;
-+      gc->get_direction = mt7530_gpio_get_direction;
-+      gc->direction_input = mt7530_gpio_direction_input;
-+      gc->direction_output = mt7530_gpio_direction_output;
-+      gc->get = mt7530_gpio_get;
-+      gc->set = mt7530_gpio_set;
-+      gc->base = -1;
-+      gc->ngpio = 15;
-+      gc->can_sleep = true;
-+
-+      return devm_gpiochip_add_data(dev, gc, priv);
-+}
-+
- static int
- mt7530_setup(struct dsa_switch *ds)
- {
-@@ -1675,6 +1779,12 @@ mt7530_setup(struct dsa_switch *ds)
-               }
-       }
-+      if (of_property_read_bool(priv->dev->of_node, "gpio-controller")) {
-+              ret = mt7530_setup_gpio(priv);
-+              if (ret)
-+                      return ret;
-+      }
-+
-       mt7530_setup_port5(ds, interface);
-       /* Flush the FDB table */
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -529,6 +529,26 @@ enum mt7531_clk_skew {
- #define  MT7531_GPIO12_RG_RXD3_MASK   GENMASK(19, 16)
- #define  MT7531_EXT_P_MDIO_12         (2 << 16)
-+/* Registers for LED GPIO control (MT7530 only)
-+ * All registers follow this pattern:
-+ * [ 2: 0]  port 0
-+ * [ 6: 4]  port 1
-+ * [10: 8]  port 2
-+ * [14:12]  port 3
-+ * [18:16]  port 4
-+ */
-+
-+/* LED enable, 0: Disable, 1: Enable (Default) */
-+#define MT7530_LED_EN                 0x7d00
-+/* LED mode, 0: GPIO mode, 1: PHY mode (Default) */
-+#define MT7530_LED_IO_MODE            0x7d04
-+/* GPIO direction, 0: Input, 1: Output */
-+#define MT7530_LED_GPIO_DIR           0x7d10
-+/* GPIO output enable, 0: Disable, 1: Enable */
-+#define MT7530_LED_GPIO_OE            0x7d14
-+/* GPIO value, 0: Low, 1: High */
-+#define MT7530_LED_GPIO_DATA          0x7d18
-+
- #define MT7530_CREV                   0x7ffc
- #define  CHIP_NAME_SHIFT              16
- #define  MT7530_ID                    0x7530
diff --git a/target/linux/generic/backport-5.10/781-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch b/target/linux/generic/backport-5.10/781-v5.13-net-dsa-mt7530-Add-support-for-EEE-features.patch
deleted file mode 100644 (file)
index 38dd8a7..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-From 40b5d2f15c091fa9c854acde91ad2acb504027d7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
-Date: Mon, 12 Apr 2021 08:50:31 +0200
-Subject: [PATCH] net: dsa: mt7530: Add support for EEE features
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch adds EEE support.
-
-Signed-off-by: René van Dorst <opensource@vdorst.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 43 ++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/mt7530.h | 14 ++++++++++++-
- 2 files changed, 56 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2371,6 +2371,17 @@ static void mt753x_phylink_mac_link_up(s
-                       mcr |= PMCR_RX_FC_EN;
-       }
-+      if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, 0) >= 0) {
-+              switch (speed) {
-+              case SPEED_1000:
-+                      mcr |= PMCR_FORCE_EEE1G;
-+                      break;
-+              case SPEED_100:
-+                      mcr |= PMCR_FORCE_EEE100;
-+                      break;
-+              }
-+      }
-+
-       mt7530_set(priv, MT7530_PMCR_P(port), mcr);
- }
-@@ -2601,6 +2612,36 @@ mt753x_phy_write(struct dsa_switch *ds,
-       return priv->info->phy_write(ds, port, regnum, val);
- }
-+static int mt753x_get_mac_eee(struct dsa_switch *ds, int port,
-+                            struct ethtool_eee *e)
-+{
-+      struct mt7530_priv *priv = ds->priv;
-+      u32 eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port));
-+
-+      e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN);
-+      e->tx_lpi_timer = GET_LPI_THRESH(eeecr);
-+
-+      return 0;
-+}
-+
-+static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
-+                            struct ethtool_eee *e)
-+{
-+      struct mt7530_priv *priv = ds->priv;
-+      u32 set, mask = LPI_THRESH_MASK | LPI_MODE_EN;
-+
-+      if (e->tx_lpi_timer > 0xFFF)
-+              return -EINVAL;
-+
-+      set = SET_LPI_THRESH(e->tx_lpi_timer);
-+      if (!e->tx_lpi_enabled)
-+              /* Force LPI Mode without a delay */
-+              set |= LPI_MODE_EN;
-+      mt7530_rmw(priv, MT7530_PMEEECR_P(port), mask, set);
-+
-+      return 0;
-+}
-+
- static const struct dsa_switch_ops mt7530_switch_ops = {
-       .get_tag_protocol       = mtk_get_tag_protocol,
-       .setup                  = mt753x_setup,
-@@ -2629,6 +2670,8 @@ static const struct dsa_switch_ops mt753
-       .phylink_mac_an_restart = mt753x_phylink_mac_an_restart,
-       .phylink_mac_link_down  = mt753x_phylink_mac_link_down,
-       .phylink_mac_link_up    = mt753x_phylink_mac_link_up,
-+      .get_mac_eee            = mt753x_get_mac_eee,
-+      .set_mac_eee            = mt753x_set_mac_eee,
- };
- static const struct mt753x_info mt753x_table[] = {
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -240,6 +240,8 @@ enum mt7530_vlan_port_attr {
- #define  PMCR_RX_EN                   BIT(13)
- #define  PMCR_BACKOFF_EN              BIT(9)
- #define  PMCR_BACKPR_EN                       BIT(8)
-+#define  PMCR_FORCE_EEE1G             BIT(7)
-+#define  PMCR_FORCE_EEE100            BIT(6)
- #define  PMCR_TX_FC_EN                        BIT(5)
- #define  PMCR_RX_FC_EN                        BIT(4)
- #define  PMCR_FORCE_SPEED_1000                BIT(3)
-@@ -264,7 +266,8 @@ enum mt7530_vlan_port_attr {
- #define  PMCR_LINK_SETTINGS_MASK      (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
-                                        PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
-                                        PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
--                                       PMCR_FORCE_FDX | PMCR_FORCE_LNK)
-+                                       PMCR_FORCE_FDX | PMCR_FORCE_LNK | \
-+                                       PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100)
- #define  PMCR_CPU_PORT_SETTING(id)    (PMCR_FORCE_MODE_ID((id)) | \
-                                        PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
-                                        PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
-@@ -273,6 +276,15 @@ enum mt7530_vlan_port_attr {
-                                        PMCR_FORCE_SPEED_1000 | \
-                                        PMCR_FORCE_FDX | PMCR_FORCE_LNK)
-+#define MT7530_PMEEECR_P(x)           (0x3004 + (x) * 0x100)
-+#define  WAKEUP_TIME_1000(x)          (((x) & 0xFF) << 24)
-+#define  WAKEUP_TIME_100(x)           (((x) & 0xFF) << 16)
-+#define  LPI_THRESH_MASK              GENMASK(15, 4)
-+#define  LPI_THRESH_SHT                       4
-+#define  SET_LPI_THRESH(x)            (((x) << LPI_THRESH_SHT) & LPI_THRESH_MASK)
-+#define  GET_LPI_THRESH(x)            (((x) & LPI_THRESH_MASK) >> LPI_THRESH_SHT)
-+#define  LPI_MODE_EN                  BIT(0)
-+
- #define MT7530_PMSR_P(x)              (0x3008 + (x) * 0x100)
- #define  PMSR_EEE1G                   BIT(7)
- #define  PMSR_EEE100M                 BIT(6)
diff --git a/target/linux/generic/backport-5.10/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/target/linux/generic/backport-5.10/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch
deleted file mode 100644 (file)
index 8e242bf..0000000
+++ /dev/null
@@ -1,1935 +0,0 @@
-From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 12 Apr 2021 19:47:17 +0200
-Subject: of: net: pass the dst buffer to of_get_mac_address()
-
-of_get_mac_address() returns a "const void*" pointer to a MAC address.
-Lately, support to fetch the MAC address by an NVMEM provider was added.
-But this will only work with platform devices. It will not work with
-PCI devices (e.g. of an integrated root complex) and esp. not with DSA
-ports.
-
-There is an of_* variant of the nvmem binding which works without
-devices. The returned data of a nvmem_cell_read() has to be freed after
-use. On the other hand the return of_get_mac_address() points to some
-static data without a lifetime. The trick for now, was to allocate a
-device resource managed buffer which is then returned. This will only
-work if we have an actual device.
-
-Change it, so that the caller of of_get_mac_address() has to supply a
-buffer where the MAC address is written to. Unfortunately, this will
-touch all drivers which use the of_get_mac_address().
-
-Usually the code looks like:
-
-  const char *addr;
-  addr = of_get_mac_address(np);
-  if (!IS_ERR(addr))
-    ether_addr_copy(ndev->dev_addr, addr);
-
-This can then be simply rewritten as:
-
-  of_get_mac_address(np, ndev->dev_addr);
-
-Sometimes is_valid_ether_addr() is used to test the MAC address.
-of_get_mac_address() already makes sure, it just returns a valid MAC
-address. Thus we can just test its return code. But we have to be
-careful if there are still other sources for the MAC address before the
-of_get_mac_address(). In this case we have to keep the
-is_valid_ether_addr() call.
-
-The following coccinelle patch was used to convert common cases to the
-new style. Afterwards, I've manually gone over the drivers and fixed the
-return code variable: either used a new one or if one was already
-available use that. Mansour Moufid, thanks for that coccinelle patch!
-
-<spml>
-@a@
-identifier x;
-expression y, z;
-@@
-- x = of_get_mac_address(y);
-+ x = of_get_mac_address(y, z);
-  <...
-- ether_addr_copy(z, x);
-  ...>
-
-@@
-identifier a.x;
-@@
-- if (<+... x ...+>) {}
-
-@@
-identifier a.x;
-@@
-  if (<+... x ...+>) {
-      ...
-  }
-- else {}
-
-@@
-identifier a.x;
-expression e;
-@@
-- if (<+... x ...+>@e)
--     {}
-- else
-+ if (!(e))
-      {...}
-
-@@
-expression x, y, z;
-@@
-- x = of_get_mac_address(y, z);
-+ of_get_mac_address(y, z);
-  ... when != x
-</spml>
-
-All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
-compile-time tested.
-
-Suggested-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Michael Walle <michael@walle.cc>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- arch/arm/mach-mvebu/kirkwood.c                     |  3 +-
- arch/powerpc/sysdev/tsi108_dev.c                   |  5 +-
- drivers/net/ethernet/aeroflex/greth.c              |  6 +--
- drivers/net/ethernet/allwinner/sun4i-emac.c        | 10 ++--
- drivers/net/ethernet/altera/altera_tse_main.c      |  7 +--
- drivers/net/ethernet/arc/emac_main.c               |  8 +--
- drivers/net/ethernet/atheros/ag71xx.c              |  7 +--
- drivers/net/ethernet/broadcom/bcm4908_enet.c       |  7 +--
- drivers/net/ethernet/broadcom/bcmsysport.c         |  7 +--
- drivers/net/ethernet/broadcom/bgmac-bcma.c         | 10 ++--
- drivers/net/ethernet/broadcom/bgmac-platform.c     | 11 ++--
- drivers/net/ethernet/cadence/macb_main.c           | 11 ++--
- drivers/net/ethernet/cavium/octeon/octeon_mgmt.c   |  8 +--
- drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  5 +-
- drivers/net/ethernet/davicom/dm9000.c              | 10 ++--
- drivers/net/ethernet/ethoc.c                       |  6 +--
- drivers/net/ethernet/ezchip/nps_enet.c             |  7 +--
- drivers/net/ethernet/freescale/fec_main.c          |  7 +--
- drivers/net/ethernet/freescale/fec_mpc52xx.c       |  7 +--
- drivers/net/ethernet/freescale/fman/mac.c          |  9 ++--
- .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |  5 +-
- drivers/net/ethernet/freescale/gianfar.c           |  8 +--
- drivers/net/ethernet/freescale/ucc_geth.c          |  5 +-
- drivers/net/ethernet/hisilicon/hisi_femac.c        |  7 +--
- drivers/net/ethernet/hisilicon/hix5hd2_gmac.c      |  7 +--
- drivers/net/ethernet/lantiq_xrx200.c               |  7 +--
- drivers/net/ethernet/marvell/mv643xx_eth.c         |  5 +-
- drivers/net/ethernet/marvell/mvneta.c              |  6 +--
- .../net/ethernet/marvell/prestera/prestera_main.c  | 11 ++--
- drivers/net/ethernet/marvell/pxa168_eth.c          |  9 +---
- drivers/net/ethernet/marvell/sky2.c                |  8 ++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c        | 11 ++--
- drivers/net/ethernet/micrel/ks8851_common.c        |  7 ++-
- drivers/net/ethernet/microchip/lan743x_main.c      |  5 +-
- drivers/net/ethernet/nxp/lpc_eth.c                 |  4 +-
- drivers/net/ethernet/qualcomm/qca_spi.c            | 10 ++--
- drivers/net/ethernet/qualcomm/qca_uart.c           |  9 +---
- drivers/net/ethernet/renesas/ravb_main.c           | 12 +++--
- drivers/net/ethernet/renesas/sh_eth.c              |  5 +-
- .../net/ethernet/samsung/sxgbe/sxgbe_platform.c    | 13 ++---
- drivers/net/ethernet/socionext/sni_ave.c           | 10 ++--
- .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
- .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
- .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
- drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
- .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
- .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
- .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
- .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
- drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
- .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
- drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c  |  2 +-
- .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
- .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
- drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
- drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
- drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
- drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
- .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
- drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +-
- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  2 +-
- .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 14 ++---
- .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  2 +-
- drivers/net/ethernet/ti/am65-cpsw-nuss.c           | 19 ++++---
- drivers/net/ethernet/ti/cpsw.c                     |  7 +--
- drivers/net/ethernet/ti/cpsw_new.c                 |  7 +--
- drivers/net/ethernet/ti/davinci_emac.c             |  8 +--
- drivers/net/ethernet/ti/netcp_core.c               |  7 +--
- drivers/net/ethernet/wiznet/w5100-spi.c            |  8 ++-
- drivers/net/ethernet/wiznet/w5100.c                |  2 +-
- drivers/net/ethernet/xilinx/ll_temac_main.c        |  8 +--
- drivers/net/ethernet/xilinx/xilinx_axienet_main.c  | 15 +++---
- drivers/net/ethernet/xilinx/xilinx_emaclite.c      |  8 +--
- drivers/net/wireless/ath/ath9k/init.c              |  5 +-
- drivers/net/wireless/mediatek/mt76/eeprom.c        |  9 +---
- drivers/net/wireless/ralink/rt2x00/rt2x00dev.c     |  6 +--
- drivers/of/of_net.c                                | 60 ++++++++++------------
- drivers/staging/octeon/ethernet.c                  | 10 ++--
- drivers/staging/wfx/main.c                         |  7 ++-
- include/linux/of_net.h                             |  6 +--
- include/net/dsa.h                                  |  2 +-
- net/dsa/dsa2.c                                     |  2 +-
- net/dsa/slave.c                                    |  2 +-
- net/ethernet/eth.c                                 | 11 ++--
- 85 files changed, 218 insertions(+), 364 deletions(-)
-
---- a/arch/arm/mach-mvebu/kirkwood.c
-+++ b/arch/arm/mach-mvebu/kirkwood.c
-@@ -84,6 +84,7 @@ static void __init kirkwood_dt_eth_fixup
-               struct device_node *pnp = of_get_parent(np);
-               struct clk *clk;
-               struct property *pmac;
-+              u8 tmpmac[ETH_ALEN];
-               void __iomem *io;
-               u8 *macaddr;
-               u32 reg;
-@@ -93,7 +94,7 @@ static void __init kirkwood_dt_eth_fixup
-               /* skip disabled nodes or nodes with valid MAC address*/
-               if (!of_device_is_available(pnp) ||
--                  !IS_ERR(of_get_mac_address(np)))
-+                  !of_get_mac_address(np, tmpmac))
-                       goto eth_fixup_skip;
-               clk = of_clk_get(pnp, 0);
---- a/arch/powerpc/sysdev/tsi108_dev.c
-+++ b/arch/powerpc/sysdev/tsi108_dev.c
-@@ -73,7 +73,6 @@ static int __init tsi108_eth_of_init(voi
-               struct device_node *phy, *mdio;
-               hw_info tsi_eth_data;
-               const unsigned int *phy_id;
--              const void *mac_addr;
-               const phandle *ph;
-               memset(r, 0, sizeof(r));
-@@ -101,9 +100,7 @@ static int __init tsi108_eth_of_init(voi
-                       goto err;
-               }
--              mac_addr = of_get_mac_address(np);
--              if (!IS_ERR(mac_addr))
--                      ether_addr_copy(tsi_eth_data.mac_addr, mac_addr);
-+              of_get_mac_address(np, tsi_eth_data.mac_addr);
-               ph = of_get_property(np, "mdio-handle", NULL);
-               mdio = of_find_node_by_phandle(*ph);
---- a/drivers/net/ethernet/aeroflex/greth.c
-+++ b/drivers/net/ethernet/aeroflex/greth.c
-@@ -1449,10 +1449,10 @@ static int greth_of_probe(struct platfor
-                       break;
-       }
-       if (i == 6) {
--              const u8 *addr;
-+              u8 addr[ETH_ALEN];
--              addr = of_get_mac_address(ofdev->dev.of_node);
--              if (!IS_ERR(addr)) {
-+              err = of_get_mac_address(ofdev->dev.of_node, addr);
-+              if (!err) {
-                       for (i = 0; i < 6; i++)
-                               macaddr[i] = (unsigned int) addr[i];
-               } else {
---- a/drivers/net/ethernet/allwinner/sun4i-emac.c
-+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
-@@ -790,7 +790,6 @@ static int emac_probe(struct platform_de
-       struct emac_board_info *db;
-       struct net_device *ndev;
-       int ret = 0;
--      const char *mac_addr;
-       ndev = alloc_etherdev(sizeof(struct emac_board_info));
-       if (!ndev) {
-@@ -853,12 +852,9 @@ static int emac_probe(struct platform_de
-       }
-       /* Read MAC-address from DT */
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(ndev->dev_addr, mac_addr);
--
--      /* Check if the MAC address is valid, if not get a random one */
--      if (!is_valid_ether_addr(ndev->dev_addr)) {
-+      ret = of_get_mac_address(np, ndev->dev_addr);
-+      if (ret) {
-+              /* if the MAC address is invalid get a random one */
-               eth_hw_addr_random(ndev);
-               dev_warn(&pdev->dev, "using random MAC address %pM\n",
-                        ndev->dev_addr);
---- a/drivers/net/ethernet/altera/altera_tse_main.c
-+++ b/drivers/net/ethernet/altera/altera_tse_main.c
-@@ -1351,7 +1351,6 @@ static int altera_tse_probe(struct platf
-       struct resource *control_port;
-       struct resource *dma_res;
-       struct altera_tse_private *priv;
--      const unsigned char *macaddr;
-       void __iomem *descmap;
-       const struct of_device_id *of_id = NULL;
-@@ -1525,10 +1524,8 @@ static int altera_tse_probe(struct platf
-       priv->rx_dma_buf_sz = ALTERA_RXDMABUFFER_SIZE;
-       /* get default MAC address from device tree */
--      macaddr = of_get_mac_address(pdev->dev.of_node);
--      if (!IS_ERR(macaddr))
--              ether_addr_copy(ndev->dev_addr, macaddr);
--      else
-+      ret = of_get_mac_address(pdev->dev.of_node, ndev->dev_addr);
-+      if (ret)
-               eth_hw_addr_random(ndev);
-       /* get phy addr and create mdio */
---- a/drivers/net/ethernet/arc/emac_main.c
-+++ b/drivers/net/ethernet/arc/emac_main.c
-@@ -857,7 +857,6 @@ int arc_emac_probe(struct net_device *nd
-       struct device_node *phy_node;
-       struct phy_device *phydev = NULL;
-       struct arc_emac_priv *priv;
--      const char *mac_addr;
-       unsigned int id, clock_frequency, irq;
-       int err;
-@@ -942,11 +941,8 @@ int arc_emac_probe(struct net_device *nd
-       }
-       /* Get MAC address from device tree */
--      mac_addr = of_get_mac_address(dev->of_node);
--
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(ndev->dev_addr, mac_addr);
--      else
-+      err = of_get_mac_address(dev->of_node, ndev->dev_addr);
-+      if (err)
-               eth_hw_addr_random(ndev);
-       arc_emac_set_address_internal(ndev);
---- a/drivers/net/ethernet/atheros/ag71xx.c
-+++ b/drivers/net/ethernet/atheros/ag71xx.c
-@@ -1856,7 +1856,6 @@ static int ag71xx_probe(struct platform_
-       const struct ag71xx_dcfg *dcfg;
-       struct net_device *ndev;
-       struct resource *res;
--      const void *mac_addr;
-       int tx_size, err, i;
-       struct ag71xx *ag;
-@@ -1957,10 +1956,8 @@ static int ag71xx_probe(struct platform_
-       ag->stop_desc->ctrl = 0;
-       ag->stop_desc->next = (u32)ag->stop_desc_dma;
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr))
--              memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
--      if (IS_ERR(mac_addr) || !is_valid_ether_addr(ndev->dev_addr)) {
-+      err = of_get_mac_address(np, ndev->dev_addr);
-+      if (err) {
-               netif_err(ag, probe, ndev, "invalid MAC address, using random address\n");
-               eth_random_addr(ndev->dev_addr);
-       }
---- a/drivers/net/ethernet/broadcom/bcmsysport.c
-+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
-@@ -2465,7 +2465,6 @@ static int bcm_sysport_probe(struct plat
-       struct bcm_sysport_priv *priv;
-       struct device_node *dn;
-       struct net_device *dev;
--      const void *macaddr;
-       u32 txq, rxq;
-       int ret;
-@@ -2560,12 +2559,10 @@ static int bcm_sysport_probe(struct plat
-       }
-       /* Initialize netdevice members */
--      macaddr = of_get_mac_address(dn);
--      if (IS_ERR(macaddr)) {
-+      ret = of_get_mac_address(dn, dev->dev_addr);
-+      if (ret) {
-               dev_warn(&pdev->dev, "using random Ethernet MAC\n");
-               eth_hw_addr_random(dev);
--      } else {
--              ether_addr_copy(dev->dev_addr, macaddr);
-       }
-       SET_NETDEV_DEV(dev, &pdev->dev);
---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
-@@ -115,7 +115,7 @@ static int bgmac_probe(struct bcma_devic
-       struct ssb_sprom *sprom = &core->bus->sprom;
-       struct mii_bus *mii_bus;
-       struct bgmac *bgmac;
--      const u8 *mac = NULL;
-+      const u8 *mac;
-       int err;
-       bgmac = bgmac_alloc(&core->dev);
-@@ -128,11 +128,10 @@ static int bgmac_probe(struct bcma_devic
-       bcma_set_drvdata(core, bgmac);
--      if (bgmac->dev->of_node)
--              mac = of_get_mac_address(bgmac->dev->of_node);
-+      err = of_get_mac_address(bgmac->dev->of_node, bgmac->net_dev->dev_addr);
-       /* If no MAC address assigned via device tree, check SPROM */
--      if (IS_ERR_OR_NULL(mac)) {
-+      if (err) {
-               switch (core->core_unit) {
-               case 0:
-                       mac = sprom->et0mac;
-@@ -149,10 +148,9 @@ static int bgmac_probe(struct bcma_devic
-                       err = -ENOTSUPP;
-                       goto err;
-               }
-+              ether_addr_copy(bgmac->net_dev->dev_addr, mac);
-       }
--      ether_addr_copy(bgmac->net_dev->dev_addr, mac);
--
-       /* On BCM4706 we need common core to access PHY */
-       if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
-           !core->bus->drv_gmac_cmn.core) {
---- a/drivers/net/ethernet/broadcom/bgmac-platform.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
-@@ -173,7 +173,7 @@ static int bgmac_probe(struct platform_d
-       struct device_node *np = pdev->dev.of_node;
-       struct bgmac *bgmac;
-       struct resource *regs;
--      const u8 *mac_addr;
-+      int ret;
-       bgmac = bgmac_alloc(&pdev->dev);
-       if (!bgmac)
-@@ -192,11 +192,10 @@ static int bgmac_probe(struct platform_d
-       bgmac->dev = &pdev->dev;
-       bgmac->dma_dev = &pdev->dev;
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(bgmac->net_dev->dev_addr, mac_addr);
--      else
--              dev_warn(&pdev->dev, "MAC address not present in device tree\n");
-+      ret = of_get_mac_address(np, bgmac->net_dev->dev_addr);
-+      if (ret)
-+              dev_warn(&pdev->dev,
-+                       "MAC address not present in device tree\n");
-       bgmac->irq = platform_get_irq(pdev, 0);
-       if (bgmac->irq < 0)
---- a/drivers/net/ethernet/cadence/macb_main.c
-+++ b/drivers/net/ethernet/cadence/macb_main.c
-@@ -4456,7 +4456,6 @@ static int macb_probe(struct platform_de
-       struct net_device *dev;
-       struct resource *regs;
-       void __iomem *mem;
--      const char *mac;
-       struct macb *bp;
-       int err, val;
-@@ -4569,15 +4568,11 @@ static int macb_probe(struct platform_de
-       if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR)
-               bp->rx_intr_mask |= MACB_BIT(RXUBR);
--      mac = of_get_mac_address(np);
--      if (PTR_ERR(mac) == -EPROBE_DEFER) {
--              err = -EPROBE_DEFER;
-+      err = of_get_mac_address(np, bp->dev->dev_addr);
-+      if (err == -EPROBE_DEFER)
-               goto err_out_free_netdev;
--      } else if (!IS_ERR_OR_NULL(mac)) {
--              ether_addr_copy(bp->dev->dev_addr, mac);
--      } else {
-+      else if (err)
-               macb_get_hwaddr(bp);
--      }
-       err = of_get_phy_mode(np, &interface);
-       if (err)
---- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
-+++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
-@@ -1385,7 +1385,6 @@ static int octeon_mgmt_probe(struct plat
-       struct net_device *netdev;
-       struct octeon_mgmt *p;
-       const __be32 *data;
--      const u8 *mac;
-       struct resource *res_mix;
-       struct resource *res_agl;
-       struct resource *res_agl_prt_ctl;
-@@ -1502,11 +1501,8 @@ static int octeon_mgmt_probe(struct plat
-       netdev->min_mtu = 64 - OCTEON_MGMT_RX_HEADROOM;
-       netdev->max_mtu = 16383 - OCTEON_MGMT_RX_HEADROOM - VLAN_HLEN;
--      mac = of_get_mac_address(pdev->dev.of_node);
--
--      if (!IS_ERR(mac))
--              ether_addr_copy(netdev->dev_addr, mac);
--      else
-+      result = of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
-+      if (result)
-               eth_hw_addr_random(netdev);
-       p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
---- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
-+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
-@@ -1474,7 +1474,6 @@ static int bgx_init_of_phy(struct bgx *b
-       device_for_each_child_node(&bgx->pdev->dev, fwn) {
-               struct phy_device *pd;
-               struct device_node *phy_np;
--              const char *mac;
-               /* Should always be an OF node.  But if it is not, we
-                * cannot handle it, so exit the loop.
-@@ -1483,9 +1482,7 @@ static int bgx_init_of_phy(struct bgx *b
-               if (!node)
-                       break;
--              mac = of_get_mac_address(node);
--              if (!IS_ERR(mac))
--                      ether_addr_copy(bgx->lmac[lmac].mac, mac);
-+              of_get_mac_address(node, bgx->lmac[lmac].mac);
-               SET_NETDEV_DEV(&bgx->lmac[lmac].netdev, &bgx->pdev->dev);
-               bgx->lmac[lmac].lmacid = lmac;
---- a/drivers/net/ethernet/davicom/dm9000.c
-+++ b/drivers/net/ethernet/davicom/dm9000.c
-@@ -1388,7 +1388,7 @@ static struct dm9000_plat_data *dm9000_p
- {
-       struct dm9000_plat_data *pdata;
-       struct device_node *np = dev->of_node;
--      const void *mac_addr;
-+      int ret;
-       if (!IS_ENABLED(CONFIG_OF) || !np)
-               return ERR_PTR(-ENXIO);
-@@ -1402,11 +1402,9 @@ static struct dm9000_plat_data *dm9000_p
-       if (of_find_property(np, "davicom,no-eeprom", NULL))
-               pdata->flags |= DM9000_PLATF_NO_EEPROM;
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(pdata->dev_addr, mac_addr);
--      else if (PTR_ERR(mac_addr) == -EPROBE_DEFER)
--              return ERR_CAST(mac_addr);
-+      ret = of_get_mac_address(np, pdata->dev_addr);
-+      if (ret == -EPROBE_DEFER)
-+              return ERR_PTR(ret);
-       return pdata;
- }
---- a/drivers/net/ethernet/ethoc.c
-+++ b/drivers/net/ethernet/ethoc.c
-@@ -1151,11 +1151,7 @@ static int ethoc_probe(struct platform_d
-               ether_addr_copy(netdev->dev_addr, pdata->hwaddr);
-               priv->phy_id = pdata->phy_id;
-       } else {
--              const void *mac;
--
--              mac = of_get_mac_address(pdev->dev.of_node);
--              if (!IS_ERR(mac))
--                      ether_addr_copy(netdev->dev_addr, mac);
-+              of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
-               priv->phy_id = -1;
-       }
---- a/drivers/net/ethernet/ezchip/nps_enet.c
-+++ b/drivers/net/ethernet/ezchip/nps_enet.c
-@@ -575,7 +575,6 @@ static s32 nps_enet_probe(struct platfor
-       struct net_device *ndev;
-       struct nps_enet_priv *priv;
-       s32 err = 0;
--      const char *mac_addr;
-       if (!dev->of_node)
-               return -ENODEV;
-@@ -602,10 +601,8 @@ static s32 nps_enet_probe(struct platfor
-       dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs_base);
-       /* set kernel MAC address to dev */
--      mac_addr = of_get_mac_address(dev->of_node);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(ndev->dev_addr, mac_addr);
--      else
-+      err = of_get_mac_address(dev->of_node, ndev->dev_addr);
-+      if (err)
-               eth_hw_addr_random(ndev);
-       /* Get IRQ number */
---- a/drivers/net/ethernet/freescale/fec_main.c
-+++ b/drivers/net/ethernet/freescale/fec_main.c
-@@ -1666,6 +1666,7 @@ static void fec_get_mac(struct net_devic
-       struct fec_enet_private *fep = netdev_priv(ndev);
-       struct fec_platform_data *pdata = dev_get_platdata(&fep->pdev->dev);
-       unsigned char *iap, tmpaddr[ETH_ALEN];
-+      int ret;
-       /*
-        * try to get mac address in following order:
-@@ -1681,9 +1682,9 @@ static void fec_get_mac(struct net_devic
-       if (!is_valid_ether_addr(iap)) {
-               struct device_node *np = fep->pdev->dev.of_node;
-               if (np) {
--                      const char *mac = of_get_mac_address(np);
--                      if (!IS_ERR(mac))
--                              iap = (unsigned char *) mac;
-+                      ret = of_get_mac_address(np, tmpaddr);
-+                      if (!ret)
-+                              iap = tmpaddr;
-               }
-       }
---- a/drivers/net/ethernet/freescale/fec_mpc52xx.c
-+++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c
-@@ -813,7 +813,6 @@ static int mpc52xx_fec_probe(struct plat
-       const u32 *prop;
-       int prop_size;
-       struct device_node *np = op->dev.of_node;
--      const char *mac_addr;
-       phys_addr_t rx_fifo;
-       phys_addr_t tx_fifo;
-@@ -891,10 +890,8 @@ static int mpc52xx_fec_probe(struct plat
-        *
-        * First try to read MAC address from DT
-        */
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr)) {
--              ether_addr_copy(ndev->dev_addr, mac_addr);
--      } else {
-+      rv = of_get_mac_address(np, ndev->dev_addr);
-+      if (rv) {
-               struct mpc52xx_fec __iomem *fec = priv->fec;
-               /*
---- a/drivers/net/ethernet/freescale/fman/mac.c
-+++ b/drivers/net/ethernet/freescale/fman/mac.c
-@@ -605,7 +605,6 @@ static int mac_probe(struct platform_dev
-       struct platform_device  *of_dev;
-       struct resource          res;
-       struct mac_priv_s       *priv;
--      const u8                *mac_addr;
-       u32                      val;
-       u8                      fman_id;
-       phy_interface_t          phy_if;
-@@ -723,11 +722,9 @@ static int mac_probe(struct platform_dev
-       priv->cell_index = (u8)val;
-       /* Get the MAC address */
--      mac_addr = of_get_mac_address(mac_node);
--      if (IS_ERR(mac_addr))
-+      err = of_get_mac_address(mac_node, mac_dev->addr);
-+      if (err)
-               dev_warn(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
--      else
--              ether_addr_copy(mac_dev->addr, mac_addr);
-       /* Get the port handles */
-       nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
-@@ -853,7 +850,7 @@ static int mac_probe(struct platform_dev
-       if (err < 0)
-               dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
--      if (!IS_ERR(mac_addr))
-+      if (!is_zero_ether_addr(mac_dev->addr))
-               dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
-       priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
---- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
-+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
-@@ -918,7 +918,6 @@ static int fs_enet_probe(struct platform
-       const u32 *data;
-       struct clk *clk;
-       int err;
--      const u8 *mac_addr;
-       const char *phy_connection_type;
-       int privsize, len, ret = -ENODEV;
-@@ -1006,9 +1005,7 @@ static int fs_enet_probe(struct platform
-       spin_lock_init(&fep->lock);
-       spin_lock_init(&fep->tx_lock);
--      mac_addr = of_get_mac_address(ofdev->dev.of_node);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(ndev->dev_addr, mac_addr);
-+      of_get_mac_address(ofdev->dev.of_node, ndev->dev_addr);
-       ret = fep->ops->allocate_bd(ndev);
-       if (ret)
---- a/drivers/net/ethernet/freescale/gianfar.c
-+++ b/drivers/net/ethernet/freescale/gianfar.c
-@@ -641,7 +641,6 @@ static phy_interface_t gfar_get_interfac
- static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
- {
-       const char *model;
--      const void *mac_addr;
-       int err = 0, i;
-       phy_interface_t interface;
-       struct net_device *dev = NULL;
-@@ -783,11 +782,8 @@ static int gfar_of_init(struct platform_
-       if (stash_len || stash_idx)
-               priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING;
--      mac_addr = of_get_mac_address(np);
--
--      if (!IS_ERR(mac_addr)) {
--              ether_addr_copy(dev->dev_addr, mac_addr);
--      } else {
-+      err = of_get_mac_address(np, dev->dev_addr);
-+      if (err) {
-               eth_hw_addr_random(dev);
-               dev_info(&ofdev->dev, "Using random MAC address: %pM\n", dev->dev_addr);
-       }
---- a/drivers/net/ethernet/freescale/ucc_geth.c
-+++ b/drivers/net/ethernet/freescale/ucc_geth.c
-@@ -3696,7 +3696,6 @@ static int ucc_geth_probe(struct platfor
-       int err, ucc_num, max_speed = 0;
-       const unsigned int *prop;
-       const char *sprop;
--      const void *mac_addr;
-       phy_interface_t phy_interface;
-       static const int enet_to_speed[] = {
-               SPEED_10, SPEED_10, SPEED_10,
-@@ -3906,9 +3905,7 @@ static int ucc_geth_probe(struct platfor
-               goto err_free_netdev;
-       }
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(dev->dev_addr, mac_addr);
-+      of_get_mac_address(np, dev->dev_addr);
-       ugeth->ug_info = ug_info;
-       ugeth->dev = device;
---- a/drivers/net/ethernet/hisilicon/hisi_femac.c
-+++ b/drivers/net/ethernet/hisilicon/hisi_femac.c
-@@ -772,7 +772,6 @@ static int hisi_femac_drv_probe(struct p
-       struct net_device *ndev;
-       struct hisi_femac_priv *priv;
-       struct phy_device *phy;
--      const char *mac_addr;
-       int ret;
-       ndev = alloc_etherdev(sizeof(*priv));
-@@ -842,10 +841,8 @@ static int hisi_femac_drv_probe(struct p
-                          (unsigned long)phy->phy_id,
-                          phy_modes(phy->interface));
--      mac_addr = of_get_mac_address(node);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(ndev->dev_addr, mac_addr);
--      if (!is_valid_ether_addr(ndev->dev_addr)) {
-+      ret = of_get_mac_address(node, ndev->dev_addr);
-+      if (ret) {
-               eth_hw_addr_random(ndev);
-               dev_warn(dev, "using random MAC address %pM\n",
-                        ndev->dev_addr);
---- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
-+++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
-@@ -1098,7 +1098,6 @@ static int hix5hd2_dev_probe(struct plat
-       struct net_device *ndev;
-       struct hix5hd2_priv *priv;
-       struct mii_bus *bus;
--      const char *mac_addr;
-       int ret;
-       ndev = alloc_etherdev(sizeof(struct hix5hd2_priv));
-@@ -1220,10 +1219,8 @@ static int hix5hd2_dev_probe(struct plat
-               goto out_phy_node;
-       }
--      mac_addr = of_get_mac_address(node);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(ndev->dev_addr, mac_addr);
--      if (!is_valid_ether_addr(ndev->dev_addr)) {
-+      ret = of_get_mac_address(node, ndev->dev_addr);
-+      if (ret) {
-               eth_hw_addr_random(ndev);
-               netdev_warn(ndev, "using random MAC address %pM\n",
-                           ndev->dev_addr);
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -440,7 +440,6 @@ static int xrx200_probe(struct platform_
-       struct resource *res;
-       struct xrx200_priv *priv;
-       struct net_device *net_dev;
--      const u8 *mac;
-       int err;
-       /* alloc the network device */
-@@ -484,10 +483,8 @@ static int xrx200_probe(struct platform_
-               return PTR_ERR(priv->clk);
-       }
--      mac = of_get_mac_address(np);
--      if (!IS_ERR(mac))
--              ether_addr_copy(net_dev->dev_addr, mac);
--      else
-+      err = of_get_mac_address(np, net_dev->dev_addr);
-+      if (err)
-               eth_hw_addr_random(net_dev);
-       /* bring up the dma engine and IP core */
---- a/drivers/net/ethernet/marvell/mv643xx_eth.c
-+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
-@@ -2700,7 +2700,6 @@ static int mv643xx_eth_shared_of_add_por
-       struct platform_device *ppdev;
-       struct mv643xx_eth_platform_data ppd;
-       struct resource res;
--      const char *mac_addr;
-       int ret;
-       int dev_num = 0;
-@@ -2731,9 +2730,7 @@ static int mv643xx_eth_shared_of_add_por
-               return -EINVAL;
-       }
--      mac_addr = of_get_mac_address(pnp);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(ppd.mac_addr, mac_addr);
-+      of_get_mac_address(pnp, ppd.mac_addr);
-       mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size);
-       mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr);
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -5062,7 +5062,6 @@ static int mvneta_probe(struct platform_
-       struct net_device *dev;
-       struct phylink *phylink;
-       struct phy *comphy;
--      const char *dt_mac_addr;
-       char hw_mac_addr[ETH_ALEN];
-       phy_interface_t phy_mode;
-       const char *mac_from;
-@@ -5158,10 +5157,9 @@ static int mvneta_probe(struct platform_
-               goto err_free_ports;
-       }
--      dt_mac_addr = of_get_mac_address(dn);
--      if (!IS_ERR(dt_mac_addr)) {
-+      err = of_get_mac_address(dn, dev->dev_addr);
-+      if (!err) {
-               mac_from = "device tree";
--              ether_addr_copy(dev->dev_addr, dt_mac_addr);
-       } else {
-               mvneta_get_mac_addr(pp, hw_mac_addr);
-               if (is_valid_ether_addr(hw_mac_addr)) {
---- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
-+++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
-@@ -462,20 +462,17 @@ static int prestera_switch_set_base_mac_
- {
-       struct device_node *base_mac_np;
-       struct device_node *np;
--      const char *base_mac;
-+      int ret;
-       np = of_find_compatible_node(NULL, NULL, "marvell,prestera");
-       base_mac_np = of_parse_phandle(np, "base-mac-provider", 0);
--      base_mac = of_get_mac_address(base_mac_np);
--      of_node_put(base_mac_np);
--      if (!IS_ERR(base_mac))
--              ether_addr_copy(sw->base_mac, base_mac);
--
--      if (!is_valid_ether_addr(sw->base_mac)) {
-+      ret = of_get_mac_address(base_mac_np, sw->base_mac);
-+      if (ret) {
-               eth_random_addr(sw->base_mac);
-               dev_info(prestera_dev(sw), "using random base mac address\n");
-       }
-+      of_node_put(base_mac_np);
-       return prestera_hw_switch_mac_set(sw, sw->base_mac);
- }
---- a/drivers/net/ethernet/marvell/pxa168_eth.c
-+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
-@@ -1392,7 +1392,6 @@ static int pxa168_eth_probe(struct platf
-       struct resource *res;
-       struct clk *clk;
-       struct device_node *np;
--      const unsigned char *mac_addr = NULL;
-       int err;
-       printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
-@@ -1435,12 +1434,8 @@ static int pxa168_eth_probe(struct platf
-       INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
--      if (pdev->dev.of_node)
--              mac_addr = of_get_mac_address(pdev->dev.of_node);
--
--      if (!IS_ERR_OR_NULL(mac_addr)) {
--              ether_addr_copy(dev->dev_addr, mac_addr);
--      } else {
-+      err = of_get_mac_address(pdev->dev.of_node, dev->dev_addr);
-+      if (err) {
-               /* try reading the mac address, if set by the bootloader */
-               pxa168_eth_get_mac_address(dev, dev->dev_addr);
-               if (!is_valid_ether_addr(dev->dev_addr)) {
---- a/drivers/net/ethernet/marvell/sky2.c
-+++ b/drivers/net/ethernet/marvell/sky2.c
-@@ -4725,7 +4725,7 @@ static struct net_device *sky2_init_netd
- {
-       struct sky2_port *sky2;
-       struct net_device *dev = alloc_etherdev(sizeof(*sky2));
--      const void *iap;
-+      int ret;
-       if (!dev)
-               return NULL;
-@@ -4795,10 +4795,8 @@ static struct net_device *sky2_init_netd
-        * 1) from device tree data
-        * 2) from internal registers set by bootloader
-        */
--      iap = of_get_mac_address(hw->pdev->dev.of_node);
--      if (!IS_ERR(iap))
--              ether_addr_copy(dev->dev_addr, iap);
--      else
-+      ret = of_get_mac_address(hw->pdev->dev.of_node, dev->dev_addr);
-+      if (ret)
-               memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8,
-                             ETH_ALEN);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2580,14 +2580,11 @@ static int __init mtk_init(struct net_de
- {
-       struct mtk_mac *mac = netdev_priv(dev);
-       struct mtk_eth *eth = mac->hw;
--      const char *mac_addr;
-+      int ret;
--      mac_addr = of_get_mac_address(mac->of_node);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(dev->dev_addr, mac_addr);
--
--      /* If the mac address is invalid, use random mac address  */
--      if (!is_valid_ether_addr(dev->dev_addr)) {
-+      ret = of_get_mac_address(mac->of_node, dev->dev_addr);
-+      if (ret) {
-+              /* If the mac address is invalid, use random mac address */
-               eth_hw_addr_random(dev);
-               dev_err(eth->dev, "generated random MAC address %pM\n",
-                       dev->dev_addr);
---- a/drivers/net/ethernet/micrel/ks8851_common.c
-+++ b/drivers/net/ethernet/micrel/ks8851_common.c
-@@ -194,11 +194,10 @@ static void ks8851_read_mac_addr(struct
- static void ks8851_init_mac(struct ks8851_net *ks, struct device_node *np)
- {
-       struct net_device *dev = ks->netdev;
--      const u8 *mac_addr;
-+      int ret;
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr)) {
--              ether_addr_copy(dev->dev_addr, mac_addr);
-+      ret = of_get_mac_address(np, dev->dev_addr);
-+      if (!ret) {
-               ks8851_write_mac_addr(dev);
-               return;
-       }
---- a/drivers/net/ethernet/microchip/lan743x_main.c
-+++ b/drivers/net/ethernet/microchip/lan743x_main.c
-@@ -2835,7 +2835,6 @@ static int lan743x_pcidev_probe(struct p
- {
-       struct lan743x_adapter *adapter = NULL;
-       struct net_device *netdev = NULL;
--      const void *mac_addr;
-       int ret = -ENODEV;
-       netdev = devm_alloc_etherdev(&pdev->dev,
-@@ -2852,9 +2851,7 @@ static int lan743x_pcidev_probe(struct p
-                             NETIF_MSG_IFDOWN | NETIF_MSG_TX_QUEUED;
-       netdev->max_mtu = LAN743X_MAX_FRAME_SIZE;
--      mac_addr = of_get_mac_address(pdev->dev.of_node);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(adapter->mac_address, mac_addr);
-+      of_get_mac_address(pdev->dev.of_node, adapter->mac_address);
-       ret = lan743x_pci_init(adapter, pdev);
-       if (ret)
---- a/drivers/net/ethernet/nxp/lpc_eth.c
-+++ b/drivers/net/ethernet/nxp/lpc_eth.c
-@@ -1347,9 +1347,7 @@ static int lpc_eth_drv_probe(struct plat
-       __lpc_get_mac(pldat, ndev->dev_addr);
-       if (!is_valid_ether_addr(ndev->dev_addr)) {
--              const char *macaddr = of_get_mac_address(np);
--              if (!IS_ERR(macaddr))
--                      ether_addr_copy(ndev->dev_addr, macaddr);
-+              of_get_mac_address(np, ndev->dev_addr);
-       }
-       if (!is_valid_ether_addr(ndev->dev_addr))
-               eth_hw_addr_random(ndev);
---- a/drivers/net/ethernet/qualcomm/qca_spi.c
-+++ b/drivers/net/ethernet/qualcomm/qca_spi.c
-@@ -885,7 +885,7 @@ qca_spi_probe(struct spi_device *spi)
-       struct net_device *qcaspi_devs = NULL;
-       u8 legacy_mode = 0;
-       u16 signature;
--      const char *mac;
-+      int ret;
-       if (!spi->dev.of_node) {
-               dev_err(&spi->dev, "Missing device tree\n");
-@@ -962,12 +962,8 @@ qca_spi_probe(struct spi_device *spi)
-       spi_set_drvdata(spi, qcaspi_devs);
--      mac = of_get_mac_address(spi->dev.of_node);
--
--      if (!IS_ERR(mac))
--              ether_addr_copy(qca->net_dev->dev_addr, mac);
--
--      if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
-+      ret = of_get_mac_address(spi->dev.of_node, qca->net_dev->dev_addr);
-+      if (ret) {
-               eth_hw_addr_random(qca->net_dev);
-               dev_info(&spi->dev, "Using random MAC address: %pM\n",
-                        qca->net_dev->dev_addr);
---- a/drivers/net/ethernet/qualcomm/qca_uart.c
-+++ b/drivers/net/ethernet/qualcomm/qca_uart.c
-@@ -323,7 +323,6 @@ static int qca_uart_probe(struct serdev_
- {
-       struct net_device *qcauart_dev = alloc_etherdev(sizeof(struct qcauart));
-       struct qcauart *qca;
--      const char *mac;
-       u32 speed = 115200;
-       int ret;
-@@ -348,12 +347,8 @@ static int qca_uart_probe(struct serdev_
-       of_property_read_u32(serdev->dev.of_node, "current-speed", &speed);
--      mac = of_get_mac_address(serdev->dev.of_node);
--
--      if (!IS_ERR(mac))
--              ether_addr_copy(qca->net_dev->dev_addr, mac);
--
--      if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
-+      ret = of_get_mac_address(serdev->dev.of_node, qca->net_dev->dev_addr);
-+      if (ret) {
-               eth_hw_addr_random(qca->net_dev);
-               dev_info(&serdev->dev, "Using random MAC address: %pM\n",
-                        qca->net_dev->dev_addr);
---- a/drivers/net/ethernet/renesas/ravb_main.c
-+++ b/drivers/net/ethernet/renesas/ravb_main.c
-@@ -109,11 +109,13 @@ static void ravb_set_buffer_align(struct
-  * Ethernet AVB device doesn't have ROM for MAC address.
-  * This function gets the MAC address that was used by a bootloader.
-  */
--static void ravb_read_mac_address(struct net_device *ndev, const u8 *mac)
-+static void ravb_read_mac_address(struct device_node *np,
-+                                struct net_device *ndev)
- {
--      if (!IS_ERR(mac)) {
--              ether_addr_copy(ndev->dev_addr, mac);
--      } else {
-+      int ret;
-+
-+      ret = of_get_mac_address(np, ndev->dev_addr);
-+      if (ret) {
-               u32 mahr = ravb_read(ndev, MAHR);
-               u32 malr = ravb_read(ndev, MALR);
-@@ -2189,7 +2191,7 @@ static int ravb_probe(struct platform_de
-       priv->msg_enable = RAVB_DEF_MSG_ENABLE;
-       /* Read and set MAC address */
--      ravb_read_mac_address(ndev, of_get_mac_address(np));
-+      ravb_read_mac_address(np, ndev);
-       if (!is_valid_ether_addr(ndev->dev_addr)) {
-               dev_warn(&pdev->dev,
-                        "no valid MAC address supplied, using a random one\n");
---- a/drivers/net/ethernet/renesas/sh_eth.c
-+++ b/drivers/net/ethernet/renesas/sh_eth.c
-@@ -3145,7 +3145,6 @@ static struct sh_eth_plat_data *sh_eth_p
-       struct device_node *np = dev->of_node;
-       struct sh_eth_plat_data *pdata;
-       phy_interface_t interface;
--      const char *mac_addr;
-       int ret;
-       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
-@@ -3157,9 +3156,7 @@ static struct sh_eth_plat_data *sh_eth_p
-               return NULL;
-       pdata->phy_interface = interface;
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(pdata->mac_addr, mac_addr);
-+      of_get_mac_address(np, pdata->mac_addr);
-       pdata->no_ether_link =
-               of_property_read_bool(np, "renesas,no-ether-link");
---- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
-+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
-@@ -25,8 +25,7 @@
- #ifdef CONFIG_OF
- static int sxgbe_probe_config_dt(struct platform_device *pdev,
--                               struct sxgbe_plat_data *plat,
--                               const char **mac)
-+                               struct sxgbe_plat_data *plat)
- {
-       struct device_node *np = pdev->dev.of_node;
-       struct sxgbe_dma_cfg *dma_cfg;
-@@ -35,7 +34,6 @@ static int sxgbe_probe_config_dt(struct
-       if (!np)
-               return -ENODEV;
--      *mac = of_get_mac_address(np);
-       err = of_get_phy_mode(np, &plat->interface);
-       if (err && err != -ENODEV)
-               return err;
-@@ -63,8 +61,7 @@ static int sxgbe_probe_config_dt(struct
- }
- #else
- static int sxgbe_probe_config_dt(struct platform_device *pdev,
--                               struct sxgbe_plat_data *plat,
--                               const char **mac)
-+                               struct sxgbe_plat_data *plat)
- {
-       return -ENOSYS;
- }
-@@ -85,7 +82,6 @@ static int sxgbe_platform_probe(struct p
-       void __iomem *addr;
-       struct sxgbe_priv_data *priv = NULL;
-       struct sxgbe_plat_data *plat_dat = NULL;
--      const char *mac = NULL;
-       struct net_device *ndev = platform_get_drvdata(pdev);
-       struct device_node *node = dev->of_node;
-@@ -101,7 +97,7 @@ static int sxgbe_platform_probe(struct p
-               if (!plat_dat)
-                       return  -ENOMEM;
--              ret = sxgbe_probe_config_dt(pdev, plat_dat, &mac);
-+              ret = sxgbe_probe_config_dt(pdev, plat_dat);
-               if (ret) {
-                       pr_err("%s: main dt probe failed\n", __func__);
-                       return ret;
-@@ -122,8 +118,7 @@ static int sxgbe_platform_probe(struct p
-       }
-       /* Get MAC address if available (DT) */
--      if (!IS_ERR_OR_NULL(mac))
--              ether_addr_copy(priv->dev->dev_addr, mac);
-+      of_get_mac_address(node, priv->dev->dev_addr);
-       /* Get the TX/RX IRQ numbers */
-       for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) {
---- a/drivers/net/ethernet/socionext/sni_ave.c
-+++ b/drivers/net/ethernet/socionext/sni_ave.c
-@@ -1559,7 +1559,6 @@ static int ave_probe(struct platform_dev
-       struct ave_private *priv;
-       struct net_device *ndev;
-       struct device_node *np;
--      const void *mac_addr;
-       void __iomem *base;
-       const char *name;
-       int i, irq, ret;
-@@ -1600,12 +1599,9 @@ static int ave_probe(struct platform_dev
-       ndev->max_mtu = AVE_MAX_ETHFRAME - (ETH_HLEN + ETH_FCS_LEN);
--      mac_addr = of_get_mac_address(np);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(ndev->dev_addr, mac_addr);
--
--      /* if the mac address is invalid, use random mac address */
--      if (!is_valid_ether_addr(ndev->dev_addr)) {
-+      ret = of_get_mac_address(np, ndev->dev_addr);
-+      if (ret) {
-+              /* if the mac address is invalid, use random mac address */
-               eth_hw_addr_random(ndev);
-               dev_warn(dev, "Using random MAC address: %pM\n",
-                        ndev->dev_addr);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
-@@ -115,7 +115,7 @@ static int anarion_dwmac_probe(struct pl
-       if (IS_ERR(gmac))
-               return PTR_ERR(gmac);
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
-@@ -444,7 +444,7 @@ static int dwc_eth_dwmac_probe(struct pl
-       if (IS_ERR(stmmac_res.addr))
-               return PTR_ERR(stmmac_res.addr);
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
-@@ -27,7 +27,7 @@ static int dwmac_generic_probe(struct pl
-               return ret;
-       if (pdev->dev.of_node) {
--              plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+              plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-               if (IS_ERR(plat_dat)) {
-                       dev_err(&pdev->dev, "dt configuration failed\n");
-                       return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
-@@ -226,7 +226,7 @@ static int imx_dwmac_probe(struct platfo
-       if (!dwmac)
-               return -ENOMEM;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
-@@ -88,7 +88,7 @@ static int intel_eth_plat_probe(struct p
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat)) {
-               dev_err(&pdev->dev, "dt configuration failed\n");
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
-@@ -255,7 +255,7 @@ static int ipq806x_gmac_probe(struct pla
-       if (val)
-               return val;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
-@@ -37,7 +37,7 @@ static int lpc18xx_dwmac_probe(struct pl
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
-@@ -407,7 +407,7 @@ static int mediatek_dwmac_probe(struct p
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
-@@ -52,7 +52,7 @@ static int meson6_dwmac_probe(struct pla
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
-@@ -372,7 +372,7 @@ static int meson8b_dwmac_probe(struct pl
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
-@@ -118,7 +118,7 @@ static int oxnas_dwmac_probe(struct plat
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
-@@ -461,7 +461,7 @@ static int qcom_ethqos_probe(struct plat
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat)) {
-               dev_err(&pdev->dev, "dt configuration failed\n");
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
-@@ -1396,7 +1396,7 @@ static int rk_gmac_probe(struct platform
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
-@@ -398,7 +398,7 @@ static int socfpga_dwmac_probe(struct pl
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
-@@ -325,7 +325,7 @@ static int sti_dwmac_probe(struct platfo
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
-@@ -371,7 +371,7 @@ static int stm32_dwmac_probe(struct plat
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
-@@ -1202,7 +1202,7 @@ static int sun8i_dwmac_probe(struct plat
-       if (ret)
-               return -EINVAL;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
-@@ -108,7 +108,7 @@ static int sun7i_gmac_probe(struct platf
-       if (ret)
-               return ret;
--      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-       if (IS_ERR(plat_dat))
-               return PTR_ERR(plat_dat);
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-@@ -25,7 +25,7 @@
- struct stmmac_resources {
-       void __iomem *addr;
--      const char *mac;
-+      u8 mac[ETH_ALEN];
-       int wol_irq;
-       int lpi_irq;
-       int irq;
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -4904,7 +4904,7 @@ int stmmac_dvr_probe(struct device *devi
-       priv->wol_irq = res->wol_irq;
-       priv->lpi_irq = res->lpi_irq;
--      if (!IS_ERR_OR_NULL(res->mac))
-+      if (!is_zero_ether_addr(res->mac))
-               memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
-       dev_set_drvdata(device, priv->dev);
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-@@ -394,7 +394,7 @@ static int stmmac_of_get_mac_mode(struct
-  * set some private fields that will be used by the main at runtime.
-  */
- struct plat_stmmacenet_data *
--stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
-+stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
- {
-       struct device_node *np = pdev->dev.of_node;
-       struct plat_stmmacenet_data *plat;
-@@ -406,12 +406,12 @@ stmmac_probe_config_dt(struct platform_d
-       if (!plat)
-               return ERR_PTR(-ENOMEM);
--      *mac = of_get_mac_address(np);
--      if (IS_ERR(*mac)) {
--              if (PTR_ERR(*mac) == -EPROBE_DEFER)
--                      return ERR_CAST(*mac);
-+      rc = of_get_mac_address(np, mac);
-+      if (rc) {
-+              if (rc == -EPROBE_DEFER)
-+                      return ERR_PTR(rc);
--              *mac = NULL;
-+              eth_zero_addr(mac);
-       }
-       phy_mode = device_get_phy_mode(&pdev->dev);
-@@ -643,7 +643,7 @@ void stmmac_remove_config_dt(struct plat
- }
- #else
- struct plat_stmmacenet_data *
--stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
-+stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
- {
-       return ERR_PTR(-EINVAL);
- }
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
-@@ -12,7 +12,7 @@
- #include "stmmac.h"
- struct plat_stmmacenet_data *
--stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
-+stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
- void stmmac_remove_config_dt(struct platform_device *pdev,
-                            struct plat_stmmacenet_data *plat);
---- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
-+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
-@@ -1741,7 +1741,6 @@ static int am65_cpsw_nuss_init_slave_por
-       for_each_child_of_node(node, port_np) {
-               struct am65_cpsw_port *port;
--              const void *mac_addr;
-               u32 port_id;
-               /* it is not a slave port node, continue */
-@@ -1820,15 +1819,15 @@ static int am65_cpsw_nuss_init_slave_por
-                       return ret;
-               }
--              mac_addr = of_get_mac_address(port_np);
--              if (!IS_ERR(mac_addr)) {
--                      ether_addr_copy(port->slave.mac_addr, mac_addr);
--              } else if (am65_cpsw_am654_get_efuse_macid(port_np,
--                                                         port->port_id,
--                                                         port->slave.mac_addr) ||
--                         !is_valid_ether_addr(port->slave.mac_addr)) {
--                      random_ether_addr(port->slave.mac_addr);
--                      dev_err(dev, "Use random MAC address\n");
-+              ret = of_get_mac_address(port_np, port->slave.mac_addr);
-+              if (ret) {
-+                      am65_cpsw_am654_get_efuse_macid(port_np,
-+                                                      port->port_id,
-+                                                      port->slave.mac_addr);
-+                      if (!is_valid_ether_addr(port->slave.mac_addr)) {
-+                              random_ether_addr(port->slave.mac_addr);
-+                              dev_err(dev, "Use random MAC address\n");
-+                      }
-               }
-       }
-       of_node_put(node);
---- a/drivers/net/ethernet/ti/cpsw.c
-+++ b/drivers/net/ethernet/ti/cpsw.c
-@@ -1306,7 +1306,6 @@ static int cpsw_probe_dt(struct cpsw_pla
-       for_each_available_child_of_node(node, slave_node) {
-               struct cpsw_slave_data *slave_data = data->slave_data + i;
--              const void *mac_addr = NULL;
-               int lenp;
-               const __be32 *parp;
-@@ -1378,10 +1377,8 @@ static int cpsw_probe_dt(struct cpsw_pla
-               }
- no_phy_slave:
--              mac_addr = of_get_mac_address(slave_node);
--              if (!IS_ERR(mac_addr)) {
--                      ether_addr_copy(slave_data->mac_addr, mac_addr);
--              } else {
-+              ret = of_get_mac_address(slave_node, slave_data->mac_addr);
-+              if (ret) {
-                       ret = ti_cm_get_macid(&pdev->dev, i,
-                                             slave_data->mac_addr);
-                       if (ret)
---- a/drivers/net/ethernet/ti/cpsw_new.c
-+++ b/drivers/net/ethernet/ti/cpsw_new.c
-@@ -1267,7 +1267,6 @@ static int cpsw_probe_dt(struct cpsw_com
-       for_each_child_of_node(tmp_node, port_np) {
-               struct cpsw_slave_data *slave_data;
--              const void *mac_addr;
-               u32 port_id;
-               ret = of_property_read_u32(port_np, "reg", &port_id);
-@@ -1326,10 +1325,8 @@ static int cpsw_probe_dt(struct cpsw_com
-                       goto err_node_put;
-               }
--              mac_addr = of_get_mac_address(port_np);
--              if (!IS_ERR(mac_addr)) {
--                      ether_addr_copy(slave_data->mac_addr, mac_addr);
--              } else {
-+              ret = of_get_mac_address(port_np, slave_data->mac_addr);
-+              if (ret) {
-                       ret = ti_cm_get_macid(dev, port_id - 1,
-                                             slave_data->mac_addr);
-                       if (ret)
---- a/drivers/net/ethernet/ti/davinci_emac.c
-+++ b/drivers/net/ethernet/ti/davinci_emac.c
-@@ -1687,7 +1687,6 @@ davinci_emac_of_get_pdata(struct platfor
-       const struct of_device_id *match;
-       const struct emac_platform_data *auxdata;
-       struct emac_platform_data *pdata = NULL;
--      const u8 *mac_addr;
-       if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
-               return dev_get_platdata(&pdev->dev);
-@@ -1699,11 +1698,8 @@ davinci_emac_of_get_pdata(struct platfor
-       np = pdev->dev.of_node;
-       pdata->version = EMAC_VERSION_2;
--      if (!is_valid_ether_addr(pdata->mac_addr)) {
--              mac_addr = of_get_mac_address(np);
--              if (!IS_ERR(mac_addr))
--                      ether_addr_copy(pdata->mac_addr, mac_addr);
--      }
-+      if (!is_valid_ether_addr(pdata->mac_addr))
-+              of_get_mac_address(np, pdata->mac_addr);
-       of_property_read_u32(np, "ti,davinci-ctrl-reg-offset",
-                            &pdata->ctrl_reg_offset);
---- a/drivers/net/ethernet/ti/netcp_core.c
-+++ b/drivers/net/ethernet/ti/netcp_core.c
-@@ -1966,7 +1966,6 @@ static int netcp_create_interface(struct
-       struct resource res;
-       void __iomem *efuse = NULL;
-       u32 efuse_mac = 0;
--      const void *mac_addr;
-       u8 efuse_mac_addr[6];
-       u32 temp[2];
-       int ret = 0;
-@@ -2036,10 +2035,8 @@ static int netcp_create_interface(struct
-               devm_iounmap(dev, efuse);
-               devm_release_mem_region(dev, res.start, size);
-       } else {
--              mac_addr = of_get_mac_address(node_interface);
--              if (!IS_ERR(mac_addr))
--                      ether_addr_copy(ndev->dev_addr, mac_addr);
--              else
-+              ret = of_get_mac_address(node_interface, ndev->dev_addr);
-+              if (ret)
-                       eth_random_addr(ndev->dev_addr);
-       }
---- a/drivers/net/ethernet/wiznet/w5100-spi.c
-+++ b/drivers/net/ethernet/wiznet/w5100-spi.c
-@@ -423,8 +423,14 @@ static int w5100_spi_probe(struct spi_de
-       const struct of_device_id *of_id;
-       const struct w5100_ops *ops;
-       kernel_ulong_t driver_data;
-+      const void *mac = NULL;
-+      u8 tmpmac[ETH_ALEN];
-       int priv_size;
--      const void *mac = of_get_mac_address(spi->dev.of_node);
-+      int ret;
-+
-+      ret = of_get_mac_address(spi->dev.of_node, tmpmac);
-+      if (!ret)
-+              mac = tmpmac;
-       if (spi->dev.of_node) {
-               of_id = of_match_device(w5100_of_match, &spi->dev);
---- a/drivers/net/ethernet/wiznet/w5100.c
-+++ b/drivers/net/ethernet/wiznet/w5100.c
-@@ -1159,7 +1159,7 @@ int w5100_probe(struct device *dev, cons
-       INIT_WORK(&priv->setrx_work, w5100_setrx_work);
-       INIT_WORK(&priv->restart_work, w5100_restart_work);
--      if (!IS_ERR_OR_NULL(mac_addr))
-+      if (mac_addr)
-               memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
-       else
-               eth_hw_addr_random(ndev);
---- a/drivers/net/ethernet/xilinx/ll_temac_main.c
-+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
-@@ -438,7 +438,7 @@ static void temac_do_set_mac_address(str
- static int temac_init_mac_address(struct net_device *ndev, const void *address)
- {
--      ether_addr_copy(ndev->dev_addr, address);
-+      memcpy(ndev->dev_addr, address, ETH_ALEN);
-       if (!is_valid_ether_addr(ndev->dev_addr))
-               eth_hw_addr_random(ndev);
-       temac_do_set_mac_address(ndev);
-@@ -1370,7 +1370,7 @@ static int temac_probe(struct platform_d
-       struct device_node *temac_np = dev_of_node(&pdev->dev), *dma_np;
-       struct temac_local *lp;
-       struct net_device *ndev;
--      const void *addr;
-+      u8 addr[ETH_ALEN];
-       __be32 *p;
-       bool little_endian;
-       int rc = 0;
-@@ -1561,8 +1561,8 @@ static int temac_probe(struct platform_d
-       if (temac_np) {
-               /* Retrieve the MAC address */
--              addr = of_get_mac_address(temac_np);
--              if (IS_ERR(addr)) {
-+              rc = of_get_mac_address(temac_np, addr);
-+              if (rc) {
-                       dev_err(&pdev->dev, "could not find MAC address\n");
-                       return -ENODEV;
-               }
---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-@@ -1803,8 +1803,8 @@ static int axienet_probe(struct platform
-       struct device_node *np;
-       struct axienet_local *lp;
-       struct net_device *ndev;
--      const void *mac_addr;
-       struct resource *ethres;
-+      u8 mac_addr[ETH_ALEN];
-       int addr_width = 32;
-       u32 value;
-@@ -2004,13 +2004,14 @@ static int axienet_probe(struct platform
-               dev_info(&pdev->dev, "Ethernet core IRQ not defined\n");
-       /* Retrieve the MAC address */
--      mac_addr = of_get_mac_address(pdev->dev.of_node);
--      if (IS_ERR(mac_addr)) {
--              dev_warn(&pdev->dev, "could not find MAC address property: %ld\n",
--                       PTR_ERR(mac_addr));
--              mac_addr = NULL;
-+      ret = of_get_mac_address(pdev->dev.of_node, mac_addr);
-+      if (!ret) {
-+              axienet_set_mac_address(ndev, mac_addr);
-+      } else {
-+              dev_warn(&pdev->dev, "could not find MAC address property: %d\n",
-+                       ret);
-+              axienet_set_mac_address(ndev, NULL);
-       }
--      axienet_set_mac_address(ndev, mac_addr);
-       lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
-       lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
---- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
-+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
-@@ -1113,7 +1113,6 @@ static int xemaclite_of_probe(struct pla
-       struct net_device *ndev = NULL;
-       struct net_local *lp = NULL;
-       struct device *dev = &ofdev->dev;
--      const void *mac_address;
-       int rc = 0;
-@@ -1155,12 +1154,9 @@ static int xemaclite_of_probe(struct pla
-       lp->next_rx_buf_to_use = 0x0;
-       lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong");
-       lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong");
--      mac_address = of_get_mac_address(ofdev->dev.of_node);
--      if (!IS_ERR(mac_address)) {
--              /* Set the MAC address. */
--              ether_addr_copy(ndev->dev_addr, mac_address);
--      } else {
-+      rc = of_get_mac_address(ofdev->dev.of_node, ndev->dev_addr);
-+      if (rc) {
-               dev_warn(dev, "No MAC address found, using random\n");
-               eth_hw_addr_random(ndev);
-       }
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -618,7 +618,6 @@ static int ath9k_of_init(struct ath_soft
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-       enum ath_bus_type bus_type = common->bus_ops->ath_bus_type;
--      const char *mac;
-       char eeprom_name[100];
-       int ret;
-@@ -641,9 +640,7 @@ static int ath9k_of_init(struct ath_soft
-               ah->ah_flags |= AH_NO_EEP_SWAP;
-       }
--      mac = of_get_mac_address(np);
--      if (!IS_ERR(mac))
--              ether_addr_copy(common->macaddr, mac);
-+      of_get_mac_address(np, common->macaddr);
-       return 0;
- }
---- a/drivers/net/wireless/mediatek/mt76/eeprom.c
-+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
-@@ -90,15 +90,9 @@ out_put_node:
- void
- mt76_eeprom_override(struct mt76_dev *dev)
- {
--#ifdef CONFIG_OF
-       struct device_node *np = dev->dev->of_node;
--      const u8 *mac = NULL;
--      if (np)
--              mac = of_get_mac_address(np);
--      if (!IS_ERR_OR_NULL(mac))
--              ether_addr_copy(dev->macaddr, mac);
--#endif
-+      of_get_mac_address(np, dev->macaddr);
-       if (!is_valid_ether_addr(dev->macaddr)) {
-               eth_random_addr(dev->macaddr);
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -990,11 +990,7 @@ static void rt2x00lib_rate(struct ieee80
- void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
- {
--      const char *mac_addr;
--
--      mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
--      if (!IS_ERR(mac_addr))
--              ether_addr_copy(eeprom_mac_addr, mac_addr);
-+      of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr);
-       if (!is_valid_ether_addr(eeprom_mac_addr)) {
-               eth_random_addr(eeprom_mac_addr);
---- a/drivers/of/of_net.c
-+++ b/drivers/of/of_net.c
-@@ -45,37 +45,29 @@ int of_get_phy_mode(struct device_node *
- }
- EXPORT_SYMBOL_GPL(of_get_phy_mode);
--static const void *of_get_mac_addr(struct device_node *np, const char *name)
-+static int of_get_mac_addr(struct device_node *np, const char *name, u8 *addr)
- {
-       struct property *pp = of_find_property(np, name, NULL);
--      if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value))
--              return pp->value;
--      return NULL;
-+      if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value)) {
-+              memcpy(addr, pp->value, ETH_ALEN);
-+              return 0;
-+      }
-+      return -ENODEV;
- }
--static const void *of_get_mac_addr_nvmem(struct device_node *np)
-+static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
- {
--      int ret;
--      const void *mac;
--      u8 nvmem_mac[ETH_ALEN];
-       struct platform_device *pdev = of_find_device_by_node(np);
-+      int ret;
-       if (!pdev)
--              return ERR_PTR(-ENODEV);
-+              return -ENODEV;
--      ret = nvmem_get_mac_address(&pdev->dev, &nvmem_mac);
--      if (ret) {
--              put_device(&pdev->dev);
--              return ERR_PTR(ret);
--      }
--
--      mac = devm_kmemdup(&pdev->dev, nvmem_mac, ETH_ALEN, GFP_KERNEL);
-+      ret = nvmem_get_mac_address(&pdev->dev, addr);
-       put_device(&pdev->dev);
--      if (!mac)
--              return ERR_PTR(-ENOMEM);
--      return mac;
-+      return ret;
- }
- /**
-@@ -98,24 +90,27 @@ static const void *of_get_mac_addr_nvmem
-  * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
-  * but is all zeros.
-  *
-- * Return: Will be a valid pointer on success and ERR_PTR in case of error.
-+ * Return: 0 on success and errno in case of error.
- */
--const void *of_get_mac_address(struct device_node *np)
-+int of_get_mac_address(struct device_node *np, u8 *addr)
- {
--      const void *addr;
--
--      addr = of_get_mac_addr(np, "mac-address");
--      if (addr)
--              return addr;
-+      int ret;
--      addr = of_get_mac_addr(np, "local-mac-address");
--      if (addr)
--              return addr;
-+      if (!np)
-+              return -ENODEV;
--      addr = of_get_mac_addr(np, "address");
--      if (addr)
--              return addr;
-+      ret = of_get_mac_addr(np, "mac-address", addr);
-+      if (!ret)
-+              return 0;
-+
-+      ret = of_get_mac_addr(np, "local-mac-address", addr);
-+      if (!ret)
-+              return 0;
-+
-+      ret = of_get_mac_addr(np, "address", addr);
-+      if (!ret)
-+              return 0;
--      return of_get_mac_addr_nvmem(np);
-+      return of_get_mac_addr_nvmem(np, addr);
- }
- EXPORT_SYMBOL(of_get_mac_address);
---- a/drivers/staging/octeon/ethernet.c
-+++ b/drivers/staging/octeon/ethernet.c
-@@ -407,14 +407,10 @@ static int cvm_oct_common_set_mac_addres
- int cvm_oct_common_init(struct net_device *dev)
- {
-       struct octeon_ethernet *priv = netdev_priv(dev);
--      const u8 *mac = NULL;
-+      int ret;
--      if (priv->of_node)
--              mac = of_get_mac_address(priv->of_node);
--
--      if (!IS_ERR_OR_NULL(mac))
--              ether_addr_copy(dev->dev_addr, mac);
--      else
-+      ret = of_get_mac_address(priv->of_node, dev->dev_addr);
-+      if (ret)
-               eth_hw_addr_random(dev);
-       /*
---- a/drivers/staging/wfx/main.c
-+++ b/drivers/staging/wfx/main.c
-@@ -334,7 +334,6 @@ int wfx_probe(struct wfx_dev *wdev)
- {
-       int i;
-       int err;
--      const void *macaddr;
-       struct gpio_desc *gpio_saved;
-       // During first part of boot, gpio_wakeup cannot yet been used. So
-@@ -423,9 +422,9 @@ int wfx_probe(struct wfx_dev *wdev)
-       for (i = 0; i < ARRAY_SIZE(wdev->addresses); i++) {
-               eth_zero_addr(wdev->addresses[i].addr);
--              macaddr = of_get_mac_address(wdev->dev->of_node);
--              if (!IS_ERR_OR_NULL(macaddr)) {
--                      ether_addr_copy(wdev->addresses[i].addr, macaddr);
-+              err = of_get_mac_address(wdev->dev->of_node,
-+                                       wdev->addresses[i].addr);
-+              if (!err) {
-                       wdev->addresses[i].addr[ETH_ALEN - 1] += i;
-               } else {
-                       ether_addr_copy(wdev->addresses[i].addr,
---- a/include/linux/of_net.h
-+++ b/include/linux/of_net.h
-@@ -13,7 +13,7 @@
- struct net_device;
- extern int of_get_phy_mode(struct device_node *np, phy_interface_t *interface);
--extern const void *of_get_mac_address(struct device_node *np);
-+extern int of_get_mac_address(struct device_node *np, u8 *mac);
- extern struct net_device *of_find_net_device_by_node(struct device_node *np);
- #else
- static inline int of_get_phy_mode(struct device_node *np,
-@@ -22,9 +22,9 @@ static inline int of_get_phy_mode(struct
-       return -ENODEV;
- }
--static inline const void *of_get_mac_address(struct device_node *np)
-+static inline int of_get_mac_address(struct device_node *np, u8 *mac)
- {
--      return ERR_PTR(-ENODEV);
-+      return -ENODEV;
- }
- static inline struct net_device *of_find_net_device_by_node(struct device_node *np)
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -208,7 +208,7 @@ struct dsa_port {
-       unsigned int            index;
-       const char              *name;
-       struct dsa_port         *cpu_dp;
--      const char              *mac;
-+      u8                      mac[ETH_ALEN];
-       struct device_node      *dn;
-       unsigned int            ageing_time;
-       bool                    vlan_filtering;
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -288,7 +288,7 @@ static int dsa_port_setup(struct dsa_por
-               break;
-       case DSA_PORT_TYPE_USER:
--              dp->mac = of_get_mac_address(dp->dn);
-+              of_get_mac_address(dp->dn, dp->mac);
-               err = dsa_slave_create(dp);
-               if (err)
-                       break;
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -1855,7 +1855,7 @@ int dsa_slave_create(struct dsa_port *po
-       slave_dev->hw_features |= NETIF_F_HW_TC;
-       slave_dev->features |= NETIF_F_LLTX;
-       slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
--      if (!IS_ERR_OR_NULL(port->mac))
-+      if (!is_zero_ether_addr(port->mac))
-               ether_addr_copy(slave_dev->dev_addr, port->mac);
-       else
-               eth_hw_addr_inherit(slave_dev, master);
---- a/net/ethernet/eth.c
-+++ b/net/ethernet/eth.c
-@@ -506,13 +506,14 @@ unsigned char * __weak arch_get_platform
- int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
- {
--      const unsigned char *addr = NULL;
-+      unsigned char *addr;
-+      int ret;
--      if (dev->of_node)
--              addr = of_get_mac_address(dev->of_node);
--      if (IS_ERR_OR_NULL(addr))
--              addr = arch_get_platform_mac_address();
-+      ret = of_get_mac_address(dev->of_node, mac_addr);
-+      if (!ret)
-+              return 0;
-+      addr = arch_get_platform_mac_address();
-       if (!addr)
-               return -ENODEV;
diff --git a/target/linux/generic/backport-5.10/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch b/target/linux/generic/backport-5.10/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch
deleted file mode 100644 (file)
index 245c5f3..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From f10843e04a075202dbb39dfcee047e3a2fdf5a8d Mon Sep 17 00:00:00 2001
-From: Michael Walle <michael@walle.cc>
-Date: Mon, 12 Apr 2021 19:47:18 +0200
-Subject: of: net: fix of_get_mac_addr_nvmem() for non-platform devices
-
-of_get_mac_address() already supports fetching the MAC address by an
-nvmem provider. But until now, it was just working for platform devices.
-Esp. it was not working for DSA ports and PCI devices. It gets more
-common that PCI devices have a device tree binding since SoCs contain
-integrated root complexes.
-
-Use the nvmem of_* binding to fetch the nvmem cells by a struct
-device_node. We still have to try to read the cell by device first
-because there might be a nvmem_cell_lookup associated with that device.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/of/of_net.c | 35 ++++++++++++++++++++++++++++++-----
- 1 file changed, 30 insertions(+), 5 deletions(-)
-
---- a/drivers/of/of_net.c
-+++ b/drivers/of/of_net.c
-@@ -11,6 +11,7 @@
- #include <linux/phy.h>
- #include <linux/export.h>
- #include <linux/device.h>
-+#include <linux/nvmem-consumer.h>
- /**
-  * of_get_phy_mode - Get phy mode for given device_node
-@@ -59,15 +60,39 @@ static int of_get_mac_addr(struct device
- static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
- {
-       struct platform_device *pdev = of_find_device_by_node(np);
-+      struct nvmem_cell *cell;
-+      const void *mac;
-+      size_t len;
-       int ret;
--      if (!pdev)
--              return -ENODEV;
-+      /* Try lookup by device first, there might be a nvmem_cell_lookup
-+       * associated with a given device.
-+       */
-+      if (pdev) {
-+              ret = nvmem_get_mac_address(&pdev->dev, addr);
-+              put_device(&pdev->dev);
-+              return ret;
-+      }
-+
-+      cell = of_nvmem_cell_get(np, "mac-address");
-+      if (IS_ERR(cell))
-+              return PTR_ERR(cell);
-+
-+      mac = nvmem_cell_read(cell, &len);
-+      nvmem_cell_put(cell);
-+
-+      if (IS_ERR(mac))
-+              return PTR_ERR(mac);
-+
-+      if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
-+              kfree(mac);
-+              return -EINVAL;
-+      }
--      ret = nvmem_get_mac_address(&pdev->dev, addr);
--      put_device(&pdev->dev);
-+      memcpy(addr, mac, ETH_ALEN);
-+      kfree(mac);
--      return ret;
-+      return 0;
- }
- /**
diff --git a/target/linux/generic/backport-5.10/783-v5.15-0001-net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch b/target/linux/generic/backport-5.10/783-v5.15-0001-net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch
deleted file mode 100644 (file)
index 6e7f206..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From 029497e66bdc762e001880e4c85a91f35a54b1e2 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Sun, 19 Sep 2021 13:57:25 +0200
-Subject: [PATCH] net: bgmac-bcma: handle deferred probe error due to
- mac-address
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Due to the inclusion of nvmem handling into the mac-address getter
-function of_get_mac_address() by
-commit d01f449c008a ("of_net: add NVMEM support to of_get_mac_address")
-it is now possible to get a -EPROBE_DEFER return code. Which did cause
-bgmac to assign a random ethernet address.
-
-This exact issue happened on my Meraki MR32. The nvmem provider is
-an EEPROM (at24c64) which gets instantiated once the module
-driver is loaded... This happens once the filesystem becomes available.
-
-With this patch, bgmac_probe() will propagate the -EPROBE_DEFER error.
-Then the driver subsystem will reschedule the probe at a later time.
-
-Cc: Petr Štetiar <ynezz@true.cz>
-Cc: Michael Walle <michael@walle.cc>
-Fixes: d01f449c008a ("of_net: add NVMEM support to of_get_mac_address")
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac-bcma.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
-@@ -129,6 +129,8 @@ static int bgmac_probe(struct bcma_devic
-       bcma_set_drvdata(core, bgmac);
-       err = of_get_mac_address(bgmac->dev->of_node, bgmac->net_dev->dev_addr);
-+      if (err == -EPROBE_DEFER)
-+              return err;
-       /* If no MAC address assigned via device tree, check SPROM */
-       if (err) {
diff --git a/target/linux/generic/backport-5.10/783-v5.15-0002-net-bgmac-platform-handle-mac-address-deferral.patch b/target/linux/generic/backport-5.10/783-v5.15-0002-net-bgmac-platform-handle-mac-address-deferral.patch
deleted file mode 100644 (file)
index bde62f3..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-From 763716a55cb1f480ffe1a9702e6b5d9ea1a80a24 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sat, 25 Sep 2021 11:36:27 +0000
-Subject: [PATCH] net: bgmac-platform: handle mac-address deferral
-
-This patch is a replication of Christian Lamparter's "net: bgmac-bcma:
-handle deferred probe error due to mac-address" patch for the
-bgmac-platform driver [1].
-
-As is the case with the bgmac-bcma driver, this change is to cover the
-scenario where the MAC address cannot yet be discovered due to reliance
-on an nvmem provider which is yet to be instantiated, resulting in a
-random address being assigned that has to be manually overridden.
-
-[1] https://lore.kernel.org/netdev/20210919115725.29064-1-chunkeey@gmail.com
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac-platform.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/bgmac-platform.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
-@@ -193,6 +193,9 @@ static int bgmac_probe(struct platform_d
-       bgmac->dma_dev = &pdev->dev;
-       ret = of_get_mac_address(np, bgmac->net_dev->dev_addr);
-+      if (ret == -EPROBE_DEFER)
-+              return ret;
-+
-       if (ret)
-               dev_warn(&pdev->dev,
-                        "MAC address not present in device tree\n");
diff --git a/target/linux/generic/backport-5.10/784-v5.16-0001-net-bgmac-improve-handling-PHY.patch b/target/linux/generic/backport-5.10/784-v5.16-0001-net-bgmac-improve-handling-PHY.patch
deleted file mode 100644 (file)
index 6788a2e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-From b5375509184dc23d2b7fa0c5ed8763899ccc9674 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 2 Oct 2021 19:58:11 +0200
-Subject: [PATCH] net: bgmac: improve handling PHY
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-1. Use info from DT if available
-
-It allows describing for example a fixed link. It's more accurate than
-just guessing there may be one (depending on a chipset).
-
-2. Verify PHY ID before trying to connect PHY
-
-PHY addr 0x1e (30) is special in Broadcom routers and means a switch
-connected as MDIO devices instead of a real PHY. Don't try connecting to
-it.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac-bcma.c | 33 ++++++++++++++--------
- 1 file changed, 21 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
-@@ -11,6 +11,7 @@
- #include <linux/bcma/bcma.h>
- #include <linux/brcmphy.h>
- #include <linux/etherdevice.h>
-+#include <linux/of_mdio.h>
- #include <linux/of_net.h>
- #include "bgmac.h"
-@@ -86,17 +87,28 @@ static int bcma_phy_connect(struct bgmac
-       struct phy_device *phy_dev;
-       char bus_id[MII_BUS_ID_SIZE + 3];
-+      /* DT info should be the most accurate */
-+      phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
-+                                       bgmac_adjust_link);
-+      if (phy_dev)
-+              return 0;
-+
-       /* Connect to the PHY */
--      snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
--               bgmac->phyaddr);
--      phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
--                            PHY_INTERFACE_MODE_MII);
--      if (IS_ERR(phy_dev)) {
--              dev_err(bgmac->dev, "PHY connection failed\n");
--              return PTR_ERR(phy_dev);
-+      if (bgmac->mii_bus && bgmac->phyaddr != BGMAC_PHY_NOREGS) {
-+              snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
-+                       bgmac->phyaddr);
-+              phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
-+                                    PHY_INTERFACE_MODE_MII);
-+              if (IS_ERR(phy_dev)) {
-+                      dev_err(bgmac->dev, "PHY connection failed\n");
-+                      return PTR_ERR(phy_dev);
-+              }
-+
-+              return 0;
-       }
--      return 0;
-+      /* Assume a fixed link to the switch port */
-+      return bgmac_phy_connect_direct(bgmac);
- }
- static const struct bcma_device_id bgmac_bcma_tbl[] = {
-@@ -297,10 +309,7 @@ static int bgmac_probe(struct bcma_devic
-       bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset;
-       bgmac->get_bus_clock = bcma_bgmac_get_bus_clock;
-       bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32;
--      if (bgmac->mii_bus)
--              bgmac->phy_connect = bcma_phy_connect;
--      else
--              bgmac->phy_connect = bgmac_phy_connect_direct;
-+      bgmac->phy_connect = bcma_phy_connect;
-       err = bgmac_enet_probe(bgmac);
-       if (err)
diff --git a/target/linux/generic/backport-5.10/784-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch b/target/linux/generic/backport-5.10/784-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch
deleted file mode 100644 (file)
index f134828..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-From 45c9d966688e7fad7f24bfc450547d91e4304d0b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 2 Oct 2021 19:58:12 +0200
-Subject: [PATCH] net: bgmac: support MDIO described in DT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Check ethernet controller DT node for "mdio" subnode and use it with
-of_mdiobus_register() when present. That allows specifying MDIO and its
-PHY devices in a standard DT based way.
-
-This is required for BCM53573 SoC support. That family is sometimes
-called Northstar (by marketing?) but is quite different from it. It uses
-different CPU(s) and many different hw blocks.
-
-One of shared blocks in BCM53573 is Ethernet controller. Switch however
-is not SRAB accessible (as it Northstar) but is MDIO attached.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
-@@ -10,6 +10,7 @@
- #include <linux/bcma/bcma.h>
- #include <linux/brcmphy.h>
-+#include <linux/of_mdio.h>
- #include "bgmac.h"
- static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask,
-@@ -211,6 +212,7 @@ struct mii_bus *bcma_mdio_mii_register(s
- {
-       struct bcma_device *core = bgmac->bcma.core;
-       struct mii_bus *mii_bus;
-+      struct device_node *np;
-       int err;
-       mii_bus = mdiobus_alloc();
-@@ -229,7 +231,9 @@ struct mii_bus *bcma_mdio_mii_register(s
-       mii_bus->parent = &core->dev;
-       mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
--      err = mdiobus_register(mii_bus);
-+      np = of_get_child_by_name(core->dev.of_node, "mdio");
-+
-+      err = of_mdiobus_register(mii_bus, np);
-       if (err) {
-               dev_err(&core->dev, "Registration of mii bus failed\n");
-               goto err_free_bus;
diff --git a/target/linux/generic/backport-5.10/785-v5.14-01-net-dsa-qca8k-change-simple-print-to-dev-variant.patch b/target/linux/generic/backport-5.10/785-v5.14-01-net-dsa-qca8k-change-simple-print-to-dev-variant.patch
deleted file mode 100644 (file)
index b8e6d9b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 5d9e068402dcf7354cc8ee66c2152845306d2ccb Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:51 +0200
-Subject: [PATCH] net: dsa: qca8k: change simple print to dev variant
-
-Change pr_err and pr_warn to dev variant.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -701,7 +701,7 @@ qca8k_setup(struct dsa_switch *ds)
-       /* Make sure that port 0 is the cpu port */
-       if (!dsa_is_cpu_port(ds, 0)) {
--              pr_err("port 0 is not the CPU port\n");
-+              dev_err(priv->dev, "port 0 is not the CPU port");
-               return -EINVAL;
-       }
-@@ -711,7 +711,7 @@ qca8k_setup(struct dsa_switch *ds)
-       priv->regmap = devm_regmap_init(ds->dev, NULL, priv,
-                                       &qca8k_regmap_config);
-       if (IS_ERR(priv->regmap))
--              pr_warn("regmap initialization failed");
-+              dev_warn(priv->dev, "regmap initialization failed");
-       ret = qca8k_setup_mdio_bus(priv);
-       if (ret)
diff --git a/target/linux/generic/backport-5.10/785-v5.14-02-net-dsa-qca8k-use-iopoll-macro-for-qca8k_busy_wait.patch b/target/linux/generic/backport-5.10/785-v5.14-02-net-dsa-qca8k-use-iopoll-macro-for-qca8k_busy_wait.patch
deleted file mode 100644 (file)
index ff8288d..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From 2ad255f2faaffb3af786031fba2e7955454b558a Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:52 +0200
-Subject: [PATCH] net: dsa: qca8k: use iopoll macro for qca8k_busy_wait
-
-Use iopoll macro instead of while loop.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 23 +++++++++++------------
- drivers/net/dsa/qca8k.h |  2 ++
- 2 files changed, 13 insertions(+), 12 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -262,21 +262,20 @@ static struct regmap_config qca8k_regmap
- static int
- qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
- {
--      unsigned long timeout;
-+      u32 val;
-+      int ret;
--      timeout = jiffies + msecs_to_jiffies(20);
-+      ret = read_poll_timeout(qca8k_read, val, !(val & mask),
-+                              0, QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-+                              priv, reg);
--      /* loop until the busy flag has cleared */
--      do {
--              u32 val = qca8k_read(priv, reg);
--              int busy = val & mask;
-+      /* Check if qca8k_read has failed for a different reason
-+       * before returning -ETIMEDOUT
-+       */
-+      if (ret < 0 && val < 0)
-+              return val;
--              if (!busy)
--                      break;
--              cond_resched();
--      } while (!time_after_eq(jiffies, timeout));
--
--      return time_after_eq(jiffies, timeout);
-+      return ret;
- }
- static void
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -18,6 +18,8 @@
- #define PHY_ID_QCA8337                                        0x004dd036
- #define QCA8K_ID_QCA8337                              0x13
-+#define QCA8K_BUSY_WAIT_TIMEOUT                               20
-+
- #define QCA8K_NUM_FDB_RECORDS                         2048
- #define QCA8K_CPU_PORT                                        0
diff --git a/target/linux/generic/backport-5.10/785-v5.14-03-net-dsa-qca8k-improve-qca8k-read-write-rmw-bus-acces.patch b/target/linux/generic/backport-5.10/785-v5.14-03-net-dsa-qca8k-improve-qca8k-read-write-rmw-bus-acces.patch
deleted file mode 100644 (file)
index c403589..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-From 504bf65931824eda83494e5b5d75686e27ace03e Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:53 +0200
-Subject: [PATCH] net: dsa: qca8k: improve qca8k read/write/rmw bus access
-
-Put bus in local variable to improve faster access to the mdio bus.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 29 ++++++++++++++++-------------
- 1 file changed, 16 insertions(+), 13 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -142,17 +142,18 @@ qca8k_set_page(struct mii_bus *bus, u16
- static u32
- qca8k_read(struct qca8k_priv *priv, u32 reg)
- {
-+      struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
-       u32 val;
-       qca8k_split_addr(reg, &r1, &r2, &page);
--      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      qca8k_set_page(priv->bus, page);
--      val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
-+      qca8k_set_page(bus, page);
-+      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
--      mutex_unlock(&priv->bus->mdio_lock);
-+      mutex_unlock(&bus->mdio_lock);
-       return val;
- }
-@@ -160,35 +161,37 @@ qca8k_read(struct qca8k_priv *priv, u32
- static void
- qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
- {
-+      struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
-       qca8k_split_addr(reg, &r1, &r2, &page);
--      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      qca8k_set_page(priv->bus, page);
--      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
-+      qca8k_set_page(bus, page);
-+      qca8k_mii_write32(bus, 0x10 | r2, r1, val);
--      mutex_unlock(&priv->bus->mdio_lock);
-+      mutex_unlock(&bus->mdio_lock);
- }
- static u32
- qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 val)
- {
-+      struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
-       u32 ret;
-       qca8k_split_addr(reg, &r1, &r2, &page);
--      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      qca8k_set_page(priv->bus, page);
--      ret = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
-+      qca8k_set_page(bus, page);
-+      ret = qca8k_mii_read32(bus, 0x10 | r2, r1);
-       ret &= ~mask;
-       ret |= val;
--      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, ret);
-+      qca8k_mii_write32(bus, 0x10 | r2, r1, ret);
--      mutex_unlock(&priv->bus->mdio_lock);
-+      mutex_unlock(&bus->mdio_lock);
-       return ret;
- }
diff --git a/target/linux/generic/backport-5.10/785-v5.14-04-net-dsa-qca8k-handle-qca8k_set_page-errors.patch b/target/linux/generic/backport-5.10/785-v5.14-04-net-dsa-qca8k-handle-qca8k_set_page-errors.patch
deleted file mode 100644 (file)
index 6be494a..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-From ba5707ec58cfb6853dff41c2aae72deb6a03d389 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:54 +0200
-Subject: [PATCH] net: dsa: qca8k: handle qca8k_set_page errors
-
-With a remote possibility, the set_page function can fail. Since this is
-a critical part of the write/read qca8k regs, propagate the error and
-terminate any read/write operation.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 33 ++++++++++++++++++++++++++-------
- 1 file changed, 26 insertions(+), 7 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -127,16 +127,23 @@ qca8k_mii_write32(struct mii_bus *bus, i
-                                   "failed to write qca8k 32bit register\n");
- }
--static void
-+static int
- qca8k_set_page(struct mii_bus *bus, u16 page)
- {
-+      int ret;
-+
-       if (page == qca8k_current_page)
--              return;
-+              return 0;
--      if (bus->write(bus, 0x18, 0, page) < 0)
-+      ret = bus->write(bus, 0x18, 0, page);
-+      if (ret < 0) {
-               dev_err_ratelimited(&bus->dev,
-                                   "failed to set qca8k page\n");
-+              return ret;
-+      }
-+
-       qca8k_current_page = page;
-+      return 0;
- }
- static u32
-@@ -150,11 +157,14 @@ qca8k_read(struct qca8k_priv *priv, u32
-       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      qca8k_set_page(bus, page);
-+      val = qca8k_set_page(bus, page);
-+      if (val < 0)
-+              goto exit;
-+
-       val = qca8k_mii_read32(bus, 0x10 | r2, r1);
-+exit:
-       mutex_unlock(&bus->mdio_lock);
--
-       return val;
- }
-@@ -163,14 +173,19 @@ qca8k_write(struct qca8k_priv *priv, u32
- {
-       struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
-+      int ret;
-       qca8k_split_addr(reg, &r1, &r2, &page);
-       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      qca8k_set_page(bus, page);
-+      ret = qca8k_set_page(bus, page);
-+      if (ret < 0)
-+              goto exit;
-+
-       qca8k_mii_write32(bus, 0x10 | r2, r1, val);
-+exit:
-       mutex_unlock(&bus->mdio_lock);
- }
-@@ -185,12 +200,16 @@ qca8k_rmw(struct qca8k_priv *priv, u32 r
-       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      qca8k_set_page(bus, page);
-+      ret = qca8k_set_page(bus, page);
-+      if (ret < 0)
-+              goto exit;
-+
-       ret = qca8k_mii_read32(bus, 0x10 | r2, r1);
-       ret &= ~mask;
-       ret |= val;
-       qca8k_mii_write32(bus, 0x10 | r2, r1, ret);
-+exit:
-       mutex_unlock(&bus->mdio_lock);
-       return ret;
diff --git a/target/linux/generic/backport-5.10/785-v5.14-05-net-dsa-qca8k-handle-error-with-qca8k_read-operation.patch b/target/linux/generic/backport-5.10/785-v5.14-05-net-dsa-qca8k-handle-error-with-qca8k_read-operation.patch
deleted file mode 100644 (file)
index 3349b78..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-From 028f5f8ef44fcf87a456772cbb9f0d90a0a22884 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:55 +0200
-Subject: [PATCH] net: dsa: qca8k: handle error with qca8k_read operation
-
-qca8k_read can fail. Rework any user to handle error values and
-correctly return.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 73 ++++++++++++++++++++++++++++++++---------
- 1 file changed, 58 insertions(+), 15 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -231,8 +231,13 @@ static int
- qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
-+      int ret;
-+
-+      ret = qca8k_read(priv, reg);
-+      if (ret < 0)
-+              return ret;
--      *val = qca8k_read(priv, reg);
-+      *val = ret;
-       return 0;
- }
-@@ -300,15 +305,20 @@ qca8k_busy_wait(struct qca8k_priv *priv,
-       return ret;
- }
--static void
-+static int
- qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
- {
--      u32 reg[4];
-+      u32 reg[4], val;
-       int i;
-       /* load the ARL table into an array */
--      for (i = 0; i < 4; i++)
--              reg[i] = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4));
-+      for (i = 0; i < 4; i++) {
-+              val = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4));
-+              if (val < 0)
-+                      return val;
-+
-+              reg[i] = val;
-+      }
-       /* vid - 83:72 */
-       fdb->vid = (reg[2] >> QCA8K_ATU_VID_S) & QCA8K_ATU_VID_M;
-@@ -323,6 +333,8 @@ qca8k_fdb_read(struct qca8k_priv *priv,
-       fdb->mac[3] = (reg[0] >> QCA8K_ATU_ADDR3_S) & 0xff;
-       fdb->mac[4] = (reg[0] >> QCA8K_ATU_ADDR4_S) & 0xff;
-       fdb->mac[5] = reg[0] & 0xff;
-+
-+      return 0;
- }
- static void
-@@ -374,6 +386,8 @@ qca8k_fdb_access(struct qca8k_priv *priv
-       /* Check for table full violation when adding an entry */
-       if (cmd == QCA8K_FDB_LOAD) {
-               reg = qca8k_read(priv, QCA8K_REG_ATU_FUNC);
-+              if (reg < 0)
-+                      return reg;
-               if (reg & QCA8K_ATU_FUNC_FULL)
-                       return -1;
-       }
-@@ -388,10 +402,10 @@ qca8k_fdb_next(struct qca8k_priv *priv,
-       qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
-       ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
--      if (ret >= 0)
--              qca8k_fdb_read(priv, fdb);
-+      if (ret < 0)
-+              return ret;
--      return ret;
-+      return qca8k_fdb_read(priv, fdb);
- }
- static int
-@@ -449,6 +463,8 @@ qca8k_vlan_access(struct qca8k_priv *pri
-       /* Check for table full violation when adding an entry */
-       if (cmd == QCA8K_VLAN_LOAD) {
-               reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
-+              if (reg < 0)
-+                      return reg;
-               if (reg & QCA8K_VTU_FUNC1_FULL)
-                       return -ENOMEM;
-       }
-@@ -475,6 +491,8 @@ qca8k_vlan_add(struct qca8k_priv *priv,
-               goto out;
-       reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
-+      if (reg < 0)
-+              return reg;
-       reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-       reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
-       if (untagged)
-@@ -506,6 +524,8 @@ qca8k_vlan_del(struct qca8k_priv *priv,
-               goto out;
-       reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
-+      if (reg < 0)
-+              return reg;
-       reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
-       reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
-                       QCA8K_VTU_FUNC0_EG_MODE_S(port);
-@@ -621,8 +641,11 @@ qca8k_mdio_read(struct qca8k_priv *priv,
-                           QCA8K_MDIO_MASTER_BUSY))
-               return -ETIMEDOUT;
--      val = (qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL) &
--              QCA8K_MDIO_MASTER_DATA_MASK);
-+      val = qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL);
-+      if (val < 0)
-+              return val;
-+
-+      val &= QCA8K_MDIO_MASTER_DATA_MASK;
-       return val;
- }
-@@ -978,6 +1001,8 @@ qca8k_phylink_mac_link_state(struct dsa_
-       u32 reg;
-       reg = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port));
-+      if (reg < 0)
-+              return reg;
-       state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
-       state->an_complete = state->link;
-@@ -1078,18 +1103,26 @@ qca8k_get_ethtool_stats(struct dsa_switc
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-       const struct qca8k_mib_desc *mib;
--      u32 reg, i;
-+      u32 reg, i, val;
-       u64 hi;
-       for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
-               mib = &ar8327_mib[i];
-               reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
--              data[i] = qca8k_read(priv, reg);
-+              val = qca8k_read(priv, reg);
-+              if (val < 0)
-+                      continue;
-+
-               if (mib->size == 2) {
-                       hi = qca8k_read(priv, reg + 4);
--                      data[i] |= hi << 32;
-+                      if (hi < 0)
-+                              continue;
-               }
-+
-+              data[i] = val;
-+              if (mib->size == 2)
-+                      data[i] |= hi << 32;
-       }
- }
-@@ -1107,18 +1140,25 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-       u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
-+      int ret = 0;
-       u32 reg;
-       mutex_lock(&priv->reg_mutex);
-       reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL);
-+      if (reg < 0) {
-+              ret = reg;
-+              goto exit;
-+      }
-+
-       if (eee->eee_enabled)
-               reg |= lpi_en;
-       else
-               reg &= ~lpi_en;
-       qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
--      mutex_unlock(&priv->reg_mutex);
--      return 0;
-+exit:
-+      mutex_unlock(&priv->reg_mutex);
-+      return ret;
- }
- static int
-@@ -1456,6 +1496,9 @@ qca8k_sw_probe(struct mdio_device *mdiod
-       /* read the switches ID register */
-       id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
-+      if (id < 0)
-+              return id;
-+
-       id >>= QCA8K_MASK_CTRL_ID_S;
-       id &= QCA8K_MASK_CTRL_ID_M;
-       if (id != QCA8K_ID_QCA8337)
diff --git a/target/linux/generic/backport-5.10/785-v5.14-06-net-dsa-qca8k-handle-error-with-qca8k_write-operatio.patch b/target/linux/generic/backport-5.10/785-v5.14-06-net-dsa-qca8k-handle-error-with-qca8k_write-operatio.patch
deleted file mode 100644 (file)
index 1e0e224..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-From d7805757c75c76e9518fc1023a29f0c4eed5b581 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:56 +0200
-Subject: [PATCH] net: dsa: qca8k: handle error with qca8k_write operation
-
-qca8k_write can fail. Rework any user to handle error values and
-correctly return.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 102 ++++++++++++++++++++++++++--------------
- 1 file changed, 67 insertions(+), 35 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -168,7 +168,7 @@ exit:
-       return val;
- }
--static void
-+static int
- qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
- {
-       struct mii_bus *bus = priv->bus;
-@@ -187,6 +187,7 @@ qca8k_write(struct qca8k_priv *priv, u32
- exit:
-       mutex_unlock(&bus->mdio_lock);
-+      return ret;
- }
- static u32
-@@ -247,9 +248,7 @@ qca8k_regmap_write(void *ctx, uint32_t r
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
--      qca8k_write(priv, reg, val);
--
--      return 0;
-+      return qca8k_write(priv, reg, val);
- }
- static const struct regmap_range qca8k_readable_ranges[] = {
-@@ -367,6 +366,7 @@ static int
- qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
- {
-       u32 reg;
-+      int ret;
-       /* Set the command and FDB index */
-       reg = QCA8K_ATU_FUNC_BUSY;
-@@ -377,7 +377,9 @@ qca8k_fdb_access(struct qca8k_priv *priv
-       }
-       /* Write the function register triggering the table access */
--      qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
-+      ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
-+      if (ret)
-+              return ret;
-       /* wait for completion */
-       if (qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY))
-@@ -447,6 +449,7 @@ static int
- qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
- {
-       u32 reg;
-+      int ret;
-       /* Set the command and VLAN index */
-       reg = QCA8K_VTU_FUNC1_BUSY;
-@@ -454,7 +457,9 @@ qca8k_vlan_access(struct qca8k_priv *pri
-       reg |= vid << QCA8K_VTU_FUNC1_VID_S;
-       /* Write the function register triggering the table access */
--      qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-+      ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
-+      if (ret)
-+              return ret;
-       /* wait for completion */
-       if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
-@@ -502,7 +507,9 @@ qca8k_vlan_add(struct qca8k_priv *priv,
-               reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
-                               QCA8K_VTU_FUNC0_EG_MODE_S(port);
--      qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+      ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+      if (ret)
-+              return ret;
-       ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
- out:
-@@ -545,7 +552,9 @@ qca8k_vlan_del(struct qca8k_priv *priv,
-       if (del) {
-               ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
-       } else {
--              qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+              ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-+              if (ret)
-+                      return ret;
-               ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-       }
-@@ -555,15 +564,20 @@ out:
-       return ret;
- }
--static void
-+static int
- qca8k_mib_init(struct qca8k_priv *priv)
- {
-+      int ret;
-+
-       mutex_lock(&priv->reg_mutex);
-       qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
-       qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-       qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
--      qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
-+
-+      ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
-+
-       mutex_unlock(&priv->reg_mutex);
-+      return ret;
- }
- static void
-@@ -600,6 +614,7 @@ static int
- qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
- {
-       u32 phy, val;
-+      int ret;
-       if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-               return -EINVAL;
-@@ -613,7 +628,9 @@ qca8k_mdio_write(struct qca8k_priv *priv
-             QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
-             QCA8K_MDIO_MASTER_DATA(data);
--      qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
-+      ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
-+      if (ret)
-+              return ret;
-       return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-               QCA8K_MDIO_MASTER_BUSY);
-@@ -623,6 +640,7 @@ static int
- qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
- {
-       u32 phy, val;
-+      int ret;
-       if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-               return -EINVAL;
-@@ -635,7 +653,9 @@ qca8k_mdio_read(struct qca8k_priv *priv,
-             QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-             QCA8K_MDIO_MASTER_REG_ADDR(regnum);
--      qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
-+      ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
-+      if (ret)
-+              return ret;
-       if (qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-                           QCA8K_MDIO_MASTER_BUSY))
-@@ -766,12 +786,18 @@ qca8k_setup(struct dsa_switch *ds)
-                     QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-       /* Enable MIB counters */
--      qca8k_mib_init(priv);
-+      ret = qca8k_mib_init(priv);
-+      if (ret)
-+              dev_warn(priv->dev, "mib init failed");
-       /* Enable QCA header mode on the cpu port */
--      qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
--                  QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
--                  QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
-+      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
-+                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
-+                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
-+      if (ret) {
-+              dev_err(priv->dev, "failed enabling QCA header mode");
-+              return ret;
-+      }
-       /* Disable forwarding by default on all ports */
-       for (i = 0; i < QCA8K_NUM_PORTS; i++)
-@@ -783,11 +809,13 @@ qca8k_setup(struct dsa_switch *ds)
-               qca8k_port_set_status(priv, i, 0);
-       /* Forward all unknown frames to CPU port for Linux processing */
--      qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
--                  BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
--                  BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
--                  BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
--                  BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
-+      ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-+                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
-+                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
-+                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
-+                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
-+      if (ret)
-+              return ret;
-       /* Setup connection between CPU port & user ports */
-       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-@@ -815,16 +843,20 @@ qca8k_setup(struct dsa_switch *ds)
-                       qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
-                                 0xfff << shift,
-                                 QCA8K_PORT_VID_DEF << shift);
--                      qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
--                                  QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
--                                  QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-+                      ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-+                                        QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
-+                                        QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-+                      if (ret)
-+                              return ret;
-               }
-       }
-       /* Setup our port MTUs to match power on defaults */
-       for (i = 0; i < QCA8K_NUM_PORTS; i++)
-               priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
--      qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
-+      ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
-+      if (ret)
-+              dev_warn(priv->dev, "failed setting MTU settings");
-       /* Flush the FDB table */
-       qca8k_fdb_flush(priv);
-@@ -1140,8 +1172,8 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-       u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
--      int ret = 0;
-       u32 reg;
-+      int ret;
-       mutex_lock(&priv->reg_mutex);
-       reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL);
-@@ -1154,7 +1186,7 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
-               reg |= lpi_en;
-       else
-               reg &= ~lpi_en;
--      qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
-+      ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
- exit:
-       mutex_unlock(&priv->reg_mutex);
-@@ -1284,9 +1316,7 @@ qca8k_port_change_mtu(struct dsa_switch
-                       mtu = priv->port_mtu[i];
-       /* Include L2 header / FCS length */
--      qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
--
--      return 0;
-+      return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
- }
- static int
diff --git a/target/linux/generic/backport-5.10/785-v5.14-07-net-dsa-qca8k-handle-error-with-qca8k_rmw-operation.patch b/target/linux/generic/backport-5.10/785-v5.14-07-net-dsa-qca8k-handle-error-with-qca8k_rmw-operation.patch
deleted file mode 100644 (file)
index 506966f..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-From aaf421425cbdec4eb6fd75a29e65c2867b0b7bbd Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:57 +0200
-Subject: [PATCH] net: dsa: qca8k: handle error with qca8k_rmw operation
-
-qca8k_rmw can fail. Rework any user to handle error values and
-correctly return. Change qca8k_rmw to return the error code or 0 instead
-of the reg value. The reg returned by qca8k_rmw wasn't used anywhere,
-so this doesn't cause any functional change.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 133 +++++++++++++++++++++++++---------------
- 1 file changed, 83 insertions(+), 50 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -190,12 +190,13 @@ exit:
-       return ret;
- }
--static u32
--qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 val)
-+static int
-+qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
- {
-       struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
--      u32 ret;
-+      u32 val;
-+      int ret;
-       qca8k_split_addr(reg, &r1, &r2, &page);
-@@ -205,10 +206,15 @@ qca8k_rmw(struct qca8k_priv *priv, u32 r
-       if (ret < 0)
-               goto exit;
--      ret = qca8k_mii_read32(bus, 0x10 | r2, r1);
--      ret &= ~mask;
--      ret |= val;
--      qca8k_mii_write32(bus, 0x10 | r2, r1, ret);
-+      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
-+      if (val < 0) {
-+              ret = val;
-+              goto exit;
-+      }
-+
-+      val &= ~mask;
-+      val |= write_val;
-+      qca8k_mii_write32(bus, 0x10 | r2, r1, val);
- exit:
-       mutex_unlock(&bus->mdio_lock);
-@@ -216,16 +222,16 @@ exit:
-       return ret;
- }
--static void
-+static int
- qca8k_reg_set(struct qca8k_priv *priv, u32 reg, u32 val)
- {
--      qca8k_rmw(priv, reg, 0, val);
-+      return qca8k_rmw(priv, reg, 0, val);
- }
--static void
-+static int
- qca8k_reg_clear(struct qca8k_priv *priv, u32 reg, u32 val)
- {
--      qca8k_rmw(priv, reg, val, 0);
-+      return qca8k_rmw(priv, reg, val, 0);
- }
- static int
-@@ -570,12 +576,19 @@ qca8k_mib_init(struct qca8k_priv *priv)
-       int ret;
-       mutex_lock(&priv->reg_mutex);
--      qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
-+      ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
-+      if (ret)
-+              goto exit;
-+
-       qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
--      qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-+
-+      ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-+      if (ret)
-+              goto exit;
-       ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
-+exit:
-       mutex_unlock(&priv->reg_mutex);
-       return ret;
- }
-@@ -747,9 +760,8 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
-                * a dt-overlay and driver reload changed the configuration
-                */
--              qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
--                              QCA8K_MDIO_MASTER_EN);
--              return 0;
-+              return qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
-+                                     QCA8K_MDIO_MASTER_EN);
-       }
-       priv->ops.phy_read = qca8k_phy_read;
-@@ -782,8 +794,12 @@ qca8k_setup(struct dsa_switch *ds)
-               return ret;
-       /* Enable CPU Port */
--      qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
--                    QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-+      ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
-+                          QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-+      if (ret) {
-+              dev_err(priv->dev, "failed enabling CPU port");
-+              return ret;
-+      }
-       /* Enable MIB counters */
-       ret = qca8k_mib_init(priv);
-@@ -800,9 +816,12 @@ qca8k_setup(struct dsa_switch *ds)
-       }
-       /* Disable forwarding by default on all ports */
--      for (i = 0; i < QCA8K_NUM_PORTS; i++)
--              qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
--                        QCA8K_PORT_LOOKUP_MEMBER, 0);
-+      for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+              ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+                              QCA8K_PORT_LOOKUP_MEMBER, 0);
-+              if (ret)
-+                      return ret;
-+      }
-       /* Disable MAC by default on all ports */
-       for (i = 1; i < QCA8K_NUM_PORTS; i++)
-@@ -821,28 +840,37 @@ qca8k_setup(struct dsa_switch *ds)
-       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-               /* CPU port gets connected to all user ports of the switch */
-               if (dsa_is_cpu_port(ds, i)) {
--                      qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
--                                QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-+                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
-+                                      QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-+                      if (ret)
-+                              return ret;
-               }
-               /* Individual user ports get connected to CPU port only */
-               if (dsa_is_user_port(ds, i)) {
-                       int shift = 16 * (i % 2);
--                      qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
--                                QCA8K_PORT_LOOKUP_MEMBER,
--                                BIT(QCA8K_CPU_PORT));
-+                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+                                      QCA8K_PORT_LOOKUP_MEMBER,
-+                                      BIT(QCA8K_CPU_PORT));
-+                      if (ret)
-+                              return ret;
-                       /* Enable ARP Auto-learning by default */
--                      qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i),
--                                    QCA8K_PORT_LOOKUP_LEARN);
-+                      ret = qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-+                                          QCA8K_PORT_LOOKUP_LEARN);
-+                      if (ret)
-+                              return ret;
-                       /* For port based vlans to work we need to set the
-                        * default egress vid
-                        */
--                      qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
--                                0xfff << shift,
--                                QCA8K_PORT_VID_DEF << shift);
-+                      ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
-+                                      0xfff << shift,
-+                                      QCA8K_PORT_VID_DEF << shift);
-+                      if (ret)
-+                              return ret;
-+
-                       ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-                                         QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
-                                         QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
-@@ -1234,7 +1262,7 @@ qca8k_port_bridge_join(struct dsa_switch
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-       int port_mask = BIT(QCA8K_CPU_PORT);
--      int i;
-+      int i, ret;
-       for (i = 1; i < QCA8K_NUM_PORTS; i++) {
-               if (dsa_to_port(ds, i)->bridge_dev != br)
-@@ -1242,17 +1270,20 @@ qca8k_port_bridge_join(struct dsa_switch
-               /* Add this port to the portvlan mask of the other ports
-                * in the bridge
-                */
--              qca8k_reg_set(priv,
--                            QCA8K_PORT_LOOKUP_CTRL(i),
--                            BIT(port));
-+              ret = qca8k_reg_set(priv,
-+                                  QCA8K_PORT_LOOKUP_CTRL(i),
-+                                  BIT(port));
-+              if (ret)
-+                      return ret;
-               if (i != port)
-                       port_mask |= BIT(i);
-       }
-+
-       /* Add all other ports to this ports portvlan mask */
--      qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
--                QCA8K_PORT_LOOKUP_MEMBER, port_mask);
-+      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
-+                      QCA8K_PORT_LOOKUP_MEMBER, port_mask);
--      return 0;
-+      return ret;
- }
- static void
diff --git a/target/linux/generic/backport-5.10/785-v5.14-08-net-dsa-qca8k-handle-error-from-qca8k_busy_wait.patch b/target/linux/generic/backport-5.10/785-v5.14-08-net-dsa-qca8k-handle-error-from-qca8k_busy_wait.patch
deleted file mode 100644 (file)
index 360ce1d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-From b7c818d194927bdc60ed15db55bb8654496a36b7 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:58 +0200
-Subject: [PATCH] net: dsa: qca8k: handle error from qca8k_busy_wait
-
-Propagate errors from qca8k_busy_wait instead of hardcoding return
-value.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 21 +++++++++++++--------
- 1 file changed, 13 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -388,8 +388,9 @@ qca8k_fdb_access(struct qca8k_priv *priv
-               return ret;
-       /* wait for completion */
--      if (qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY))
--              return -1;
-+      ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
-+      if (ret)
-+              return ret;
-       /* Check for table full violation when adding an entry */
-       if (cmd == QCA8K_FDB_LOAD) {
-@@ -468,8 +469,9 @@ qca8k_vlan_access(struct qca8k_priv *pri
-               return ret;
-       /* wait for completion */
--      if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
--              return -ETIMEDOUT;
-+      ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
-+      if (ret)
-+              return ret;
-       /* Check for table full violation when adding an entry */
-       if (cmd == QCA8K_VLAN_LOAD) {
-@@ -580,7 +582,9 @@ qca8k_mib_init(struct qca8k_priv *priv)
-       if (ret)
-               goto exit;
--      qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-+      ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
-+      if (ret)
-+              goto exit;
-       ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
-       if (ret)
-@@ -670,9 +674,10 @@ qca8k_mdio_read(struct qca8k_priv *priv,
-       if (ret)
-               return ret;
--      if (qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
--                          QCA8K_MDIO_MASTER_BUSY))
--              return -ETIMEDOUT;
-+      ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-+                            QCA8K_MDIO_MASTER_BUSY);
-+      if (ret)
-+              return ret;
-       val = qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL);
-       if (val < 0)
diff --git a/target/linux/generic/backport-5.10/785-v5.14-09-net-dsa-qca8k-add-support-for-qca8327-switch.patch b/target/linux/generic/backport-5.10/785-v5.14-09-net-dsa-qca8k-add-support-for-qca8327-switch.patch
deleted file mode 100644 (file)
index 7230585..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-From 6e82a457e06252b59102486767539cc9c2aba60b Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 22:59:59 +0200
-Subject: [PATCH] net: dsa: qca8k: add support for qca8327 switch
-
-qca8327 switch is a low tier version of the more recent qca8337.
-It does share the same regs used by the qca8k driver and can be
-supported with minimal change.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 23 ++++++++++++++++++++---
- drivers/net/dsa/qca8k.h |  6 ++++++
- 2 files changed, 26 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1533,6 +1533,7 @@ static const struct dsa_switch_ops qca8k
- static int
- qca8k_sw_probe(struct mdio_device *mdiodev)
- {
-+      const struct qca8k_match_data *data;
-       struct qca8k_priv *priv;
-       u32 id;
-@@ -1560,6 +1561,11 @@ qca8k_sw_probe(struct mdio_device *mdiod
-               gpiod_set_value_cansleep(priv->reset_gpio, 0);
-       }
-+      /* get the switches ID from the compatible */
-+      data = of_device_get_match_data(&mdiodev->dev);
-+      if (!data)
-+              return -ENODEV;
-+
-       /* read the switches ID register */
-       id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
-       if (id < 0)
-@@ -1567,8 +1573,10 @@ qca8k_sw_probe(struct mdio_device *mdiod
-       id >>= QCA8K_MASK_CTRL_ID_S;
-       id &= QCA8K_MASK_CTRL_ID_M;
--      if (id != QCA8K_ID_QCA8337)
-+      if (id != data->id) {
-+              dev_err(&mdiodev->dev, "Switch id detected %x but expected %x", id, data->id);
-               return -ENODEV;
-+      }
-       priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-       if (!priv->ds)
-@@ -1634,9 +1642,18 @@ static int qca8k_resume(struct device *d
- static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
-                        qca8k_suspend, qca8k_resume);
-+static const struct qca8k_match_data qca832x = {
-+      .id = QCA8K_ID_QCA8327,
-+};
-+
-+static const struct qca8k_match_data qca833x = {
-+      .id = QCA8K_ID_QCA8337,
-+};
-+
- static const struct of_device_id qca8k_of_match[] = {
--      { .compatible = "qca,qca8334" },
--      { .compatible = "qca,qca8337" },
-+      { .compatible = "qca,qca8327", .data = &qca832x },
-+      { .compatible = "qca,qca8334", .data = &qca833x },
-+      { .compatible = "qca,qca8337", .data = &qca833x },
-       { /* sentinel */ },
- };
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -15,6 +15,8 @@
- #define QCA8K_NUM_PORTS                                       7
- #define QCA8K_MAX_MTU                                 9000
-+#define PHY_ID_QCA8327                                        0x004dd034
-+#define QCA8K_ID_QCA8327                              0x12
- #define PHY_ID_QCA8337                                        0x004dd036
- #define QCA8K_ID_QCA8337                              0x13
-@@ -213,6 +215,10 @@ struct ar8xxx_port_status {
-       int enabled;
- };
-+struct qca8k_match_data {
-+      u8 id;
-+};
-+
- struct qca8k_priv {
-       struct regmap *regmap;
-       struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.10/785-v5.14-10-devicetree-net-dsa-qca8k-Document-new-compatible-qca.patch b/target/linux/generic/backport-5.10/785-v5.14-10-devicetree-net-dsa-qca8k-Document-new-compatible-qca.patch
deleted file mode 100644 (file)
index 3c4a14b..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-From 227a9ffc1bc77037339530607fe129af3824620e Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:00 +0200
-Subject: [PATCH] devicetree: net: dsa: qca8k: Document new compatible qca8327
-
-Add support for qca8327 in the compatible list.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Acked-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -3,6 +3,7 @@
- Required properties:
- - compatible: should be one of:
-+    "qca,qca8327"
-     "qca,qca8334"
-     "qca,qca8337"
diff --git a/target/linux/generic/backport-5.10/785-v5.14-11-net-dsa-qca8k-add-priority-tweak-to-qca8337-switch.patch b/target/linux/generic/backport-5.10/785-v5.14-11-net-dsa-qca8k-add-priority-tweak-to-qca8337-switch.patch
deleted file mode 100644 (file)
index cd3050e..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-From 83a3ceb39b2495171aabe9446271b94c678354f3 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:01 +0200
-Subject: [PATCH] net: dsa: qca8k: add priority tweak to qca8337 switch
-
-The port 5 of the qca8337 have some problem in flood condition. The
-original legacy driver had some specific buffer and priority settings
-for the different port suggested by the QCA switch team. Add this
-missing settings to improve switch stability under load condition.
-The packet priority tweak is only needed for the qca8337 switch and
-other qca8k switch are not affected.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 47 +++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h | 25 ++++++++++++++++++++++
- 2 files changed, 72 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -779,6 +779,7 @@ qca8k_setup(struct dsa_switch *ds)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-       int ret, i;
-+      u32 mask;
-       /* Make sure that port 0 is the cpu port */
-       if (!dsa_is_cpu_port(ds, 0)) {
-@@ -884,6 +885,51 @@ qca8k_setup(struct dsa_switch *ds)
-               }
-       }
-+      /* The port 5 of the qca8337 have some problem in flood condition. The
-+       * original legacy driver had some specific buffer and priority settings
-+       * for the different port suggested by the QCA switch team. Add this
-+       * missing settings to improve switch stability under load condition.
-+       * This problem is limited to qca8337 and other qca8k switch are not affected.
-+       */
-+      if (priv->switch_id == QCA8K_ID_QCA8337) {
-+              for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+                      switch (i) {
-+                      /* The 2 CPU port and port 5 requires some different
-+                       * priority than any other ports.
-+                       */
-+                      case 0:
-+                      case 5:
-+                      case 6:
-+                              mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e);
-+                              break;
-+                      default:
-+                              mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) |
-+                                      QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19);
-+                      }
-+                      qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask);
-+
-+                      mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) |
-+                      QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-+                      QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-+                      QCA8K_PORT_HOL_CTRL1_WRED_EN;
-+                      qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i),
-+                                QCA8K_PORT_HOL_CTRL1_ING_BUF |
-+                                QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
-+                                QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
-+                                QCA8K_PORT_HOL_CTRL1_WRED_EN,
-+                                mask);
-+              }
-+      }
-+
-       /* Setup our port MTUs to match power on defaults */
-       for (i = 0; i < QCA8K_NUM_PORTS; i++)
-               priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
-@@ -1578,6 +1624,7 @@ qca8k_sw_probe(struct mdio_device *mdiod
-               return -ENODEV;
-       }
-+      priv->switch_id = id;
-       priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-       if (!priv->ds)
-               return -ENOMEM;
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -168,6 +168,30 @@
- #define   QCA8K_PORT_LOOKUP_STATE                     GENMASK(18, 16)
- #define   QCA8K_PORT_LOOKUP_LEARN                     BIT(20)
-+#define QCA8K_REG_PORT_HOL_CTRL0(_i)                  (0x970 + (_i) * 0x8)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF            GENMASK(3, 0)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI0(x)             ((x) << 0)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF            GENMASK(7, 4)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI1(x)             ((x) << 4)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF            GENMASK(11, 8)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI2(x)             ((x) << 8)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF            GENMASK(15, 12)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI3(x)             ((x) << 12)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF            GENMASK(19, 16)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI4(x)             ((x) << 16)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF            GENMASK(23, 20)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PRI5(x)             ((x) << 20)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF            GENMASK(29, 24)
-+#define   QCA8K_PORT_HOL_CTRL0_EG_PORT(x)             ((x) << 24)
-+
-+#define QCA8K_REG_PORT_HOL_CTRL1(_i)                  (0x974 + (_i) * 0x8)
-+#define   QCA8K_PORT_HOL_CTRL1_ING_BUF                        GENMASK(3, 0)
-+#define   QCA8K_PORT_HOL_CTRL1_ING(x)                 ((x) << 0)
-+#define   QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN          BIT(6)
-+#define   QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN         BIT(7)
-+#define   QCA8K_PORT_HOL_CTRL1_WRED_EN                        BIT(8)
-+#define   QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN           BIT(16)
-+
- /* Pkt edit registers */
- #define QCA8K_EGRESS_VLAN(x)                          (0x0c70 + (4 * (x / 2)))
-@@ -220,6 +244,7 @@ struct qca8k_match_data {
- };
- struct qca8k_priv {
-+      u8 switch_id;
-       struct regmap *regmap;
-       struct mii_bus *bus;
-       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/785-v5.14-12-net-dsa-qca8k-limit-port5-delay-to-qca8337.patch b/target/linux/generic/backport-5.10/785-v5.14-12-net-dsa-qca8k-limit-port5-delay-to-qca8337.patch
deleted file mode 100644 (file)
index d25edbb..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From 5bf9ff3b9fb5ecb67a1a3517b26db3a00f2a2f11 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:02 +0200
-Subject: [PATCH] net: dsa: qca8k: limit port5 delay to qca8337
-
-Limit port5 rx delay to qca8337. This is taken from the legacy QSDK code
-that limits the rx delay on port5 to only this particular switch version,
-on other switch only the tx and rx delay for port0 are needed.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1003,8 +1003,10 @@ qca8k_phylink_mac_config(struct dsa_swit
-                           QCA8K_PORT_PAD_RGMII_EN |
-                           QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
-                           QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
--              qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
--                          QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-+              /* QCA8337 requires to set rgmii rx delay */
-+              if (priv->switch_id == QCA8K_ID_QCA8337)
-+                      qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-+                                  QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-               break;
-       case PHY_INTERFACE_MODE_SGMII:
-       case PHY_INTERFACE_MODE_1000BASEX:
diff --git a/target/linux/generic/backport-5.10/785-v5.14-13-net-dsa-qca8k-add-GLOBAL_FC-settings-needed-for-qca8.patch b/target/linux/generic/backport-5.10/785-v5.14-13-net-dsa-qca8k-add-GLOBAL_FC-settings-needed-for-qca8.patch
deleted file mode 100644 (file)
index 2b393d2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0fc57e4b5e39461fc0a54aae0afe4241363a7267 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:03 +0200
-Subject: [PATCH] net: dsa: qca8k: add GLOBAL_FC settings needed for qca8327
-
-Switch qca8327 needs special settings for the GLOBAL_FC_THRES regs.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 10 ++++++++++
- drivers/net/dsa/qca8k.h |  6 ++++++
- 2 files changed, 16 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -930,6 +930,16 @@ qca8k_setup(struct dsa_switch *ds)
-               }
-       }
-+      /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
-+      if (priv->switch_id == QCA8K_ID_QCA8327) {
-+              mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) |
-+                     QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496);
-+              qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH,
-+                        QCA8K_GLOBAL_FC_GOL_XON_THRES_S |
-+                        QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S,
-+                        mask);
-+      }
-+
-       /* Setup our port MTUs to match power on defaults */
-       for (i = 0; i < QCA8K_NUM_PORTS; i++)
-               priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -168,6 +168,12 @@
- #define   QCA8K_PORT_LOOKUP_STATE                     GENMASK(18, 16)
- #define   QCA8K_PORT_LOOKUP_LEARN                     BIT(20)
-+#define QCA8K_REG_GLOBAL_FC_THRESH                    0x800
-+#define   QCA8K_GLOBAL_FC_GOL_XON_THRES(x)            ((x) << 16)
-+#define   QCA8K_GLOBAL_FC_GOL_XON_THRES_S             GENMASK(24, 16)
-+#define   QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x)           ((x) << 0)
-+#define   QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S            GENMASK(8, 0)
-+
- #define QCA8K_REG_PORT_HOL_CTRL0(_i)                  (0x970 + (_i) * 0x8)
- #define   QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF            GENMASK(3, 0)
- #define   QCA8K_PORT_HOL_CTRL0_EG_PRI0(x)             ((x) << 0)
diff --git a/target/linux/generic/backport-5.10/785-v5.14-14-net-dsa-qca8k-add-support-for-switch-rev.patch b/target/linux/generic/backport-5.10/785-v5.14-14-net-dsa-qca8k-add-support-for-switch-rev.patch
deleted file mode 100644 (file)
index ed9b818..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-From 95ffeaf18b3bb90eeef52cbf7d79ccc9d0345ff5 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:04 +0200
-Subject: [PATCH] net: dsa: qca8k: add support for switch rev
-
-qca8k internal phy driver require some special debug value to be set
-based on the switch revision. Rework the switch id read function to
-also read the chip revision.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 53 ++++++++++++++++++++++++++---------------
- drivers/net/dsa/qca8k.h |  7 ++++--
- 2 files changed, 39 insertions(+), 21 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1588,12 +1588,40 @@ static const struct dsa_switch_ops qca8k
-       .phylink_mac_link_up    = qca8k_phylink_mac_link_up,
- };
-+static int qca8k_read_switch_id(struct qca8k_priv *priv)
-+{
-+      const struct qca8k_match_data *data;
-+      u32 val;
-+      u8 id;
-+
-+      /* get the switches ID from the compatible */
-+      data = of_device_get_match_data(priv->dev);
-+      if (!data)
-+              return -ENODEV;
-+
-+      val = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
-+      if (val < 0)
-+              return -ENODEV;
-+
-+      id = QCA8K_MASK_CTRL_DEVICE_ID(val & QCA8K_MASK_CTRL_DEVICE_ID_MASK);
-+      if (id != data->id) {
-+              dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id);
-+              return -ENODEV;
-+      }
-+
-+      priv->switch_id = id;
-+
-+      /* Save revision to communicate to the internal PHY driver */
-+      priv->switch_revision = (val & QCA8K_MASK_CTRL_REV_ID_MASK);
-+
-+      return 0;
-+}
-+
- static int
- qca8k_sw_probe(struct mdio_device *mdiodev)
- {
--      const struct qca8k_match_data *data;
-       struct qca8k_priv *priv;
--      u32 id;
-+      int ret;
-       /* allocate the private data struct so that we can probe the switches
-        * ID register
-@@ -1619,24 +1647,11 @@ qca8k_sw_probe(struct mdio_device *mdiod
-               gpiod_set_value_cansleep(priv->reset_gpio, 0);
-       }
--      /* get the switches ID from the compatible */
--      data = of_device_get_match_data(&mdiodev->dev);
--      if (!data)
--              return -ENODEV;
-+      /* Check the detected switch id */
-+      ret = qca8k_read_switch_id(priv);
-+      if (ret)
-+              return ret;
--      /* read the switches ID register */
--      id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
--      if (id < 0)
--              return id;
--
--      id >>= QCA8K_MASK_CTRL_ID_S;
--      id &= QCA8K_MASK_CTRL_ID_M;
--      if (id != data->id) {
--              dev_err(&mdiodev->dev, "Switch id detected %x but expected %x", id, data->id);
--              return -ENODEV;
--      }
--
--      priv->switch_id = id;
-       priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
-       if (!priv->ds)
-               return -ENOMEM;
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -30,8 +30,10 @@
- /* Global control registers */
- #define QCA8K_REG_MASK_CTRL                           0x000
--#define   QCA8K_MASK_CTRL_ID_M                                0xff
--#define   QCA8K_MASK_CTRL_ID_S                                8
-+#define   QCA8K_MASK_CTRL_REV_ID_MASK                 GENMASK(7, 0)
-+#define   QCA8K_MASK_CTRL_REV_ID(x)                   ((x) >> 0)
-+#define   QCA8K_MASK_CTRL_DEVICE_ID_MASK              GENMASK(15, 8)
-+#define   QCA8K_MASK_CTRL_DEVICE_ID(x)                        ((x) >> 8)
- #define QCA8K_REG_PORT0_PAD_CTRL                      0x004
- #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
- #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
-@@ -251,6 +253,7 @@ struct qca8k_match_data {
- struct qca8k_priv {
-       u8 switch_id;
-+      u8 switch_revision;
-       struct regmap *regmap;
-       struct mii_bus *bus;
-       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/785-v5.14-15-net-dsa-qca8k-add-ethernet-ports-fallback-to-setup_m.patch b/target/linux/generic/backport-5.10/785-v5.14-15-net-dsa-qca8k-add-ethernet-ports-fallback-to-setup_m.patch
deleted file mode 100644 (file)
index 629cb32..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From 1ee0591a1093c2448642c33433483e9260275f7b Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:05 +0200
-Subject: [PATCH] net: dsa: qca8k: add ethernet-ports fallback to
- setup_mdio_bus
-
-Dsa now also supports ethernet-ports. Add this new binding as a fallback
-if the ports node can't be found.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -719,6 +719,9 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
-       ports = of_get_child_by_name(priv->dev->of_node, "ports");
-       if (!ports)
-+              ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports");
-+
-+      if (!ports)
-               return -EINVAL;
-       for_each_available_child_of_node(ports, port) {
diff --git a/target/linux/generic/backport-5.10/785-v5.14-16-net-dsa-qca8k-make-rgmii-delay-configurable.patch b/target/linux/generic/backport-5.10/785-v5.14-16-net-dsa-qca8k-make-rgmii-delay-configurable.patch
deleted file mode 100644 (file)
index 6dc2dc6..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-From e4b9977cee1583da38a6e9118078bb728aaccf7b Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:06 +0200
-Subject: [PATCH] net: dsa: qca8k: make rgmii delay configurable
-
-The legacy qsdk code used a different delay instead of the max value.
-Qsdk use 1 ns for rx and 2 ns for tx. Make these values configurable
-using the standard rx/tx-internal-delay-ps ethernet binding and apply
-qsdk values by default. The connected gmac doesn't add any delay so no
-additional delay is added to tx/rx.
-On this switch the delay is actually in ns so value should be in the
-1000 order. Any value converted from ps to ns by dividing it by 1000
-as the switch max value for delay is 3ns.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 82 ++++++++++++++++++++++++++++++++++++++++-
- drivers/net/dsa/qca8k.h | 11 +++---
- 2 files changed, 86 insertions(+), 7 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -778,6 +778,68 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
- }
- static int
-+qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv)
-+{
-+      struct device_node *port_dn;
-+      phy_interface_t mode;
-+      struct dsa_port *dp;
-+      u32 val;
-+
-+      /* CPU port is already checked */
-+      dp = dsa_to_port(priv->ds, 0);
-+
-+      port_dn = dp->dn;
-+
-+      /* Check if port 0 is set to the correct type */
-+      of_get_phy_mode(port_dn, &mode);
-+      if (mode != PHY_INTERFACE_MODE_RGMII_ID &&
-+          mode != PHY_INTERFACE_MODE_RGMII_RXID &&
-+          mode != PHY_INTERFACE_MODE_RGMII_TXID) {
-+              return 0;
-+      }
-+
-+      switch (mode) {
-+      case PHY_INTERFACE_MODE_RGMII_ID:
-+      case PHY_INTERFACE_MODE_RGMII_RXID:
-+              if (of_property_read_u32(port_dn, "rx-internal-delay-ps", &val))
-+                      val = 2;
-+              else
-+                      /* Switch regs accept value in ns, convert ps to ns */
-+                      val = val / 1000;
-+
-+              if (val > QCA8K_MAX_DELAY) {
-+                      dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
-+                      val = 3;
-+              }
-+
-+              priv->rgmii_rx_delay = val;
-+              /* Stop here if we need to check only for rx delay */
-+              if (mode != PHY_INTERFACE_MODE_RGMII_ID)
-+                      break;
-+
-+              fallthrough;
-+      case PHY_INTERFACE_MODE_RGMII_TXID:
-+              if (of_property_read_u32(port_dn, "tx-internal-delay-ps", &val))
-+                      val = 1;
-+              else
-+                      /* Switch regs accept value in ns, convert ps to ns */
-+                      val = val / 1000;
-+
-+              if (val > QCA8K_MAX_DELAY) {
-+                      dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
-+                      val = 3;
-+              }
-+
-+              priv->rgmii_tx_delay = val;
-+              break;
-+      default:
-+              return 0;
-+      }
-+
-+      return 0;
-+}
-+
-+static int
- qca8k_setup(struct dsa_switch *ds)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-@@ -802,6 +864,10 @@ qca8k_setup(struct dsa_switch *ds)
-       if (ret)
-               return ret;
-+      ret = qca8k_setup_of_rgmii_delay(priv);
-+      if (ret)
-+              return ret;
-+
-       /* Enable CPU Port */
-       ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
-                           QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-@@ -970,6 +1036,8 @@ qca8k_phylink_mac_config(struct dsa_swit
-       case 0: /* 1st CPU port */
-               if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-                   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+                  state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+                  state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-                   state->interface != PHY_INTERFACE_MODE_SGMII)
-                       return;
-@@ -985,6 +1053,8 @@ qca8k_phylink_mac_config(struct dsa_swit
-       case 6: /* 2nd CPU port / external PHY */
-               if (state->interface != PHY_INTERFACE_MODE_RGMII &&
-                   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+                  state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+                  state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-                   state->interface != PHY_INTERFACE_MODE_SGMII &&
-                   state->interface != PHY_INTERFACE_MODE_1000BASEX)
-                       return;
-@@ -1008,14 +1078,18 @@ qca8k_phylink_mac_config(struct dsa_swit
-               qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
-               break;
-       case PHY_INTERFACE_MODE_RGMII_ID:
-+      case PHY_INTERFACE_MODE_RGMII_TXID:
-+      case PHY_INTERFACE_MODE_RGMII_RXID:
-               /* RGMII_ID needs internal delay. This is enabled through
-                * PORT5_PAD_CTRL for all ports, rather than individual port
-                * registers
-                */
-               qca8k_write(priv, reg,
-                           QCA8K_PORT_PAD_RGMII_EN |
--                          QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
--                          QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
-+                          QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay) |
-+                          QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay) |
-+                          QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
-+                          QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-               /* QCA8337 requires to set rgmii rx delay */
-               if (priv->switch_id == QCA8K_ID_QCA8337)
-                       qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-@@ -1073,6 +1147,8 @@ qca8k_phylink_validate(struct dsa_switch
-               if (state->interface != PHY_INTERFACE_MODE_NA &&
-                   state->interface != PHY_INTERFACE_MODE_RGMII &&
-                   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+                  state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+                  state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-                   state->interface != PHY_INTERFACE_MODE_SGMII)
-                       goto unsupported;
-               break;
-@@ -1090,6 +1166,8 @@ qca8k_phylink_validate(struct dsa_switch
-               if (state->interface != PHY_INTERFACE_MODE_NA &&
-                   state->interface != PHY_INTERFACE_MODE_RGMII &&
-                   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
-+                  state->interface != PHY_INTERFACE_MODE_RGMII_TXID &&
-+                  state->interface != PHY_INTERFACE_MODE_RGMII_RXID &&
-                   state->interface != PHY_INTERFACE_MODE_SGMII &&
-                   state->interface != PHY_INTERFACE_MODE_1000BASEX)
-                       goto unsupported;
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -38,12 +38,11 @@
- #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
- #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
- #define   QCA8K_PORT_PAD_RGMII_EN                     BIT(26)
--#define   QCA8K_PORT_PAD_RGMII_TX_DELAY(x)            \
--                                              ((0x8 + (x & 0x3)) << 22)
--#define   QCA8K_PORT_PAD_RGMII_RX_DELAY(x)            \
--                                              ((0x10 + (x & 0x3)) << 20)
--#define   QCA8K_MAX_DELAY                             3
-+#define   QCA8K_PORT_PAD_RGMII_TX_DELAY(x)            ((x) << 22)
-+#define   QCA8K_PORT_PAD_RGMII_RX_DELAY(x)            ((x) << 20)
-+#define         QCA8K_PORT_PAD_RGMII_TX_DELAY_EN              BIT(25)
- #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN            BIT(24)
-+#define   QCA8K_MAX_DELAY                             3
- #define   QCA8K_PORT_PAD_SGMII_EN                     BIT(7)
- #define QCA8K_REG_PWS                                 0x010
- #define   QCA8K_PWS_SERDES_AEN_DIS                    BIT(7)
-@@ -254,6 +253,8 @@ struct qca8k_match_data {
- struct qca8k_priv {
-       u8 switch_id;
-       u8 switch_revision;
-+      u8 rgmii_tx_delay;
-+      u8 rgmii_rx_delay;
-       struct regmap *regmap;
-       struct mii_bus *bus;
-       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/785-v5.14-17-net-dsa-qca8k-clear-MASTER_EN-after-phy-read-write.patch b/target/linux/generic/backport-5.10/785-v5.14-17-net-dsa-qca8k-clear-MASTER_EN-after-phy-read-write.patch
deleted file mode 100644 (file)
index 4593da0..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-From 63c33bbfeb6842a956a0eb12901e28eb335bdb18 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:07 +0200
-Subject: [PATCH] net: dsa: qca8k: clear MASTER_EN after phy read/write
-
-Clear MDIO_MASTER_EN bit from MDIO_MASTER_CTRL after read/write
-operation. The MDIO_MASTER_EN bit is not reset after read/write
-operation and the next operation can be wrongly interpreted by the
-switch as a mdio operation. This cause a production of wrong/garbage
-data from the switch and underfined bheavior. (random port drop,
-unplugged port flagged with link up, wrong port speed)
-Also on driver remove the MASTER_CTRL can be left set and cause the
-malfunction of any next driver using the mdio device.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -649,8 +649,14 @@ qca8k_mdio_write(struct qca8k_priv *priv
-       if (ret)
-               return ret;
--      return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
--              QCA8K_MDIO_MASTER_BUSY);
-+      ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-+                            QCA8K_MDIO_MASTER_BUSY);
-+
-+      /* even if the busy_wait timeouts try to clear the MASTER_EN */
-+      qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
-+                      QCA8K_MDIO_MASTER_EN);
-+
-+      return ret;
- }
- static int
-@@ -685,6 +691,10 @@ qca8k_mdio_read(struct qca8k_priv *priv,
-       val &= QCA8K_MDIO_MASTER_DATA_MASK;
-+      /* even if the busy_wait timeouts try to clear the MASTER_EN */
-+      qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
-+                      QCA8K_MDIO_MASTER_EN);
-+
-       return val;
- }
diff --git a/target/linux/generic/backport-5.10/785-v5.14-18-net-dsa-qca8k-dsa-qca8k-protect-MASTER-busy_wait-wit.patch b/target/linux/generic/backport-5.10/785-v5.14-18-net-dsa-qca8k-dsa-qca8k-protect-MASTER-busy_wait-wit.patch
deleted file mode 100644 (file)
index b6684d7..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-From 60df02b6ea4581d72eb7a3ab7204504a54059b72 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:08 +0200
-Subject: [PATCH] net: dsa: qca8k: dsa: qca8k: protect MASTER busy_wait with
- mdio mutex
-
-MDIO_MASTER operation have a dedicated busy wait that is not protected
-by the mdio mutex. This can cause situation where the MASTER operation
-is done and a normal operation is executed between the MASTER read/write
-and the MASTER busy_wait. Rework the qca8k_mdio_read/write function to
-address this issue by binding the lock for the whole MASTER operation
-and not only the mdio read/write common operation.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 68 +++++++++++++++++++++++++++++++++--------
- 1 file changed, 55 insertions(+), 13 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -628,8 +628,31 @@ qca8k_port_to_phy(int port)
- }
- static int
-+qca8k_mdio_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
-+{
-+      u16 r1, r2, page;
-+      u32 val;
-+      int ret;
-+
-+      qca8k_split_addr(reg, &r1, &r2, &page);
-+
-+      ret = read_poll_timeout(qca8k_mii_read32, val, !(val & mask), 0,
-+                              QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
-+                              priv->bus, 0x10 | r2, r1);
-+
-+      /* Check if qca8k_read has failed for a different reason
-+       * before returnting -ETIMEDOUT
-+       */
-+      if (ret < 0 && val < 0)
-+              return val;
-+
-+      return ret;
-+}
-+
-+static int
- qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
- {
-+      u16 r1, r2, page;
-       u32 phy, val;
-       int ret;
-@@ -645,12 +668,21 @@ qca8k_mdio_write(struct qca8k_priv *priv
-             QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
-             QCA8K_MDIO_MASTER_DATA(data);
--      ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
-+      qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
-+
-+      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+
-+      ret = qca8k_set_page(priv->bus, page);
-       if (ret)
--              return ret;
-+              goto exit;
-+
-+      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
--      ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
--                            QCA8K_MDIO_MASTER_BUSY);
-+      ret = qca8k_mdio_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-+                                 QCA8K_MDIO_MASTER_BUSY);
-+
-+exit:
-+      mutex_unlock(&priv->bus->mdio_lock);
-       /* even if the busy_wait timeouts try to clear the MASTER_EN */
-       qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
-@@ -662,6 +694,7 @@ qca8k_mdio_write(struct qca8k_priv *priv
- static int
- qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
- {
-+      u16 r1, r2, page;
-       u32 phy, val;
-       int ret;
-@@ -676,21 +709,30 @@ qca8k_mdio_read(struct qca8k_priv *priv,
-             QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-             QCA8K_MDIO_MASTER_REG_ADDR(regnum);
--      ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
--      if (ret)
--              return ret;
-+      qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
-+
-+      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
--      ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
--                            QCA8K_MDIO_MASTER_BUSY);
-+      ret = qca8k_set_page(priv->bus, page);
-       if (ret)
--              return ret;
-+              goto exit;
--      val = qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL);
--      if (val < 0)
--              return val;
-+      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
-+
-+      ret = qca8k_mdio_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-+                                 QCA8K_MDIO_MASTER_BUSY);
-+      if (ret)
-+              goto exit;
-+      val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
-       val &= QCA8K_MDIO_MASTER_DATA_MASK;
-+exit:
-+      mutex_unlock(&priv->bus->mdio_lock);
-+
-+      if (val >= 0)
-+              val &= QCA8K_MDIO_MASTER_DATA_MASK;
-+
-       /* even if the busy_wait timeouts try to clear the MASTER_EN */
-       qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
-                       QCA8K_MDIO_MASTER_EN);
diff --git a/target/linux/generic/backport-5.10/785-v5.14-19-net-dsa-qca8k-enlarge-mdio-delay-and-timeout.patch b/target/linux/generic/backport-5.10/785-v5.14-19-net-dsa-qca8k-enlarge-mdio-delay-and-timeout.patch
deleted file mode 100644 (file)
index 30eeed3..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-From 617960d72e93de0f3fa52407e2d39e8c43e73b0a Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:09 +0200
-Subject: [PATCH] net: dsa: qca8k: enlarge mdio delay and timeout
-
-The witch require some extra delay after setting page or the next
-read/write can use still use the old page. Add a delay after the
-set_page function to address this as it's done in QSDK legacy driver.
-Some timeouts were notice with VLAN and phy function, enlarge the
-mdio busy wait timeout to fix these problems.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 1 +
- drivers/net/dsa/qca8k.h | 2 +-
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -143,6 +143,7 @@ qca8k_set_page(struct mii_bus *bus, u16
-       }
-       qca8k_current_page = page;
-+      usleep_range(1000, 2000);
-       return 0;
- }
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -20,7 +20,7 @@
- #define PHY_ID_QCA8337                                        0x004dd036
- #define QCA8K_ID_QCA8337                              0x13
--#define QCA8K_BUSY_WAIT_TIMEOUT                               20
-+#define QCA8K_BUSY_WAIT_TIMEOUT                               2000
- #define QCA8K_NUM_FDB_RECORDS                         2048
diff --git a/target/linux/generic/backport-5.10/785-v5.14-20-net-dsa-qca8k-add-support-for-internal-phy-and-inter.patch b/target/linux/generic/backport-5.10/785-v5.14-20-net-dsa-qca8k-add-support-for-internal-phy-and-inter.patch
deleted file mode 100644 (file)
index 88d3c1e..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-From 759bafb8a3226326ca357613bc90acf738f80c32 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:10 +0200
-Subject: [PATCH] net: dsa: qca8k: add support for internal phy and internal
- mdio
-
-Add support to setup_mdio_bus for internal phy declaration. Introduce a
-flag to use the legacy port phy mapping by default and use the direct
-mapping if a mdio node is detected in the switch node. Register a
-dedicated mdio internal mdio bus to address the different mapping
-between port and phy if the mdio node is detected.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 112 +++++++++++++++++++++++++++++-----------
- drivers/net/dsa/qca8k.h |   1 +
- 2 files changed, 83 insertions(+), 30 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -11,6 +11,7 @@
- #include <linux/netdevice.h>
- #include <net/dsa.h>
- #include <linux/of_net.h>
-+#include <linux/of_mdio.h>
- #include <linux/of_platform.h>
- #include <linux/if_bridge.h>
- #include <linux/mdio.h>
-@@ -629,7 +630,7 @@ qca8k_port_to_phy(int port)
- }
- static int
--qca8k_mdio_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
-+qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
- {
-       u16 r1, r2, page;
-       u32 val;
-@@ -639,7 +640,7 @@ qca8k_mdio_busy_wait(struct qca8k_priv *
-       ret = read_poll_timeout(qca8k_mii_read32, val, !(val & mask), 0,
-                               QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
--                              priv->bus, 0x10 | r2, r1);
-+                              bus, 0x10 | r2, r1);
-       /* Check if qca8k_read has failed for a different reason
-        * before returnting -ETIMEDOUT
-@@ -651,19 +652,16 @@ qca8k_mdio_busy_wait(struct qca8k_priv *
- }
- static int
--qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
-+qca8k_mdio_write(struct mii_bus *salve_bus, int phy, int regnum, u16 data)
- {
-+      struct qca8k_priv *priv = salve_bus->priv;
-       u16 r1, r2, page;
--      u32 phy, val;
-+      u32 val;
-       int ret;
-       if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-               return -EINVAL;
--      /* callee is responsible for not passing bad ports,
--       * but we still would like to make spills impossible.
--       */
--      phy = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-       val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-             QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-             QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
-@@ -679,33 +677,29 @@ qca8k_mdio_write(struct qca8k_priv *priv
-       qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
--      ret = qca8k_mdio_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-+      ret = qca8k_mdio_busy_wait(priv->bus, QCA8K_MDIO_MASTER_CTRL,
-                                  QCA8K_MDIO_MASTER_BUSY);
- exit:
--      mutex_unlock(&priv->bus->mdio_lock);
--
-       /* even if the busy_wait timeouts try to clear the MASTER_EN */
--      qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
--                      QCA8K_MDIO_MASTER_EN);
-+      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, 0);
-+
-+      mutex_unlock(&priv->bus->mdio_lock);
-       return ret;
- }
- static int
--qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
-+qca8k_mdio_read(struct mii_bus *salve_bus, int phy, int regnum)
- {
-+      struct qca8k_priv *priv = salve_bus->priv;
-       u16 r1, r2, page;
--      u32 phy, val;
-+      u32 val;
-       int ret;
-       if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
-               return -EINVAL;
--      /* callee is responsible for not passing bad ports,
--       * but we still would like to make spills impossible.
--       */
--      phy = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-       val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
-             QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
-             QCA8K_MDIO_MASTER_REG_ADDR(regnum);
-@@ -720,24 +714,22 @@ qca8k_mdio_read(struct qca8k_priv *priv,
-       qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
--      ret = qca8k_mdio_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-+      ret = qca8k_mdio_busy_wait(priv->bus, QCA8K_MDIO_MASTER_CTRL,
-                                  QCA8K_MDIO_MASTER_BUSY);
-       if (ret)
-               goto exit;
-       val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
--      val &= QCA8K_MDIO_MASTER_DATA_MASK;
- exit:
-+      /* even if the busy_wait timeouts try to clear the MASTER_EN */
-+      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, 0);
-+
-       mutex_unlock(&priv->bus->mdio_lock);
-       if (val >= 0)
-               val &= QCA8K_MDIO_MASTER_DATA_MASK;
--      /* even if the busy_wait timeouts try to clear the MASTER_EN */
--      qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
--                      QCA8K_MDIO_MASTER_EN);
--
-       return val;
- }
-@@ -746,7 +738,14 @@ qca8k_phy_write(struct dsa_switch *ds, i
- {
-       struct qca8k_priv *priv = ds->priv;
--      return qca8k_mdio_write(priv, port, regnum, data);
-+      /* Check if the legacy mapping should be used and the
-+       * port is not correctly mapped to the right PHY in the
-+       * devicetree
-+       */
-+      if (priv->legacy_phy_port_mapping)
-+              port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-+
-+      return qca8k_mdio_write(priv->bus, port, regnum, data);
- }
- static int
-@@ -755,7 +754,14 @@ qca8k_phy_read(struct dsa_switch *ds, in
-       struct qca8k_priv *priv = ds->priv;
-       int ret;
--      ret = qca8k_mdio_read(priv, port, regnum);
-+      /* Check if the legacy mapping should be used and the
-+       * port is not correctly mapped to the right PHY in the
-+       * devicetree
-+       */
-+      if (priv->legacy_phy_port_mapping)
-+              port = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
-+
-+      ret = qca8k_mdio_read(priv->bus, port, regnum);
-       if (ret < 0)
-               return 0xffff;
-@@ -764,10 +770,37 @@ qca8k_phy_read(struct dsa_switch *ds, in
- }
- static int
-+qca8k_mdio_register(struct qca8k_priv *priv, struct device_node *mdio)
-+{
-+      struct dsa_switch *ds = priv->ds;
-+      struct mii_bus *bus;
-+
-+      bus = devm_mdiobus_alloc(ds->dev);
-+
-+      if (!bus)
-+              return -ENOMEM;
-+
-+      bus->priv = (void *)priv;
-+      bus->name = "qca8k slave mii";
-+      bus->read = qca8k_mdio_read;
-+      bus->write = qca8k_mdio_write;
-+      snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d",
-+               ds->index);
-+
-+      bus->parent = ds->dev;
-+      bus->phy_mask = ~ds->phys_mii_mask;
-+
-+      ds->slave_mii_bus = bus;
-+
-+      return devm_of_mdiobus_register(priv->dev, bus, mdio);
-+}
-+
-+static int
- qca8k_setup_mdio_bus(struct qca8k_priv *priv)
- {
-       u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg;
--      struct device_node *ports, *port;
-+      struct device_node *ports, *port, *mdio;
-+      phy_interface_t mode;
-       int err;
-       ports = of_get_child_by_name(priv->dev->of_node, "ports");
-@@ -788,7 +821,10 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
-               if (!dsa_is_user_port(priv->ds, reg))
-                       continue;
--              if (of_property_read_bool(port, "phy-handle"))
-+              of_get_phy_mode(port, &mode);
-+
-+              if (of_property_read_bool(port, "phy-handle") &&
-+                  mode != PHY_INTERFACE_MODE_INTERNAL)
-                       external_mdio_mask |= BIT(reg);
-               else
-                       internal_mdio_mask |= BIT(reg);
-@@ -825,8 +861,23 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
-                                      QCA8K_MDIO_MASTER_EN);
-       }
-+      /* Check if the devicetree declare the port:phy mapping */
-+      mdio = of_get_child_by_name(priv->dev->of_node, "mdio");
-+      if (of_device_is_available(mdio)) {
-+              err = qca8k_mdio_register(priv, mdio);
-+              if (err)
-+                      of_node_put(mdio);
-+
-+              return err;
-+      }
-+
-+      /* If a mapping can't be found the legacy mapping is used,
-+       * using the qca8k_port_to_phy function
-+       */
-+      priv->legacy_phy_port_mapping = true;
-       priv->ops.phy_read = qca8k_phy_read;
-       priv->ops.phy_write = qca8k_phy_write;
-+
-       return 0;
- }
-@@ -1212,7 +1263,8 @@ qca8k_phylink_validate(struct dsa_switch
-       case 5:
-               /* Internal PHY */
-               if (state->interface != PHY_INTERFACE_MODE_NA &&
--                  state->interface != PHY_INTERFACE_MODE_GMII)
-+                  state->interface != PHY_INTERFACE_MODE_GMII &&
-+                  state->interface != PHY_INTERFACE_MODE_INTERNAL)
-                       goto unsupported;
-               break;
-       case 6: /* 2nd CPU port / external PHY */
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -255,6 +255,7 @@ struct qca8k_priv {
-       u8 switch_revision;
-       u8 rgmii_tx_delay;
-       u8 rgmii_rx_delay;
-+      bool legacy_phy_port_mapping;
-       struct regmap *regmap;
-       struct mii_bus *bus;
-       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/785-v5.14-21-devicetree-bindings-dsa-qca8k-Document-internal-mdio.patch b/target/linux/generic/backport-5.10/785-v5.14-21-devicetree-bindings-dsa-qca8k-Document-internal-mdio.patch
deleted file mode 100644 (file)
index 6db01b4..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-From 0c994a28e7518f098c84a3049cb2915780db873a Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:11 +0200
-Subject: [PATCH] devicetree: bindings: dsa: qca8k: Document internal mdio
- definition
-
-Document new way of declare mapping of internal PHY to port.
-The new implementation directly declare the PHY connected to the port
-by adding a node in the switch node. The driver detect this and register
-an internal mdiobus using the mapping defined in the mdio node.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- .../devicetree/bindings/net/dsa/qca8k.txt     | 39 +++++++++++++++++++
- 1 file changed, 39 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -21,6 +21,10 @@ described in dsa/dsa.txt. If the QCA8K s
- mdio-bus each subnode describing a port needs to have a valid phandle
- referencing the internal PHY it is connected to. This is because there's no
- N:N mapping of port and PHY id.
-+To declare the internal mdio-bus configuration, declare a mdio node in the
-+switch node and declare the phandle for the port referencing the internal
-+PHY is connected to. In this config a internal mdio-bus is registered and
-+the mdio MASTER is used as communication.
- Don't use mixed external and internal mdio-bus configurations, as this is
- not supported by the hardware.
-@@ -150,26 +154,61 @@ for the internal master mdio-bus configu
-                               port@1 {
-                                       reg = <1>;
-                                       label = "lan1";
-+                                      phy-mode = "internal";
-+                                      phy-handle = <&phy_port1>;
-                               };
-                               port@2 {
-                                       reg = <2>;
-                                       label = "lan2";
-+                                      phy-mode = "internal";
-+                                      phy-handle = <&phy_port2>;
-                               };
-                               port@3 {
-                                       reg = <3>;
-                                       label = "lan3";
-+                                      phy-mode = "internal";
-+                                      phy-handle = <&phy_port3>;
-                               };
-                               port@4 {
-                                       reg = <4>;
-                                       label = "lan4";
-+                                      phy-mode = "internal";
-+                                      phy-handle = <&phy_port4>;
-                               };
-                               port@5 {
-                                       reg = <5>;
-                                       label = "wan";
-+                                      phy-mode = "internal";
-+                                      phy-handle = <&phy_port5>;
-+                              };
-+                      };
-+
-+                      mdio {
-+                              #address-cells = <1>;
-+                              #size-cells = <0>;
-+
-+                              phy_port1: phy@0 {
-+                                      reg = <0>;
-+                              };
-+
-+                              phy_port2: phy@1 {
-+                                      reg = <1>;
-+                              };
-+
-+                              phy_port3: phy@2 {
-+                                      reg = <2>;
-+                              };
-+
-+                              phy_port4: phy@3 {
-+                                      reg = <3>;
-+                              };
-+
-+                              phy_port5: phy@4 {
-+                                      reg = <4>;
-                               };
-                       };
-               };
diff --git a/target/linux/generic/backport-5.10/785-v5.14-22-net-dsa-qca8k-improve-internal-mdio-read-write-bus-a.patch b/target/linux/generic/backport-5.10/785-v5.14-22-net-dsa-qca8k-improve-internal-mdio-read-write-bus-a.patch
deleted file mode 100644 (file)
index da8d5b3..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-From b7ebac354d54f1657bb89b7a7ca149db50203e6a Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:12 +0200
-Subject: [PATCH] net: dsa: qca8k: improve internal mdio read/write bus access
-
-Improve the internal mdio read/write bus access by caching the value
-without accessing it for every read/write.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 28 +++++++++++++++-------------
- 1 file changed, 15 insertions(+), 13 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -655,6 +655,7 @@ static int
- qca8k_mdio_write(struct mii_bus *salve_bus, int phy, int regnum, u16 data)
- {
-       struct qca8k_priv *priv = salve_bus->priv;
-+      struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
-       u32 val;
-       int ret;
-@@ -669,22 +670,22 @@ qca8k_mdio_write(struct mii_bus *salve_b
-       qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
--      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      ret = qca8k_set_page(priv->bus, page);
-+      ret = qca8k_set_page(bus, page);
-       if (ret)
-               goto exit;
--      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
-+      qca8k_mii_write32(bus, 0x10 | r2, r1, val);
--      ret = qca8k_mdio_busy_wait(priv->bus, QCA8K_MDIO_MASTER_CTRL,
-+      ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-                                  QCA8K_MDIO_MASTER_BUSY);
- exit:
-       /* even if the busy_wait timeouts try to clear the MASTER_EN */
--      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, 0);
-+      qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
--      mutex_unlock(&priv->bus->mdio_lock);
-+      mutex_unlock(&bus->mdio_lock);
-       return ret;
- }
-@@ -693,6 +694,7 @@ static int
- qca8k_mdio_read(struct mii_bus *salve_bus, int phy, int regnum)
- {
-       struct qca8k_priv *priv = salve_bus->priv;
-+      struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
-       u32 val;
-       int ret;
-@@ -706,26 +708,26 @@ qca8k_mdio_read(struct mii_bus *salve_bu
-       qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page);
--      mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
-+      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      ret = qca8k_set_page(priv->bus, page);
-+      ret = qca8k_set_page(bus, page);
-       if (ret)
-               goto exit;
--      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val);
-+      qca8k_mii_write32(bus, 0x10 | r2, r1, val);
--      ret = qca8k_mdio_busy_wait(priv->bus, QCA8K_MDIO_MASTER_CTRL,
-+      ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
-                                  QCA8K_MDIO_MASTER_BUSY);
-       if (ret)
-               goto exit;
--      val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1);
-+      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
- exit:
-       /* even if the busy_wait timeouts try to clear the MASTER_EN */
--      qca8k_mii_write32(priv->bus, 0x10 | r2, r1, 0);
-+      qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
--      mutex_unlock(&priv->bus->mdio_lock);
-+      mutex_unlock(&bus->mdio_lock);
-       if (val >= 0)
-               val &= QCA8K_MDIO_MASTER_DATA_MASK;
diff --git a/target/linux/generic/backport-5.10/785-v5.14-23-net-dsa-qca8k-pass-switch_revision-info-to-phy-dev_f.patch b/target/linux/generic/backport-5.10/785-v5.14-23-net-dsa-qca8k-pass-switch_revision-info-to-phy-dev_f.patch
deleted file mode 100644 (file)
index 1179cf1..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From a46aec02bc06ac2c33f326339e4ef88c735dc30d Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:13 +0200
-Subject: [PATCH] net: dsa: qca8k: pass switch_revision info to phy dev_flags
-
-Define get_phy_flags to pass switch_Revision needed to tweak the
-internal PHY with debug values based on the revision.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1740,6 +1740,22 @@ qca8k_port_vlan_del(struct dsa_switch *d
-       return ret;
- }
-+static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)
-+{
-+      struct qca8k_priv *priv = ds->priv;
-+
-+      /* Communicate to the phy internal driver the switch revision.
-+       * Based on the switch revision different values needs to be
-+       * set to the dbg and mmd reg on the phy.
-+       * The first 2 bit are used to communicate the switch revision
-+       * to the phy driver.
-+       */
-+      if (port > 0 && port < 6)
-+              return priv->switch_revision;
-+
-+      return 0;
-+}
-+
- static enum dsa_tag_protocol
- qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
-                      enum dsa_tag_protocol mp)
-@@ -1774,6 +1790,7 @@ static const struct dsa_switch_ops qca8k
-       .phylink_mac_config     = qca8k_phylink_mac_config,
-       .phylink_mac_link_down  = qca8k_phylink_mac_link_down,
-       .phylink_mac_link_up    = qca8k_phylink_mac_link_up,
-+      .get_phy_flags          = qca8k_get_phy_flags,
- };
- static int qca8k_read_switch_id(struct qca8k_priv *priv)
diff --git a/target/linux/generic/backport-5.10/785-v5.14-25-net-phy-add-support-for-qca8k-switch-internal-PHY-in.patch b/target/linux/generic/backport-5.10/785-v5.14-25-net-phy-add-support-for-qca8k-switch-internal-PHY-in.patch
deleted file mode 100644 (file)
index 20325f5..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-From 272833b9b3b3969be7a91839121d86662c8c4253 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 14 May 2021 23:00:15 +0200
-Subject: [PATCH] net: phy: add support for qca8k switch internal PHY in at803x
-
-Since the at803x share the same regs, it's assumed they are based on the
-same implementation. Make it part of the at803x PHY driver to skip
-having redudant code.
-Add initial support for qca8k internal PHYs. The internal PHYs requires
-special mmd and debug values to be set based on the switch revision
-passwd using the dev_flags. Supports output of idle, receive and eee_wake
-errors stats.
-Some debug values sets can't be translated as the documentation lacks any
-reference about them.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/Kconfig  |   5 +-
- drivers/net/phy/at803x.c | 132 ++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 134 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -235,10 +235,11 @@ config NXP_TJA11XX_PHY
-         Currently supports the NXP TJA1100 and TJA1101 PHY.
- config AT803X_PHY
--      tristate "Qualcomm Atheros AR803X PHYs"
-+      tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs"
-       depends on REGULATOR
-       help
--        Currently supports the AR8030, AR8031, AR8033 and AR8035 model
-+        Currently supports the AR8030, AR8031, AR8033, AR8035 and internal
-+        QCA8337(Internal qca8k PHY) model
- config QSEMI_PHY
-       tristate "Quality Semiconductor PHYs"
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -92,10 +92,16 @@
- #define AT803X_DEBUG_REG_5                    0x05
- #define AT803X_DEBUG_TX_CLK_DLY_EN            BIT(8)
-+#define AT803X_DEBUG_REG_3C                   0x3C
-+
-+#define AT803X_DEBUG_REG_3D                   0x3D
-+
- #define AT803X_DEBUG_REG_1F                   0x1F
- #define AT803X_DEBUG_PLL_ON                   BIT(2)
- #define AT803X_DEBUG_RGMII_1V8                        BIT(3)
-+#define MDIO_AZ_DEBUG                         0x800D
-+
- /* AT803x supports either the XTAL input pad, an internal PLL or the
-  * DSP as clock reference for the clock output pad. The XTAL reference
-  * is only used for 25 MHz output, all other frequencies need the PLL.
-@@ -142,10 +148,34 @@
- #define AT803X_PAGE_FIBER             0
- #define AT803X_PAGE_COPPER            1
-+#define QCA8327_PHY_ID                                0x004dd034
-+#define QCA8337_PHY_ID                                0x004dd036
-+#define QCA8K_PHY_ID_MASK                     0xffffffff
-+
-+#define QCA8K_DEVFLAGS_REVISION_MASK          GENMASK(2, 0)
-+
- MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
- MODULE_AUTHOR("Matus Ujhelyi");
- MODULE_LICENSE("GPL");
-+enum stat_access_type {
-+      PHY,
-+      MMD
-+};
-+
-+struct at803x_hw_stat {
-+      const char *string;
-+      u8 reg;
-+      u32 mask;
-+      enum stat_access_type access_type;
-+};
-+
-+static struct at803x_hw_stat at803x_hw_stats[] = {
-+      { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
-+      { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
-+      { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
-+};
-+
- struct at803x_priv {
-       int flags;
- #define AT803X_KEEP_PLL_ENABLED       BIT(0)  /* don't turn off internal PLL */
-@@ -154,6 +184,7 @@ struct at803x_priv {
-       struct regulator_dev *vddio_rdev;
-       struct regulator_dev *vddh_rdev;
-       struct regulator *vddio;
-+      u64 stats[ARRAY_SIZE(at803x_hw_stats)];
- };
- struct at803x_context {
-@@ -165,6 +196,17 @@ struct at803x_context {
-       u16 led_control;
- };
-+static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data)
-+{
-+      int ret;
-+
-+      ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
-+      if (ret < 0)
-+              return ret;
-+
-+      return phy_write(phydev, AT803X_DEBUG_DATA, data);
-+}
-+
- static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
- {
-       int ret;
-@@ -327,6 +369,53 @@ static void at803x_get_wol(struct phy_de
-               wol->wolopts |= WAKE_MAGIC;
- }
-+static int at803x_get_sset_count(struct phy_device *phydev)
-+{
-+      return ARRAY_SIZE(at803x_hw_stats);
-+}
-+
-+static void at803x_get_strings(struct phy_device *phydev, u8 *data)
-+{
-+      int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) {
-+              strscpy(data + i * ETH_GSTRING_LEN,
-+                      at803x_hw_stats[i].string, ETH_GSTRING_LEN);
-+      }
-+}
-+
-+static u64 at803x_get_stat(struct phy_device *phydev, int i)
-+{
-+      struct at803x_hw_stat stat = at803x_hw_stats[i];
-+      struct at803x_priv *priv = phydev->priv;
-+      int val;
-+      u64 ret;
-+
-+      if (stat.access_type == MMD)
-+              val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg);
-+      else
-+              val = phy_read(phydev, stat.reg);
-+
-+      if (val < 0) {
-+              ret = U64_MAX;
-+      } else {
-+              val = val & stat.mask;
-+              priv->stats[i] += val;
-+              ret = priv->stats[i];
-+      }
-+
-+      return ret;
-+}
-+
-+static void at803x_get_stats(struct phy_device *phydev,
-+                           struct ethtool_stats *stats, u64 *data)
-+{
-+      int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++)
-+              data[i] = at803x_get_stat(phydev, i);
-+}
-+
- static int at803x_suspend(struct phy_device *phydev)
- {
-       int value;
-@@ -1102,6 +1191,34 @@ static int at803x_cable_test_start(struc
-       return 0;
- }
-+static int qca83xx_config_init(struct phy_device *phydev)
-+{
-+      u8 switch_revision;
-+
-+      switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK;
-+
-+      switch (switch_revision) {
-+      case 1:
-+              /* For 100M waveform */
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_0, 0x02ea);
-+              /* Turn on Gigabit clock */
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x68a0);
-+              break;
-+
-+      case 2:
-+              phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0);
-+              fallthrough;
-+      case 4:
-+              phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x6860);
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_5, 0x2c46);
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
-+              break;
-+      }
-+
-+      return 0;
-+}
-+
- static struct phy_driver at803x_driver[] = {
- {
-       /* Qualcomm Atheros AR8035 */
-@@ -1198,7 +1315,20 @@ static struct phy_driver at803x_driver[]
-       .read_status            = at803x_read_status,
-       .soft_reset             = genphy_soft_reset,
-       .config_aneg            = at803x_config_aneg,
--} };
-+}, {
-+      /* QCA8337 */
-+      .phy_id = QCA8337_PHY_ID,
-+      .phy_id_mask = QCA8K_PHY_ID_MASK,
-+      .name = "QCA PHY 8337",
-+      /* PHY_GBIT_FEATURES */
-+      .probe = at803x_probe,
-+      .flags = PHY_IS_INTERNAL,
-+      .config_init = qca83xx_config_init,
-+      .soft_reset = genphy_soft_reset,
-+      .get_sset_count = at803x_get_sset_count,
-+      .get_strings = at803x_get_strings,
-+      .get_stats = at803x_get_stats,
-+}, };
- module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-5.10/786-v5.14-net-dsa-qca8k-fix-missing-unlock-on-error-in-qca8k-vlan.patch b/target/linux/generic/backport-5.10/786-v5.14-net-dsa-qca8k-fix-missing-unlock-on-error-in-qca8k-vlan.patch
deleted file mode 100644 (file)
index a68e3b1..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-From 0d56e5c191b197e1d30a0a4c92628836dafced0f Mon Sep 17 00:00:00 2001
-From: Wei Yongjun <weiyongjun1@huawei.com>
-Date: Tue, 18 May 2021 11:24:13 +0000
-Subject: [PATCH] net: dsa: qca8k: fix missing unlock on error in
- qca8k_vlan_(add|del)
-
-Add the missing unlock before return from function qca8k_vlan_add()
-and qca8k_vlan_del() in the error handling case.
-
-Fixes: 028f5f8ef44f ("net: dsa: qca8k: handle error with qca8k_read operation")
-Reported-by: Hulk Robot <hulkci@huawei.com>
-Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 16 ++++++++++------
- 1 file changed, 10 insertions(+), 6 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -506,8 +506,10 @@ qca8k_vlan_add(struct qca8k_priv *priv,
-               goto out;
-       reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
--      if (reg < 0)
--              return reg;
-+      if (reg < 0) {
-+              ret = reg;
-+              goto out;
-+      }
-       reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-       reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
-       if (untagged)
-@@ -519,7 +521,7 @@ qca8k_vlan_add(struct qca8k_priv *priv,
-       ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-       if (ret)
--              return ret;
-+              goto out;
-       ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
- out:
-@@ -541,8 +543,10 @@ qca8k_vlan_del(struct qca8k_priv *priv,
-               goto out;
-       reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
--      if (reg < 0)
--              return reg;
-+      if (reg < 0) {
-+              ret = reg;
-+              goto out;
-+      }
-       reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
-       reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
-                       QCA8K_VTU_FUNC0_EG_MODE_S(port);
-@@ -564,7 +568,7 @@ qca8k_vlan_del(struct qca8k_priv *priv,
-       } else {
-               ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
-               if (ret)
--                      return ret;
-+                      goto out;
-               ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
-       }
diff --git a/target/linux/generic/backport-5.10/787-v5.14-01-net-dsa-qca8k-check-return-value-of-read-functions-c.patch b/target/linux/generic/backport-5.10/787-v5.14-01-net-dsa-qca8k-check-return-value-of-read-functions-c.patch
deleted file mode 100644 (file)
index 451b0e9..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-From 7c9896e37807862e276064dd9331860f5d27affc Mon Sep 17 00:00:00 2001
-From: Yang Yingliang <yangyingliang@huawei.com>
-Date: Sat, 29 May 2021 11:04:38 +0800
-Subject: [PATCH] net: dsa: qca8k: check return value of read functions
- correctly
-
-Current return type of qca8k_mii_read32() and qca8k_read() are
-unsigned, it can't be negative, so the return value check is
-unuseful. For check the return value correctly, change return
-type of the read functions and add a output parameter to store
-the read value.
-
-Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca8k.c | 130 +++++++++++++++++++---------------------
- 1 file changed, 60 insertions(+), 70 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -89,26 +89,26 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u
-       *page = regaddr & 0x3ff;
- }
--static u32
--qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum)
-+static int
-+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
- {
--      u32 val;
-       int ret;
-       ret = bus->read(bus, phy_id, regnum);
-       if (ret >= 0) {
--              val = ret;
-+              *val = ret;
-               ret = bus->read(bus, phy_id, regnum + 1);
--              val |= ret << 16;
-+              *val |= ret << 16;
-       }
-       if (ret < 0) {
-               dev_err_ratelimited(&bus->dev,
-                                   "failed to read qca8k 32bit register\n");
-+              *val = 0;
-               return ret;
-       }
--      return val;
-+      return 0;
- }
- static void
-@@ -148,26 +148,26 @@ qca8k_set_page(struct mii_bus *bus, u16
-       return 0;
- }
--static u32
--qca8k_read(struct qca8k_priv *priv, u32 reg)
-+static int
-+qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
- {
-       struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
--      u32 val;
-+      int ret;
-       qca8k_split_addr(reg, &r1, &r2, &page);
-       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
--      val = qca8k_set_page(bus, page);
--      if (val < 0)
-+      ret = qca8k_set_page(bus, page);
-+      if (ret < 0)
-               goto exit;
--      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
-+      ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val);
- exit:
-       mutex_unlock(&bus->mdio_lock);
--      return val;
-+      return ret;
- }
- static int
-@@ -208,11 +208,9 @@ qca8k_rmw(struct qca8k_priv *priv, u32 r
-       if (ret < 0)
-               goto exit;
--      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
--      if (val < 0) {
--              ret = val;
-+      ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
-+      if (ret < 0)
-               goto exit;
--      }
-       val &= ~mask;
-       val |= write_val;
-@@ -240,15 +238,8 @@ static int
- qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
--      int ret;
--
--      ret = qca8k_read(priv, reg);
--      if (ret < 0)
--              return ret;
--
--      *val = ret;
--      return 0;
-+      return qca8k_read(priv, reg, val);
- }
- static int
-@@ -296,18 +287,18 @@ static struct regmap_config qca8k_regmap
- static int
- qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
- {
-+      int ret, ret1;
-       u32 val;
--      int ret;
--      ret = read_poll_timeout(qca8k_read, val, !(val & mask),
-+      ret = read_poll_timeout(qca8k_read, ret1, !(val & mask),
-                               0, QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
--                              priv, reg);
-+                              priv, reg, &val);
-       /* Check if qca8k_read has failed for a different reason
-        * before returning -ETIMEDOUT
-        */
--      if (ret < 0 && val < 0)
--              return val;
-+      if (ret < 0 && ret1 < 0)
-+              return ret1;
-       return ret;
- }
-@@ -316,13 +307,13 @@ static int
- qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
- {
-       u32 reg[4], val;
--      int i;
-+      int i, ret;
-       /* load the ARL table into an array */
-       for (i = 0; i < 4; i++) {
--              val = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4));
--              if (val < 0)
--                      return val;
-+              ret = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4), &val);
-+              if (ret < 0)
-+                      return ret;
-               reg[i] = val;
-       }
-@@ -396,9 +387,9 @@ qca8k_fdb_access(struct qca8k_priv *priv
-       /* Check for table full violation when adding an entry */
-       if (cmd == QCA8K_FDB_LOAD) {
--              reg = qca8k_read(priv, QCA8K_REG_ATU_FUNC);
--              if (reg < 0)
--                      return reg;
-+              ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, &reg);
-+              if (ret < 0)
-+                      return ret;
-               if (reg & QCA8K_ATU_FUNC_FULL)
-                       return -1;
-       }
-@@ -477,9 +468,9 @@ qca8k_vlan_access(struct qca8k_priv *pri
-       /* Check for table full violation when adding an entry */
-       if (cmd == QCA8K_VLAN_LOAD) {
--              reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
--              if (reg < 0)
--                      return reg;
-+              ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, &reg);
-+              if (ret < 0)
-+                      return ret;
-               if (reg & QCA8K_VTU_FUNC1_FULL)
-                       return -ENOMEM;
-       }
-@@ -505,11 +496,9 @@ qca8k_vlan_add(struct qca8k_priv *priv,
-       if (ret < 0)
-               goto out;
--      reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
--      if (reg < 0) {
--              ret = reg;
-+      ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-+      if (ret < 0)
-               goto out;
--      }
-       reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
-       reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port));
-       if (untagged)
-@@ -542,11 +531,9 @@ qca8k_vlan_del(struct qca8k_priv *priv,
-       if (ret < 0)
-               goto out;
--      reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
--      if (reg < 0) {
--              ret = reg;
-+      ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, &reg);
-+      if (ret < 0)
-               goto out;
--      }
-       reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
-       reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
-                       QCA8K_VTU_FUNC0_EG_MODE_S(port);
-@@ -638,19 +625,19 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
- {
-       u16 r1, r2, page;
-       u32 val;
--      int ret;
-+      int ret, ret1;
-       qca8k_split_addr(reg, &r1, &r2, &page);
--      ret = read_poll_timeout(qca8k_mii_read32, val, !(val & mask), 0,
-+      ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0,
-                               QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,
--                              bus, 0x10 | r2, r1);
-+                              bus, 0x10 | r2, r1, &val);
-       /* Check if qca8k_read has failed for a different reason
-        * before returnting -ETIMEDOUT
-        */
--      if (ret < 0 && val < 0)
--              return val;
-+      if (ret < 0 && ret1 < 0)
-+              return ret1;
-       return ret;
- }
-@@ -725,7 +712,7 @@ qca8k_mdio_read(struct mii_bus *salve_bu
-       if (ret)
-               goto exit;
--      val = qca8k_mii_read32(bus, 0x10 | r2, r1);
-+      ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val);
- exit:
-       /* even if the busy_wait timeouts try to clear the MASTER_EN */
-@@ -733,10 +720,10 @@ exit:
-       mutex_unlock(&bus->mdio_lock);
--      if (val >= 0)
--              val &= QCA8K_MDIO_MASTER_DATA_MASK;
-+      if (ret >= 0)
-+              ret = val & QCA8K_MDIO_MASTER_DATA_MASK;
--      return val;
-+      return ret;
- }
- static int
-@@ -1211,7 +1198,7 @@ qca8k_phylink_mac_config(struct dsa_swit
-               qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-               /* Enable/disable SerDes auto-negotiation as necessary */
--              val = qca8k_read(priv, QCA8K_REG_PWS);
-+              qca8k_read(priv, QCA8K_REG_PWS, &val);
-               if (phylink_autoneg_inband(mode))
-                       val &= ~QCA8K_PWS_SERDES_AEN_DIS;
-               else
-@@ -1219,7 +1206,7 @@ qca8k_phylink_mac_config(struct dsa_swit
-               qca8k_write(priv, QCA8K_REG_PWS, val);
-               /* Configure the SGMII parameters */
--              val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
-+              qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
-               val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-                       QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
-@@ -1314,10 +1301,11 @@ qca8k_phylink_mac_link_state(struct dsa_
- {
-       struct qca8k_priv *priv = ds->priv;
-       u32 reg;
-+      int ret;
--      reg = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port));
--      if (reg < 0)
--              return reg;
-+      ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), &reg);
-+      if (ret < 0)
-+              return ret;
-       state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
-       state->an_complete = state->link;
-@@ -1419,19 +1407,20 @@ qca8k_get_ethtool_stats(struct dsa_switc
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-       const struct qca8k_mib_desc *mib;
-       u32 reg, i, val;
--      u64 hi;
-+      u64 hi = 0;
-+      int ret;
-       for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
-               mib = &ar8327_mib[i];
-               reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
--              val = qca8k_read(priv, reg);
--              if (val < 0)
-+              ret = qca8k_read(priv, reg, &val);
-+              if (ret < 0)
-                       continue;
-               if (mib->size == 2) {
--                      hi = qca8k_read(priv, reg + 4);
--                      if (hi < 0)
-+                      ret = qca8k_read(priv, reg + 4, (u32 *)&hi);
-+                      if (ret < 0)
-                               continue;
-               }
-@@ -1459,7 +1448,7 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
-       int ret;
-       mutex_lock(&priv->reg_mutex);
--      reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL);
-+      ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
-       if (reg < 0) {
-               ret = reg;
-               goto exit;
-@@ -1802,14 +1791,15 @@ static int qca8k_read_switch_id(struct q
-       const struct qca8k_match_data *data;
-       u32 val;
-       u8 id;
-+      int ret;
-       /* get the switches ID from the compatible */
-       data = of_device_get_match_data(priv->dev);
-       if (!data)
-               return -ENODEV;
--      val = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
--      if (val < 0)
-+      ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
-+      if (ret < 0)
-               return -ENODEV;
-       id = QCA8K_MASK_CTRL_DEVICE_ID(val & QCA8K_MASK_CTRL_DEVICE_ID_MASK);
diff --git a/target/linux/generic/backport-5.10/787-v5.14-02-net-dsa-qca8k-add-missing-check-return-value-in-qca8.patch b/target/linux/generic/backport-5.10/787-v5.14-02-net-dsa-qca8k-add-missing-check-return-value-in-qca8.patch
deleted file mode 100644 (file)
index d20da5b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From 9fe99de01440d9ede74d447ac76e9c445d8daae9 Mon Sep 17 00:00:00 2001
-From: Yang Yingliang <yangyingliang@huawei.com>
-Date: Sat, 29 May 2021 11:04:39 +0800
-Subject: [PATCH] net: dsa: qca8k: add missing check return value in
- qca8k_phylink_mac_config()
-
-Now we can check qca8k_read() return value correctly, so if
-it fails, we need return directly.
-
-Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/qca8k.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1128,6 +1128,7 @@ qca8k_phylink_mac_config(struct dsa_swit
- {
-       struct qca8k_priv *priv = ds->priv;
-       u32 reg, val;
-+      int ret;
-       switch (port) {
-       case 0: /* 1st CPU port */
-@@ -1198,7 +1199,9 @@ qca8k_phylink_mac_config(struct dsa_swit
-               qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-               /* Enable/disable SerDes auto-negotiation as necessary */
--              qca8k_read(priv, QCA8K_REG_PWS, &val);
-+              ret = qca8k_read(priv, QCA8K_REG_PWS, &val);
-+              if (ret)
-+                      return;
-               if (phylink_autoneg_inband(mode))
-                       val &= ~QCA8K_PWS_SERDES_AEN_DIS;
-               else
-@@ -1206,7 +1209,9 @@ qca8k_phylink_mac_config(struct dsa_swit
-               qca8k_write(priv, QCA8K_REG_PWS, val);
-               /* Configure the SGMII parameters */
--              qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
-+              ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val);
-+              if (ret)
-+                      return;
-               val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-                       QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
diff --git a/target/linux/generic/backport-5.10/788-v5.14-01-net-dsa-qca8k-fix-an-endian-bug-in-qca8k-get-ethtool.patch b/target/linux/generic/backport-5.10/788-v5.14-01-net-dsa-qca8k-fix-an-endian-bug-in-qca8k-get-ethtool.patch
deleted file mode 100644 (file)
index 429d5d5..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-aFrom aa3d020b22cb844ab7bdbb9e5d861a64666e2b74 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Wed, 9 Jun 2021 12:52:12 +0300
-Subject: [PATCH] net: dsa: qca8k: fix an endian bug in
- qca8k_get_ethtool_stats()
-
-The "hi" variable is a u64 but the qca8k_read() writes to the top 32
-bits of it.  That will work on little endian systems but it's a bit
-subtle.  It's cleaner to make declare "hi" as a u32.  We will still need
-to cast it when we shift it later on in the function but that's fine.
-
-Fixes: 7c9896e37807 ("net: dsa: qca8k: check return value of read functions correctly")
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1412,7 +1412,7 @@ qca8k_get_ethtool_stats(struct dsa_switc
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-       const struct qca8k_mib_desc *mib;
-       u32 reg, i, val;
--      u64 hi = 0;
-+      u32 hi = 0;
-       int ret;
-       for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
-@@ -1424,14 +1424,14 @@ qca8k_get_ethtool_stats(struct dsa_switc
-                       continue;
-               if (mib->size == 2) {
--                      ret = qca8k_read(priv, reg + 4, (u32 *)&hi);
-+                      ret = qca8k_read(priv, reg + 4, &hi);
-                       if (ret < 0)
-                               continue;
-               }
-               data[i] = val;
-               if (mib->size == 2)
--                      data[i] |= hi << 32;
-+                      data[i] |= (u64)hi << 32;
-       }
- }
diff --git a/target/linux/generic/backport-5.10/788-v5.14-02-net-dsa-qca8k-check-the-correct-variable-in-qca8k-se.patch b/target/linux/generic/backport-5.10/788-v5.14-02-net-dsa-qca8k-check-the-correct-variable-in-qca8k-se.patch
deleted file mode 100644 (file)
index c58f79c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From 3d0167f2a627528032821cdeb78b4eab0510460f Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Wed, 9 Jun 2021 12:53:03 +0300
-Subject: [PATCH] net: dsa: qca8k: check the correct variable in
- qca8k_set_mac_eee()
-
-This code check "reg" but "ret" was intended so the error handling will
-never trigger.
-
-Fixes: 7c9896e37807 ("net: dsa: qca8k: check return value of read functions correctly")
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1454,10 +1454,8 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
-       mutex_lock(&priv->reg_mutex);
-       ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, &reg);
--      if (reg < 0) {
--              ret = reg;
-+      if (ret < 0)
-               goto exit;
--      }
-       if (eee->eee_enabled)
-               reg |= lpi_en;
diff --git a/target/linux/generic/backport-5.10/789-v5.15-net-dsa-qca8k-fix-kernel-panic-with-legacy-mdio-mapping.patch b/target/linux/generic/backport-5.10/789-v5.15-net-dsa-qca8k-fix-kernel-panic-with-legacy-mdio-mapping.patch
deleted file mode 100644 (file)
index 1e293d3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-From ce062a0adbfe933b1932235fdfd874c4c91d1bb0 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sat, 11 Sep 2021 17:50:09 +0200
-Subject: net: dsa: qca8k: fix kernel panic with legacy mdio mapping
-
-When the mdio legacy mapping is used the mii_bus priv registered by DSA
-refer to the dsa switch struct instead of the qca8k_priv struct and
-causes a kernel panic. Create dedicated function when the internal
-dedicated mdio driver is used to properly handle the 2 different
-implementation.
-
-Fixes: 759bafb8a322 ("net: dsa: qca8k: add support for internal phy and internal mdio")
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 30 ++++++++++++++++++++++--------
- 1 file changed, 22 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -643,10 +643,8 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
- }
- static int
--qca8k_mdio_write(struct mii_bus *salve_bus, int phy, int regnum, u16 data)
-+qca8k_mdio_write(struct mii_bus *bus, int phy, int regnum, u16 data)
- {
--      struct qca8k_priv *priv = salve_bus->priv;
--      struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
-       u32 val;
-       int ret;
-@@ -682,10 +680,8 @@ exit:
- }
- static int
--qca8k_mdio_read(struct mii_bus *salve_bus, int phy, int regnum)
-+qca8k_mdio_read(struct mii_bus *bus, int phy, int regnum)
- {
--      struct qca8k_priv *priv = salve_bus->priv;
--      struct mii_bus *bus = priv->bus;
-       u16 r1, r2, page;
-       u32 val;
-       int ret;
-@@ -727,6 +723,24 @@ exit:
- }
- static int
-+qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)
-+{
-+      struct qca8k_priv *priv = slave_bus->priv;
-+      struct mii_bus *bus = priv->bus;
-+
-+      return qca8k_mdio_write(bus, phy, regnum, data);
-+}
-+
-+static int
-+qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)
-+{
-+      struct qca8k_priv *priv = slave_bus->priv;
-+      struct mii_bus *bus = priv->bus;
-+
-+      return qca8k_mdio_read(bus, phy, regnum);
-+}
-+
-+static int
- qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data)
- {
-       struct qca8k_priv *priv = ds->priv;
-@@ -775,8 +789,8 @@ qca8k_mdio_register(struct qca8k_priv *p
-       bus->priv = (void *)priv;
-       bus->name = "qca8k slave mii";
--      bus->read = qca8k_mdio_read;
--      bus->write = qca8k_mdio_write;
-+      bus->read = qca8k_internal_mdio_read;
-+      bus->write = qca8k_internal_mdio_write;
-       snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d",
-                ds->index);
diff --git a/target/linux/generic/backport-5.10/790-v5.13-0001-net-dsa-b53-Add-debug-prints-in-b53_vlan_enable.patch b/target/linux/generic/backport-5.10/790-v5.13-0001-net-dsa-b53-Add-debug-prints-in-b53_vlan_enable.patch
deleted file mode 100644 (file)
index 91cf55b..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-From ee47ed08d75e8f16b3cf882061ee19c2ea19dd6c Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Wed, 10 Mar 2021 10:52:26 -0800
-Subject: [PATCH] net: dsa: b53: Add debug prints in b53_vlan_enable()
-
-Having dynamic debug prints in b53_vlan_enable() has been helpful to
-uncover a recent but update the function to indicate the port being
-configured (or -1 for initial setup) and include the global VLAN enabled
-and VLAN filtering enable status.
-
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_common.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -349,7 +349,7 @@ static void b53_set_forwarding(struct b5
-       b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt);
- }
--static void b53_enable_vlan(struct b53_device *dev, bool enable,
-+static void b53_enable_vlan(struct b53_device *dev, int port, bool enable,
-                           bool enable_filtering)
- {
-       u8 mgmt, vc0, vc1, vc4 = 0, vc5;
-@@ -431,6 +431,9 @@ static void b53_enable_vlan(struct b53_d
-       b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
-       dev->vlan_enabled = enable;
-+
-+      dev_dbg(dev->dev, "Port %d VLAN enabled: %d, filtering: %d\n",
-+              port, enable, enable_filtering);
- }
- static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100)
-@@ -708,7 +711,7 @@ int b53_configure_vlan(struct dsa_switch
-               b53_do_vlan_op(dev, VTA_CMD_CLEAR);
-       }
--      b53_enable_vlan(dev, dev->vlan_enabled, ds->vlan_filtering);
-+      b53_enable_vlan(dev, -1, dev->vlan_enabled, ds->vlan_filtering);
-       b53_for_each_port(dev, i)
-               b53_write16(dev, B53_VLAN_PAGE,
-@@ -1390,7 +1393,7 @@ int b53_vlan_filtering(struct dsa_switch
-       if (switchdev_trans_ph_prepare(trans))
-               return 0;
--      b53_enable_vlan(dev, dev->vlan_enabled, vlan_filtering);
-+      b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering);
-       return 0;
- }
-@@ -1415,7 +1418,7 @@ int b53_vlan_prepare(struct dsa_switch *
-       if (vlan->vid_end >= dev->num_vlans)
-               return -ERANGE;
--      b53_enable_vlan(dev, true, ds->vlan_filtering);
-+      b53_enable_vlan(dev, port, true, ds->vlan_filtering);
-       return 0;
- }
diff --git a/target/linux/generic/backport-5.10/790-v5.13-0002-net-dsa-b53-spi-allow-device-tree-probing.patch b/target/linux/generic/backport-5.10/790-v5.13-0002-net-dsa-b53-spi-allow-device-tree-probing.patch
deleted file mode 100644 (file)
index 56579b2..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From 6d16eadab6db0c1d61e59fee7ed1ecc2d10269be Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Mon, 15 Mar 2021 15:14:23 +0100
-Subject: [PATCH] net: dsa: b53: spi: allow device tree probing
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add missing of_match_table to allow device tree probing.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_spi.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_spi.c
-+++ b/drivers/net/dsa/b53/b53_spi.c
-@@ -324,9 +324,22 @@ static int b53_spi_remove(struct spi_dev
-       return 0;
- }
-+static const struct of_device_id b53_spi_of_match[] = {
-+      { .compatible = "brcm,bcm5325" },
-+      { .compatible = "brcm,bcm5365" },
-+      { .compatible = "brcm,bcm5395" },
-+      { .compatible = "brcm,bcm5397" },
-+      { .compatible = "brcm,bcm5398" },
-+      { .compatible = "brcm,bcm53115" },
-+      { .compatible = "brcm,bcm53125" },
-+      { .compatible = "brcm,bcm53128" },
-+      { /* sentinel */ }
-+};
-+
- static struct spi_driver b53_spi_driver = {
-       .driver = {
-               .name   = "b53-switch",
-+              .of_match_table = b53_spi_of_match,
-       },
-       .probe  = b53_spi_probe,
-       .remove = b53_spi_remove,
diff --git a/target/linux/generic/backport-5.10/790-v5.13-0003-net-dsa-b53-relax-is63xx-condition.patch b/target/linux/generic/backport-5.10/790-v5.13-0003-net-dsa-b53-relax-is63xx-condition.patch
deleted file mode 100644 (file)
index 99eced1..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From ad426d7d966b525b73ed5a1842dd830312bbba71 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Wed, 17 Mar 2021 09:42:01 +0100
-Subject: [PATCH] net: dsa: b53: relax is63xx() condition
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM63xx switches are present on bcm63xx and bmips devices.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_priv.h | 4 ----
- 1 file changed, 4 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -186,11 +186,7 @@ static inline int is531x5(struct b53_dev
- static inline int is63xx(struct b53_device *dev)
- {
--#ifdef CONFIG_BCM63XX
-       return dev->chip_id == BCM63XX_DEVICE_ID;
--#else
--      return 0;
--#endif
- }
- static inline int is5301x(struct b53_device *dev)
diff --git a/target/linux/generic/backport-5.10/790-v5.13-0004-net-dsa-tag_brcm-add-support-for-legacy-tags.patch b/target/linux/generic/backport-5.10/790-v5.13-0004-net-dsa-tag_brcm-add-support-for-legacy-tags.patch
deleted file mode 100644 (file)
index 3b7d8f3..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-From 964dbf186eaa84d409c359ddf09c827a3fbe8228 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Wed, 17 Mar 2021 11:29:26 +0100
-Subject: [PATCH] net: dsa: tag_brcm: add support for legacy tags
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add support for legacy Broadcom tags, which are similar to DSA_TAG_PROTO_BRCM.
-These tags are used on BCM5325, BCM5365 and BCM63xx switches.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/dsa.h  |   2 +
- net/dsa/Kconfig    |   7 +++
- net/dsa/tag_brcm.c | 107 +++++++++++++++++++++++++++++++++++++++++++--
- 3 files changed, 113 insertions(+), 3 deletions(-)
-
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -45,10 +45,12 @@ struct phylink_link_state;
- #define DSA_TAG_PROTO_OCELOT_VALUE            15
- #define DSA_TAG_PROTO_AR9331_VALUE            16
- #define DSA_TAG_PROTO_RTL4_A_VALUE            17
-+#define DSA_TAG_PROTO_BRCM_LEGACY_VALUE               22
- 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_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
-@@ -47,6 +47,13 @@ config NET_DSA_TAG_BRCM
-         Say Y if you want to enable support for tagging frames for the
-         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"
-+      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
-+        address.
- 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
-@@ -11,9 +11,26 @@
- #include "dsa_priv.h"
--/* This tag length is 4 bytes, older ones were 6 bytes, we do not
-- * handle them
-- */
-+/* Legacy Broadcom tag (6 bytes) */
-+#define BRCM_LEG_TAG_LEN      6
-+
-+/* Type fields */
-+/* 1st byte in the tag */
-+#define BRCM_LEG_TYPE_HI      0x88
-+/* 2nd byte in the tag */
-+#define BRCM_LEG_TYPE_LO      0x74
-+
-+/* Tag fields */
-+/* 3rd byte in the tag */
-+#define BRCM_LEG_UNICAST      (0 << 5)
-+#define BRCM_LEG_MULTICAST    (1 << 5)
-+#define BRCM_LEG_EGRESS               (2 << 5)
-+#define BRCM_LEG_INGRESS      (3 << 5)
-+
-+/* 6th byte in the tag */
-+#define BRCM_LEG_PORT_ID      (0xf)
-+
-+/* Newer Broadcom tag (4 bytes) */
- #define BRCM_TAG_LEN  4
- /* Tag is constructed and desconstructed using byte by byte access
-@@ -194,6 +211,87 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
- MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM);
- #endif
-+#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)
-+{
-+      struct dsa_port *dp = dsa_slave_to_port(dev);
-+      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_slave_xmit() free the SKB
-+       */
-+      if (__skb_put_padto(skb, ETH_ZLEN + BRCM_LEG_TAG_LEN, false))
-+              return NULL;
-+
-+      skb_push(skb, BRCM_LEG_TAG_LEN);
-+
-+      memmove(skb->data, skb->data + BRCM_LEG_TAG_LEN, 2 * ETH_ALEN);
-+
-+      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_tag[3] = 0;
-+      brcm_tag[4] = 0;
-+      brcm_tag[5] = dp->index & BRCM_LEG_PORT_ID;
-+
-+      return skb;
-+}
-+
-+static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
-+                                      struct net_device *dev,
-+                                      struct packet_type *pt)
-+{
-+      int source_port;
-+      u8 *brcm_tag;
-+
-+      if (unlikely(!pskb_may_pull(skb, BRCM_LEG_PORT_ID)))
-+              return NULL;
-+
-+      brcm_tag = skb->data - 2;
-+
-+      source_port = brcm_tag[5] & BRCM_LEG_PORT_ID;
-+
-+      skb->dev = dsa_master_find_slave(dev, 0, source_port);
-+      if (!skb->dev)
-+              return NULL;
-+
-+      /* Remove Broadcom tag and update checksum */
-+      skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
-+
-+      skb->offload_fwd_mark = 1;
-+
-+      /* Move the Ethernet DA and SA */
-+      memmove(skb->data - ETH_HLEN,
-+              skb->data - ETH_HLEN - BRCM_LEG_TAG_LEN,
-+              2 * ETH_ALEN);
-+
-+      return skb;
-+}
-+
-+static const struct dsa_device_ops brcm_legacy_netdev_ops = {
-+      .name = "brcm-legacy",
-+      .proto = DSA_TAG_PROTO_BRCM_LEGACY,
-+      .xmit = brcm_leg_tag_xmit,
-+      .rcv = brcm_leg_tag_rcv,
-+      .overhead = BRCM_LEG_TAG_LEN,
-+};
-+
-+DSA_TAG_DRIVER(brcm_legacy_netdev_ops);
-+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY);
-+#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */
-+
- #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)
-@@ -226,6 +324,9 @@ static struct dsa_tag_driver *dsa_tag_dr
- #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM)
-       &DSA_TAG_DRIVER_NAME(brcm_netdev_ops),
- #endif
-+#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_PREPEND)
-       &DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops),
- #endif
diff --git a/target/linux/generic/backport-5.10/790-v5.13-0005-net-dsa-b53-support-legacy-tags.patch b/target/linux/generic/backport-5.10/790-v5.13-0005-net-dsa-b53-support-legacy-tags.patch
deleted file mode 100644 (file)
index 838e78a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From 46c5176c586c81306bf9e7024c13b95da775490f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Wed, 17 Mar 2021 11:29:27 +0100
-Subject: [PATCH] net: dsa: b53: support legacy tags
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-These tags are used on BCM5325, BCM5365 and BCM63xx switches.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/Kconfig      |  1 +
- drivers/net/dsa/b53/b53_common.c | 12 +++++++-----
- 2 files changed, 8 insertions(+), 5 deletions(-)
-
---- a/drivers/net/dsa/b53/Kconfig
-+++ b/drivers/net/dsa/b53/Kconfig
-@@ -3,6 +3,7 @@ menuconfig B53
-       tristate "Broadcom BCM53xx managed switch support"
-       depends on NET_DSA
-       select NET_DSA_TAG_BRCM
-+      select NET_DSA_TAG_BRCM_LEGACY
-       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
-@@ -2024,15 +2024,17 @@ enum dsa_tag_protocol b53_get_tag_protoc
- {
-       struct b53_device *dev = ds->priv;
--      /* Older models (5325, 5365) support a different tag format that we do
--       * not support in net/dsa/tag_brcm.c yet.
--       */
--      if (is5325(dev) || is5365(dev) ||
--          !b53_can_enable_brcm_tags(ds, port, mprot)) {
-+      if (!b53_can_enable_brcm_tags(ds, port, mprot)) {
-               dev->tag_protocol = DSA_TAG_PROTO_NONE;
-               goto out;
-       }
-+      /* Older models require a different 6 byte tag */
-+      if (is5325(dev) || is5365(dev) || is63xx(dev)) {
-+              dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY;
-+              goto out;
-+      }
-+
-       /* Broadcom BCM58xx chips have a flow accelerator on Port 8
-        * which requires us to use the prepended Broadcom tag type
-        */
diff --git a/target/linux/generic/backport-5.10/790-v5.13-0006-net-dsa-b53-mmap-Add-device-tree-support.patch b/target/linux/generic/backport-5.10/790-v5.13-0006-net-dsa-b53-mmap-Add-device-tree-support.patch
deleted file mode 100644 (file)
index c1014b2..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-From a5538a777b73b35750ed1ffff8c1ef539e861624 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
-Date: Wed, 17 Mar 2021 10:23:17 +0100
-Subject: [PATCH] net: dsa: b53: mmap: Add device tree support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add device tree support to b53_mmap.c while keeping platform devices support.
-
-Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_mmap.c | 55 ++++++++++++++++++++++++++++++++++
- 1 file changed, 55 insertions(+)
-
---- a/drivers/net/dsa/b53/b53_mmap.c
-+++ b/drivers/net/dsa/b53/b53_mmap.c
-@@ -16,6 +16,7 @@
-  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-  */
-+#include <linux/bits.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/io.h>
-@@ -228,11 +229,65 @@ static const struct b53_io_ops b53_mmap_
-       .write64 = b53_mmap_write64,
- };
-+static int b53_mmap_probe_of(struct platform_device *pdev,
-+                           struct b53_platform_data **ppdata)
-+{
-+      struct device_node *np = pdev->dev.of_node;
-+      struct device_node *of_ports, *of_port;
-+      struct device *dev = &pdev->dev;
-+      struct b53_platform_data *pdata;
-+      void __iomem *mem;
-+
-+      mem = devm_platform_ioremap_resource(pdev, 0);
-+      if (IS_ERR(mem))
-+              return PTR_ERR(mem);
-+
-+      pdata = devm_kzalloc(dev, sizeof(struct b53_platform_data),
-+                           GFP_KERNEL);
-+      if (!pdata)
-+              return -ENOMEM;
-+
-+      pdata->regs = mem;
-+      pdata->chip_id = BCM63XX_DEVICE_ID;
-+      pdata->big_endian = of_property_read_bool(np, "big-endian");
-+
-+      of_ports = of_get_child_by_name(np, "ports");
-+      if (!of_ports) {
-+              dev_err(dev, "no ports child node found\n");
-+              return -EINVAL;
-+      }
-+
-+      for_each_available_child_of_node(of_ports, of_port) {
-+              u32 reg;
-+
-+              if (of_property_read_u32(of_port, "reg", &reg))
-+                      continue;
-+
-+              if (reg < B53_CPU_PORT)
-+                      pdata->enabled_ports |= BIT(reg);
-+      }
-+
-+      of_node_put(of_ports);
-+      *ppdata = pdata;
-+
-+      return 0;
-+}
-+
- static int b53_mmap_probe(struct platform_device *pdev)
- {
-+      struct device_node *np = pdev->dev.of_node;
-       struct b53_platform_data *pdata = pdev->dev.platform_data;
-       struct b53_mmap_priv *priv;
-       struct b53_device *dev;
-+      int ret;
-+
-+      if (!pdata && np) {
-+              ret = b53_mmap_probe_of(pdev, &pdata);
-+              if (ret) {
-+                      dev_err(&pdev->dev, "OF probe error\n");
-+                      return ret;
-+              }
-+      }
-       if (!pdata)
-               return -EINVAL;
diff --git a/target/linux/generic/backport-5.10/790-v5.13-0007-net-dsa-b53-spi-add-missing-MODULE_DEVICE_TABLE.patch b/target/linux/generic/backport-5.10/790-v5.13-0007-net-dsa-b53-spi-add-missing-MODULE_DEVICE_TABLE.patch
deleted file mode 100644 (file)
index ea36755..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From 866f1577ba69bde2b9f36c300f603596c7d84a62 Mon Sep 17 00:00:00 2001
-From: Qinglang Miao <miaoqinglang@huawei.com>
-Date: Thu, 25 Mar 2021 17:19:54 +0800
-Subject: [PATCH] net: dsa: b53: spi: add missing MODULE_DEVICE_TABLE
-
-This patch adds missing MODULE_DEVICE_TABLE definition which generates
-correct modalias for automatic loading of this driver when it is built
-as an external module.
-
-Reported-by: Hulk Robot <hulkci@huawei.com>
-Signed-off-by: Qinglang Miao <miaoqinglang@huawei.com>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_spi.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/dsa/b53/b53_spi.c
-+++ b/drivers/net/dsa/b53/b53_spi.c
-@@ -335,6 +335,7 @@ static const struct of_device_id b53_spi
-       { .compatible = "brcm,bcm53128" },
-       { /* sentinel */ }
- };
-+MODULE_DEVICE_TABLE(of, b53_spi_of_match);
- static struct spi_driver b53_spi_driver = {
-       .driver = {
diff --git a/target/linux/generic/backport-5.10/791-v5.14-0001-net-dsa-b53-Do-not-force-CPU-to-be-always-tagged.patch b/target/linux/generic/backport-5.10/791-v5.14-0001-net-dsa-b53-Do-not-force-CPU-to-be-always-tagged.patch
deleted file mode 100644 (file)
index 2a8def3..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-From 2c32a3d3c233b855943677609fe388f82b1f0975 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Tue, 8 Jun 2021 14:22:04 -0700
-Subject: [PATCH] net: dsa: b53: Do not force CPU to be always tagged
-
-Commit ca8931948344 ("net: dsa: b53: Keep CPU port as tagged in all
-VLANs") forced the CPU port to be always tagged in any VLAN membership.
-This was necessary back then because we did not support Broadcom tags
-for all configurations so the only way to differentiate tagged and
-untagged traffic while DSA_TAG_PROTO_NONE was used was to force the CPU
-port into being always tagged.
-
-With most configurations enabling Broadcom tags, especially after
-8fab459e69ab ("net: dsa: b53: Enable Broadcom tags for 531x5/539x
-families") we do not need to apply this unconditional force tagging of
-the CPU port in all VLANs.
-
-A helper function is introduced to faciliate the encapsulation of the
-specific condition requiring the CPU port to be tagged in all VLANs and
-the dsa_switch_ops::untag_bridge_pvid boolean is moved to when
-dsa_switch_ops::setup is called when we have already determined the
-tagging protocol we will be using.
-
-Reported-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Tested-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_common.c | 17 ++++++++++++++---
- 1 file changed, 14 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1049,6 +1049,11 @@ static int b53_setup(struct dsa_switch *
-       unsigned int port;
-       int ret;
-+      /* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set
-+       * which forces the CPU port to be tagged in all VLANs.
-+       */
-+      ds->untag_bridge_pvid = dev->tag_protocol == DSA_TAG_PROTO_NONE;
-+
-       ret = b53_reset_switch(dev);
-       if (ret) {
-               dev_err(ds->dev, "failed to reset switch\n");
-@@ -1423,6 +1428,13 @@ int b53_vlan_prepare(struct dsa_switch *
-       return 0;
- }
- EXPORT_SYMBOL(b53_vlan_prepare);
-+ 
-+static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
-+{
-+      struct b53_device *dev = ds->priv;
-+
-+      return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
-+}
- void b53_vlan_add(struct dsa_switch *ds, int port,
-                 const struct switchdev_obj_port_vlan *vlan)
-@@ -1442,7 +1454,7 @@ void b53_vlan_add(struct dsa_switch *ds,
-                       untagged = true;
-               vl->members |= BIT(port);
--              if (untagged && !dsa_is_cpu_port(ds, port))
-+              if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
-                       vl->untag |= BIT(port);
-               else
-                       vl->untag &= ~BIT(port);
-@@ -1480,7 +1492,7 @@ int b53_vlan_del(struct dsa_switch *ds,
-               if (pvid == vid)
-                       pvid = b53_default_pvid(dev);
--              if (untagged && !dsa_is_cpu_port(ds, port))
-+              if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
-                       vl->untag &= ~(BIT(port));
-               b53_set_vlan_entry(dev, vid, vl);
-@@ -2644,7 +2656,6 @@ struct b53_device *b53_switch_alloc(stru
-       dev->ops = ops;
-       ds->ops = &b53_switch_ops;
-       ds->configure_vlan_while_not_filtering = true;
--      ds->untag_bridge_pvid = true;
-       dev->vlan_enabled = ds->configure_vlan_while_not_filtering;
-       /* Let DSA handle the case were multiple bridges span the same switch
-        * device and different VLAN awareness settings are requested, which
diff --git a/target/linux/generic/backport-5.10/791-v5.14-0002-net-dsa-b53-remove-redundant-null-check-on-dev.patch b/target/linux/generic/backport-5.10/791-v5.14-0002-net-dsa-b53-remove-redundant-null-check-on-dev.patch
deleted file mode 100644 (file)
index ee3a71f..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 11b57faf951cd3a570e3d9e463fc7c41023bc8c6 Mon Sep 17 00:00:00 2001
-From: Colin Ian King <colin.king@canonical.com>
-Date: Tue, 15 Jun 2021 10:05:16 +0100
-Subject: [PATCH] net: dsa: b53: remove redundant null check on dev
-
-The pointer dev can never be null, the null check is redundant
-and can be removed. Cleans up a static analysis warning that
-pointer priv is dereferencing dev before dev is being null
-checked.
-
-Addresses-Coverity: ("Dereference before null check")
-Signed-off-by: Colin Ian King <colin.king@canonical.com>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_srab.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_srab.c
-+++ b/drivers/net/dsa/b53/b53_srab.c
-@@ -632,8 +632,7 @@ static int b53_srab_remove(struct platfo
-       struct b53_srab_priv *priv = dev->priv;
-       b53_srab_intr_set(priv, false);
--      if (dev)
--              b53_switch_remove(dev);
-+      b53_switch_remove(dev);
-       return 0;
- }
diff --git a/target/linux/generic/backport-5.10/791-v5.14-0003-net-dsa-b53-Create-default-VLAN-entry-explicitly.patch b/target/linux/generic/backport-5.10/791-v5.14-0003-net-dsa-b53-Create-default-VLAN-entry-explicitly.patch
deleted file mode 100644 (file)
index df891d6..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-From 64a81b24487f0d2fba0f033029eec2abc7d82cee Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Mon, 21 Jun 2021 15:10:55 -0700
-Subject: [PATCH] net: dsa: b53: Create default VLAN entry explicitly
-
-In case CONFIG_VLAN_8021Q is not set, there will be no call down to the
-b53 driver to ensure that the default PVID VLAN entry will be configured
-with the appropriate untagged attribute towards the CPU port. We were
-implicitly relying on dsa_slave_vlan_rx_add_vid() to do that for us,
-instead make it explicit.
-
-Reported-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/b53/b53_common.c | 27 +++++++++++++++++++--------
- 1 file changed, 19 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -693,6 +693,13 @@ static u16 b53_default_pvid(struct b53_d
-               return 0;
- }
-+static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
-+{
-+      struct b53_device *dev = ds->priv;
-+
-+      return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
-+}
-+
- int b53_configure_vlan(struct dsa_switch *ds)
- {
-       struct b53_device *dev = ds->priv;
-@@ -713,9 +720,20 @@ int b53_configure_vlan(struct dsa_switch
-       b53_enable_vlan(dev, -1, dev->vlan_enabled, ds->vlan_filtering);
--      b53_for_each_port(dev, i)
-+      /* Create an untagged VLAN entry for the default PVID in case
-+       * CONFIG_VLAN_8021Q is disabled and there are no calls to
-+       * dsa_slave_vlan_rx_add_vid() to create the default VLAN
-+       * entry. Do this only when the tagging protocol is not
-+       * DSA_TAG_PROTO_NONE
-+       */
-+      b53_for_each_port(dev, i) {
-+              v = &dev->vlans[def_vid];
-+              v->members |= BIT(i);
-+              if (!b53_vlan_port_needs_forced_tagged(ds, i))
-+                      v->untag = v->members;
-               b53_write16(dev, B53_VLAN_PAGE,
-                           B53_VLAN_PORT_DEF_TAG(i), def_vid);
-+      }
-       /* Upon initial call we have not set-up any VLANs, but upon
-        * system resume, we need to restore all VLAN entries.
-@@ -1429,13 +1447,6 @@ int b53_vlan_prepare(struct dsa_switch *
- }
- EXPORT_SYMBOL(b53_vlan_prepare);
-  
--static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
--{
--      struct b53_device *dev = ds->priv;
--
--      return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port);
--}
--
- void b53_vlan_add(struct dsa_switch *ds, int port,
-                 const struct switchdev_obj_port_vlan *vlan)
- {
diff --git a/target/linux/generic/backport-5.10/792-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch b/target/linux/generic/backport-5.10/792-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch
deleted file mode 100644 (file)
index 16aa071..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0ccf8511182436183c031e8a2f740ae91a02c625 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Tue, 14 Sep 2021 14:33:45 +0200
-Subject: net: phy: at803x: add support for qca 8327 internal phy
-
-Add support for qca8327 internal phy needed for correct init of the
-switch port. It does use the same qca8337 function and reg just with a
-different id.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Tested-by: Rosen Penev <rosenp@gmail.com>
-Tested-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1328,6 +1328,19 @@ static struct phy_driver at803x_driver[]
-       .get_sset_count = at803x_get_sset_count,
-       .get_strings = at803x_get_strings,
-       .get_stats = at803x_get_stats,
-+}, {
-+      /* QCA8327 */
-+      .phy_id = QCA8327_PHY_ID,
-+      .phy_id_mask = QCA8K_PHY_ID_MASK,
-+      .name = "QCA PHY 8327",
-+      /* PHY_GBIT_FEATURES */
-+      .probe = at803x_probe,
-+      .flags = PHY_IS_INTERNAL,
-+      .config_init = qca83xx_config_init,
-+      .soft_reset = genphy_soft_reset,
-+      .get_sset_count = at803x_get_sset_count,
-+      .get_strings = at803x_get_strings,
-+      .get_stats = at803x_get_stats,
- }, };
- module_phy_driver(at803x_driver);
-@@ -1338,6 +1351,8 @@ static struct mdio_device_id __maybe_unu
-       { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
-       { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
-       { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
-+      { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
-+      { PHY_ID_MATCH_EXACT(QCA8327_PHY_ID) },
-       { }
- };
diff --git a/target/linux/generic/backport-5.10/793-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch b/target/linux/generic/backport-5.10/793-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch
deleted file mode 100644 (file)
index d80b5db..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-From 983d96a9116a328668601555d96736261d33170c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 16 Sep 2021 14:03:51 +0200
-Subject: [PATCH] net: dsa: b53: Include all ports in "enabled_ports"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Make "enabled_ports" bitfield contain all available switch ports
-including a CPU port. This way there is no need for fixup during
-initialization.
-
-For BCM53010, BCM53018 and BCM53019 include also other available ports.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 23 +++++++++++------------
- 1 file changed, 11 insertions(+), 12 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2288,7 +2288,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM5325_DEVICE_ID,
-               .dev_name = "BCM5325",
-               .vlans = 16,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x3f,
-               .arl_bins = 2,
-               .arl_buckets = 1024,
-               .imp_port = 5,
-@@ -2299,7 +2299,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM5365_DEVICE_ID,
-               .dev_name = "BCM5365",
-               .vlans = 256,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x3f,
-               .arl_bins = 2,
-               .arl_buckets = 1024,
-               .imp_port = 5,
-@@ -2310,7 +2310,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM5389_DEVICE_ID,
-               .dev_name = "BCM5389",
-               .vlans = 4096,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x11f,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
-@@ -2324,7 +2324,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM5395_DEVICE_ID,
-               .dev_name = "BCM5395",
-               .vlans = 4096,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x11f,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
-@@ -2338,7 +2338,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM5397_DEVICE_ID,
-               .dev_name = "BCM5397",
-               .vlans = 4096,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x11f,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
-@@ -2352,7 +2352,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM5398_DEVICE_ID,
-               .dev_name = "BCM5398",
-               .vlans = 4096,
--              .enabled_ports = 0x7f,
-+              .enabled_ports = 0x17f,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
-@@ -2366,7 +2366,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM53115_DEVICE_ID,
-               .dev_name = "BCM53115",
-               .vlans = 4096,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x11f,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .vta_regs = B53_VTA_REGS,
-@@ -2380,7 +2380,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM53125_DEVICE_ID,
-               .dev_name = "BCM53125",
-               .vlans = 4096,
--              .enabled_ports = 0xff,
-+              .enabled_ports = 0x1ff,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
-@@ -2422,7 +2422,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM53010_DEVICE_ID,
-               .dev_name = "BCM53010",
-               .vlans = 4096,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x1bf,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
-@@ -2464,7 +2464,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM53018_DEVICE_ID,
-               .dev_name = "BCM53018",
-               .vlans = 4096,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x1bf,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
-@@ -2478,7 +2478,7 @@ static const struct b53_chip_data b53_sw
-               .chip_id = BCM53019_DEVICE_ID,
-               .dev_name = "BCM53019",
-               .vlans = 4096,
--              .enabled_ports = 0x1f,
-+              .enabled_ports = 0x1bf,
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
-@@ -2605,7 +2605,6 @@ static int b53_switch_init(struct b53_de
-                       dev->cpu_port = 5;
-       }
--      dev->enabled_ports |= BIT(dev->cpu_port);
-       dev->num_ports = fls(dev->enabled_ports);
-       dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS);
diff --git a/target/linux/generic/backport-5.10/793-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch b/target/linux/generic/backport-5.10/793-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch
deleted file mode 100644 (file)
index 4a4f8e9..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From b290c6384afabbca5ae6e2af72fb1b2bc37922be Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 16 Sep 2021 14:03:52 +0200
-Subject: [PATCH] net: dsa: b53: Drop BCM5301x workaround for a wrong CPU/IMP
- port
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-On BCM5301x port 8 requires a fixed link when used.
-
-Years ago when b53 was an OpenWrt downstream driver (with configuration
-based on sometimes bugged NVRAM) there was a need for a fixup. In case
-of forcing fixed link for (incorrectly specified) port 5 the code had to
-actually setup port 8 link.
-
-For upstream b53 driver with setup based on DT there is no need for that
-workaround. In DT we have and require correct ports setup.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/b53/b53_common.c | 6 ------
- 1 file changed, 6 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1256,12 +1256,6 @@ static void b53_adjust_link(struct dsa_s
-                               return;
-                       }
-               }
--      } else if (is5301x(dev)) {
--              if (port != dev->cpu_port) {
--                      b53_force_port_config(dev, dev->cpu_port, 2000,
--                                            DUPLEX_FULL, true, true);
--                      b53_force_link(dev, dev->cpu_port, 1);
--              }
-       }
-       /* Re-negotiate EEE if it was enabled already */
diff --git a/target/linux/generic/backport-5.10/793-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch b/target/linux/generic/backport-5.10/793-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch
deleted file mode 100644 (file)
index 3954ee4..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3ff26b29230c54fea2353b63124c589b61953e14 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 16 Sep 2021 14:03:53 +0200
-Subject: [PATCH] net: dsa: b53: Improve flow control setup on BCM5301x
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-According to the Broadcom's reference driver flow control needs to be
-enabled for any CPU switch port (5, 7 or 8 - depending on which one is
-used). Current code makes it work only for the port 5. Use
-dsa_is_cpu_port() which solved that problem.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Florian Fainelli <f.fainelli@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
-@@ -1187,7 +1187,7 @@ static void b53_adjust_link(struct dsa_s
-               return;
-       /* Enable flow control on BCM5301x's CPU port */
--      if (is5301x(dev) && port == dev->cpu_port)
-+      if (is5301x(dev) && dsa_is_cpu_port(ds, port))
-               tx_pause = rx_pause = true;
-       if (phydev->pause) {
diff --git a/target/linux/generic/backport-5.10/793-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch b/target/linux/generic/backport-5.10/793-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch
deleted file mode 100644 (file)
index 9e687b1..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-From 7d5af56418d7d01e43247a33b6fe6492ea871923 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 16 Sep 2021 14:03:54 +0200
-Subject: [PATCH] net: dsa: b53: Drop unused "cpu_port" field
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's set but never used anymore.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Tested-by: Florian Fainelli <f.fainelli@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 -
- 2 files changed, 29 deletions(-)
-
---- a/drivers/net/dsa/b53/b53_common.c
-+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2286,7 +2286,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 2,
-               .arl_buckets = 1024,
-               .imp_port = 5,
--              .cpu_port = B53_CPU_PORT_25,
-               .duplex_reg = B53_DUPLEX_STAT_FE,
-       },
-       {
-@@ -2297,7 +2296,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 2,
-               .arl_buckets = 1024,
-               .imp_port = 5,
--              .cpu_port = B53_CPU_PORT_25,
-               .duplex_reg = B53_DUPLEX_STAT_FE,
-       },
-       {
-@@ -2308,7 +2306,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2322,7 +2319,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2336,7 +2332,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS_9798,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2350,7 +2345,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS_9798,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2365,7 +2359,6 @@ static const struct b53_chip_data b53_sw
-               .arl_buckets = 1024,
-               .vta_regs = B53_VTA_REGS,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-               .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
-@@ -2378,7 +2371,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2392,7 +2384,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2406,7 +2397,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS_63XX,
-               .duplex_reg = B53_DUPLEX_STAT_63XX,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
-@@ -2420,7 +2410,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2434,7 +2423,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2448,7 +2436,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2462,7 +2449,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2476,7 +2462,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2490,7 +2475,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2504,7 +2488,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2518,7 +2501,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 1024,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2532,7 +2514,6 @@ static const struct b53_chip_data b53_sw
-               .arl_bins = 4,
-               .arl_buckets = 256,
-               .imp_port = 8,
--              .cpu_port = B53_CPU_PORT,
-               .vta_regs = B53_VTA_REGS,
-               .duplex_reg = B53_DUPLEX_STAT_GE,
-               .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
-@@ -2558,7 +2539,6 @@ static int b53_switch_init(struct b53_de
-                       dev->vta_regs[2] = chip->vta_regs[2];
-                       dev->jumbo_pm_reg = chip->jumbo_pm_reg;
-                       dev->imp_port = chip->imp_port;
--                      dev->cpu_port = chip->cpu_port;
-                       dev->num_vlans = chip->vlans;
-                       dev->num_arl_bins = chip->arl_bins;
-                       dev->num_arl_buckets = chip->arl_buckets;
-@@ -2590,13 +2570,6 @@ static int b53_switch_init(struct b53_de
-                       break;
- #endif
-               }
--      } else if (dev->chip_id == BCM53115_DEVICE_ID) {
--              u64 strap_value;
--
--              b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value);
--              /* use second IMP port if GMII is enabled */
--              if (strap_value & SV_GMII_CTRL_115)
--                      dev->cpu_port = 5;
-       }
-       dev->num_ports = fls(dev->enabled_ports);
---- a/drivers/net/dsa/b53/b53_priv.h
-+++ b/drivers/net/dsa/b53/b53_priv.h
-@@ -123,7 +123,6 @@ struct b53_device {
-       /* used ports mask */
-       u16 enabled_ports;
-       unsigned int imp_port;
--      unsigned int cpu_port;
-       /* connect specific data */
-       u8 current_page;
diff --git a/target/linux/generic/backport-5.10/794-v5.15-net-dsa-don-t-set-skb-offload_fwd_mark-when-not-offl.patch b/target/linux/generic/backport-5.10/794-v5.15-net-dsa-don-t-set-skb-offload_fwd_mark-when-not-offl.patch
deleted file mode 100644 (file)
index ab4fdf8..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-From bea7907837c57a0aaac009931eb14efb056dafab Mon Sep 17 00:00:00 2001
-From: Vladimir Oltean <vladimir.oltean@nxp.com>
-Date: Thu, 29 Jul 2021 17:56:00 +0300
-Subject: [PATCH] net: dsa: don't set skb->offload_fwd_mark when not offloading
- the bridge
-
-DSA has gained the recent ability to deal gracefully with upper
-interfaces it cannot offload, such as the bridge, bonding or team
-drivers. When such uppers exist, the ports are still in standalone mode
-as far as the hardware is concerned.
-
-But when we deliver packets to the software bridge in order for that to
-do the forwarding, there is an unpleasant surprise in that the bridge
-will refuse to forward them. This is because we unconditionally set
-skb->offload_fwd_mark = true, meaning that the bridge thinks the frames
-were already forwarded in hardware by us.
-
-Since dp->bridge_dev is populated only when there is hardware offload
-for it, but not in the software fallback case, let's introduce a new
-helper that can be called from the tagger data path which sets the
-skb->offload_fwd_mark accordingly to zero when there is no hardware
-offload for bridging. This lets the bridge forward packets back to other
-interfaces of our switch, if needed.
-
-Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
-Reviewed-by: Tobias Waldekranz <tobias@waldekranz.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- net/dsa/dsa_priv.h         | 14 ++++++++++++++
- net/dsa/tag_brcm.c         |  4 ++--
- net/dsa/tag_dsa.c          | 15 +++++++++++----
- net/dsa/tag_ksz.c          |  2 +-
- net/dsa/tag_lan9303.c      |  3 ++-
- net/dsa/tag_mtk.c          |  2 +-
- net/dsa/tag_ocelot.c       |  2 +-
- net/dsa/tag_rtl4_a.c       |  2 +-
- net/dsa/tag_sja1105.c      | 20 ++++++++++++++------
- 9 files changed, 47 insertions(+), 17 deletions(-)
-
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -266,6 +266,20 @@ static inline struct sk_buff *dsa_untag_
-       return skb;
- }
-+/* If the ingress port offloads the bridge, we mark the frame as autonomously
-+ * forwarded by hardware, so the software bridge doesn't forward in twice, back
-+ * to us, because we already did. However, if we're in fallback mode and we do
-+ * software bridging, we are not offloading it, therefore the dp->bridge_dev
-+ * pointer is not populated, and flooding needs to be done by software (we are
-+ * effectively operating in standalone ports mode).
-+ */
-+static inline void dsa_default_offload_fwd_mark(struct sk_buff *skb)
-+{
-+      struct dsa_port *dp = dsa_slave_to_port(skb->dev);
-+
-+      skb->offload_fwd_mark = !!(dp->bridge_dev);
-+}
-+
- /* switch.c */
- int dsa_switch_register_notifier(struct dsa_switch *ds);
- void dsa_switch_unregister_notifier(struct dsa_switch *ds);
---- a/net/dsa/tag_brcm.c
-+++ b/net/dsa/tag_brcm.c
-@@ -166,7 +166,7 @@ static struct sk_buff *brcm_tag_rcv_ll(s
-       /* Remove Broadcom tag and update checksum */
-       skb_pull_rcsum(skb, BRCM_TAG_LEN);
--      skb->offload_fwd_mark = 1;
-+      dsa_default_offload_fwd_mark(skb);
-       return skb;
- }
-@@ -270,7 +270,7 @@ static struct sk_buff *brcm_leg_tag_rcv(
-       /* Remove Broadcom tag and update checksum */
-       skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
--      skb->offload_fwd_mark = 1;
-+      dsa_default_offload_fwd_mark(skb);
-       /* Move the Ethernet DA and SA */
-       memmove(skb->data - ETH_HLEN,
---- a/net/dsa/tag_ksz.c
-+++ b/net/dsa/tag_ksz.c
-@@ -24,7 +24,7 @@ static struct sk_buff *ksz_common_rcv(st
-       pskb_trim_rcsum(skb, skb->len - len);
--      skb->offload_fwd_mark = true;
-+      dsa_default_offload_fwd_mark(skb);
-       return skb;
- }
---- a/net/dsa/tag_lan9303.c
-+++ b/net/dsa/tag_lan9303.c
-@@ -115,7 +115,8 @@ static struct sk_buff *lan9303_rcv(struc
-       skb_pull_rcsum(skb, 2 + 2);
-       memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
-               2 * ETH_ALEN);
--      skb->offload_fwd_mark = !(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU);
-+      if (!(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU))
-+              dsa_default_offload_fwd_mark(skb);
-       return skb;
- }
---- a/net/dsa/tag_mtk.c
-+++ b/net/dsa/tag_mtk.c
-@@ -104,7 +104,7 @@ static struct sk_buff *mtk_tag_rcv(struc
-       /* Only unicast or broadcast frames are offloaded */
-       if (likely(!is_multicast_skb))
--              skb->offload_fwd_mark = 1;
-+              dsa_default_offload_fwd_mark(skb);
-       return skb;
- }
---- a/net/dsa/tag_ocelot.c
-+++ b/net/dsa/tag_ocelot.c
-@@ -225,7 +225,7 @@ static struct sk_buff *ocelot_rcv(struct
-                */
-               return NULL;
--      skb->offload_fwd_mark = 1;
-+      dsa_default_offload_fwd_mark(skb);
-       skb->priority = qos_class;
-       /* Ocelot switches copy frames unmodified to the CPU. However, it is
---- a/net/dsa/tag_rtl4_a.c
-+++ b/net/dsa/tag_rtl4_a.c
-@@ -115,7 +115,7 @@ static struct sk_buff *rtl4a_tag_rcv(str
-               skb->data - ETH_HLEN - RTL4_A_HDR_LEN,
-               2 * ETH_ALEN);
--      skb->offload_fwd_mark = 1;
-+      dsa_default_offload_fwd_mark(skb);
-       return skb;
- }
diff --git a/target/linux/generic/backport-5.10/795-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch b/target/linux/generic/backport-5.10/795-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch
deleted file mode 100644 (file)
index c82bf91..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-From b4df02b562f4aa14ff6811f30e1b4d2159585c59 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 19 Sep 2021 18:28:15 +0200
-Subject: net: phy: at803x: add support for qca 8327 A variant internal phy
-
-For qca8327 internal phy there are 2 different switch variant with 2
-different phy id. Add this missing variant so the internal phy can be
-correctly identified and fixed.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 25 ++++++++++++++++++++-----
- 1 file changed, 20 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -148,7 +148,8 @@
- #define AT803X_PAGE_FIBER             0
- #define AT803X_PAGE_COPPER            1
--#define QCA8327_PHY_ID                                0x004dd034
-+#define QCA8327_A_PHY_ID                      0x004dd033
-+#define QCA8327_B_PHY_ID                      0x004dd034
- #define QCA8337_PHY_ID                                0x004dd036
- #define QCA8K_PHY_ID_MASK                     0xffffffff
-@@ -1329,10 +1330,23 @@ static struct phy_driver at803x_driver[]
-       .get_strings = at803x_get_strings,
-       .get_stats = at803x_get_stats,
- }, {
--      /* QCA8327 */
--      .phy_id = QCA8327_PHY_ID,
-+      /* QCA8327-A from switch QCA8327-AL1A */
-+      .phy_id = QCA8327_A_PHY_ID,
-       .phy_id_mask = QCA8K_PHY_ID_MASK,
--      .name = "QCA PHY 8327",
-+      .name = "QCA PHY 8327-A",
-+      /* PHY_GBIT_FEATURES */
-+      .probe = at803x_probe,
-+      .flags = PHY_IS_INTERNAL,
-+      .config_init = qca83xx_config_init,
-+      .soft_reset = genphy_soft_reset,
-+      .get_sset_count = at803x_get_sset_count,
-+      .get_strings = at803x_get_strings,
-+      .get_stats = at803x_get_stats,
-+}, {
-+      /* QCA8327-B from switch QCA8327-BL1A */
-+      .phy_id = QCA8327_B_PHY_ID,
-+      .phy_id_mask = QCA8K_PHY_ID_MASK,
-+      .name = "QCA PHY 8327-B",
-       /* PHY_GBIT_FEATURES */
-       .probe = at803x_probe,
-       .flags = PHY_IS_INTERNAL,
-@@ -1352,7 +1366,8 @@ static struct mdio_device_id __maybe_unu
-       { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
-       { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
-       { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
--      { PHY_ID_MATCH_EXACT(QCA8327_PHY_ID) },
-+      { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
-+      { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
-       { }
- };
diff --git a/target/linux/generic/backport-5.10/795-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch b/target/linux/generic/backport-5.10/795-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch
deleted file mode 100644 (file)
index be24fd5..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From 15b9df4ece17d084f14eb0ca1cf05f2ad497e425 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 19 Sep 2021 18:28:16 +0200
-Subject: net: phy: at803x: add resume/suspend function to qca83xx phy
-
-Add resume/suspend function to qca83xx internal phy.
-We can't use the at803x generic function as the documentation lacks of
-any support for WoL regs.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1329,6 +1329,8 @@ static struct phy_driver at803x_driver[]
-       .get_sset_count = at803x_get_sset_count,
-       .get_strings = at803x_get_strings,
-       .get_stats = at803x_get_stats,
-+      .suspend                = genphy_suspend,
-+      .resume                 = genphy_resume,
- }, {
-       /* QCA8327-A from switch QCA8327-AL1A */
-       .phy_id = QCA8327_A_PHY_ID,
-@@ -1342,6 +1344,8 @@ static struct phy_driver at803x_driver[]
-       .get_sset_count = at803x_get_sset_count,
-       .get_strings = at803x_get_strings,
-       .get_stats = at803x_get_stats,
-+      .suspend                = genphy_suspend,
-+      .resume                 = genphy_resume,
- }, {
-       /* QCA8327-B from switch QCA8327-BL1A */
-       .phy_id = QCA8327_B_PHY_ID,
-@@ -1355,6 +1359,8 @@ static struct phy_driver at803x_driver[]
-       .get_sset_count = at803x_get_sset_count,
-       .get_strings = at803x_get_strings,
-       .get_stats = at803x_get_stats,
-+      .suspend                = genphy_suspend,
-+      .resume                 = genphy_resume,
- }, };
- module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-5.10/795-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch b/target/linux/generic/backport-5.10/795-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch
deleted file mode 100644 (file)
index 23f574c..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-From d44fd8604a4ab92119adb35f05fd87612af722b5 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 19 Sep 2021 18:28:17 +0200
-Subject: net: phy: at803x: fix spacing and improve name for 83xx phy
-
-Fix spacing and improve name for 83xx phy following other phy in the
-same driver.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 60 ++++++++++++++++++++++++------------------------
- 1 file changed, 30 insertions(+), 30 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1318,47 +1318,47 @@ static struct phy_driver at803x_driver[]
-       .config_aneg            = at803x_config_aneg,
- }, {
-       /* QCA8337 */
--      .phy_id = QCA8337_PHY_ID,
--      .phy_id_mask = QCA8K_PHY_ID_MASK,
--      .name = "QCA PHY 8337",
-+      .phy_id                 = QCA8337_PHY_ID,
-+      .phy_id_mask            = QCA8K_PHY_ID_MASK,
-+      .name                   = "Qualcomm Atheros 8337 internal PHY",
-       /* PHY_GBIT_FEATURES */
--      .probe = at803x_probe,
--      .flags = PHY_IS_INTERNAL,
--      .config_init = qca83xx_config_init,
--      .soft_reset = genphy_soft_reset,
--      .get_sset_count = at803x_get_sset_count,
--      .get_strings = at803x_get_strings,
--      .get_stats = at803x_get_stats,
-+      .probe                  = at803x_probe,
-+      .flags                  = PHY_IS_INTERNAL,
-+      .config_init            = qca83xx_config_init,
-+      .soft_reset             = genphy_soft_reset,
-+      .get_sset_count         = at803x_get_sset_count,
-+      .get_strings            = at803x_get_strings,
-+      .get_stats              = at803x_get_stats,
-       .suspend                = genphy_suspend,
-       .resume                 = genphy_resume,
- }, {
-       /* QCA8327-A from switch QCA8327-AL1A */
--      .phy_id = QCA8327_A_PHY_ID,
--      .phy_id_mask = QCA8K_PHY_ID_MASK,
--      .name = "QCA PHY 8327-A",
-+      .phy_id                 = QCA8327_A_PHY_ID,
-+      .phy_id_mask            = QCA8K_PHY_ID_MASK,
-+      .name                   = "Qualcomm Atheros 8327-A internal PHY",
-       /* PHY_GBIT_FEATURES */
--      .probe = at803x_probe,
--      .flags = PHY_IS_INTERNAL,
--      .config_init = qca83xx_config_init,
--      .soft_reset = genphy_soft_reset,
--      .get_sset_count = at803x_get_sset_count,
--      .get_strings = at803x_get_strings,
--      .get_stats = at803x_get_stats,
-+      .probe                  = at803x_probe,
-+      .flags                  = PHY_IS_INTERNAL,
-+      .config_init            = qca83xx_config_init,
-+      .soft_reset             = genphy_soft_reset,
-+      .get_sset_count         = at803x_get_sset_count,
-+      .get_strings            = at803x_get_strings,
-+      .get_stats              = at803x_get_stats,
-       .suspend                = genphy_suspend,
-       .resume                 = genphy_resume,
- }, {
-       /* QCA8327-B from switch QCA8327-BL1A */
--      .phy_id = QCA8327_B_PHY_ID,
--      .phy_id_mask = QCA8K_PHY_ID_MASK,
--      .name = "QCA PHY 8327-B",
-+      .phy_id                 = QCA8327_B_PHY_ID,
-+      .phy_id_mask            = QCA8K_PHY_ID_MASK,
-+      .name                   = "Qualcomm Atheros 8327-B internal PHY",
-       /* PHY_GBIT_FEATURES */
--      .probe = at803x_probe,
--      .flags = PHY_IS_INTERNAL,
--      .config_init = qca83xx_config_init,
--      .soft_reset = genphy_soft_reset,
--      .get_sset_count = at803x_get_sset_count,
--      .get_strings = at803x_get_strings,
--      .get_stats = at803x_get_stats,
-+      .probe                  = at803x_probe,
-+      .flags                  = PHY_IS_INTERNAL,
-+      .config_init            = qca83xx_config_init,
-+      .soft_reset             = genphy_soft_reset,
-+      .get_sset_count         = at803x_get_sset_count,
-+      .get_strings            = at803x_get_strings,
-+      .get_stats              = at803x_get_stats,
-       .suspend                = genphy_suspend,
-       .resume                 = genphy_resume,
- }, };
diff --git a/target/linux/generic/backport-5.10/796-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch b/target/linux/generic/backport-5.10/796-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch
deleted file mode 100644 (file)
index 5dfe27d..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-From ba3c01ee02ed0d821c9f241f179bbc9457542b8f Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 10 Oct 2021 00:46:15 +0200
-Subject: net: phy: at803x: fix resume for QCA8327 phy
-
-From Documentation phy resume triggers phy reset and restart
-auto-negotiation. Add a dedicated function to wait reset to finish as
-it was notice a regression where port sometime are not reliable after a
-suspend/resume session. The reset wait logic is copied from phy_poll_reset.
-Add dedicated suspend function to use genphy_suspend only with QCA8337
-phy and set only additional debug settings for QCA8327. With more test
-it was reported that QCA8327 doesn't proprely support this mode and
-using this cause the unreliability of the switch ports, especially the
-malfunction of the port0.
-
-Fixes: 15b9df4ece17 ("net: phy: at803x: add resume/suspend function to qca83xx phy")
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 69 +++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 63 insertions(+), 6 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -92,9 +92,14 @@
- #define AT803X_DEBUG_REG_5                    0x05
- #define AT803X_DEBUG_TX_CLK_DLY_EN            BIT(8)
-+#define AT803X_DEBUG_REG_HIB_CTRL             0x0b
-+#define   AT803X_DEBUG_HIB_CTRL_SEL_RST_80U   BIT(10)
-+#define   AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
-+
- #define AT803X_DEBUG_REG_3C                   0x3C
- #define AT803X_DEBUG_REG_3D                   0x3D
-+#define   AT803X_DEBUG_GATE_CLK_IN1000                BIT(6)
- #define AT803X_DEBUG_REG_1F                   0x1F
- #define AT803X_DEBUG_PLL_ON                   BIT(2)
-@@ -1220,6 +1225,58 @@ static int qca83xx_config_init(struct ph
-       return 0;
- }
-+static int qca83xx_resume(struct phy_device *phydev)
-+{
-+      int ret, val;
-+
-+      /* Skip reset if not suspended */
-+      if (!phydev->suspended)
-+              return 0;
-+
-+      /* Reinit the port, reset values set by suspend */
-+      qca83xx_config_init(phydev);
-+
-+      /* Reset the port on port resume */
-+      phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
-+
-+      /* On resume from suspend the switch execute a reset and
-+       * restart auto-negotiation. Wait for reset to complete.
-+       */
-+      ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
-+                                  50000, 600000, true);
-+      if (ret)
-+              return ret;
-+
-+      msleep(1);
-+
-+      return 0;
-+}
-+
-+static int qca83xx_suspend(struct phy_device *phydev)
-+{
-+      u16 mask = 0;
-+
-+      /* Only QCA8337 support actual suspend.
-+       * QCA8327 cause port unreliability when phy suspend
-+       * is set.
-+       */
-+      if (phydev->drv->phy_id == QCA8337_PHY_ID) {
-+              genphy_suspend(phydev);
-+      } else {
-+              mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
-+              phy_modify(phydev, MII_BMCR, mask, 0);
-+      }
-+
-+      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D,
-+                            AT803X_DEBUG_GATE_CLK_IN1000, 0);
-+
-+      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
-+                            AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE |
-+                            AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0);
-+
-+      return 0;
-+}
-+
- static struct phy_driver at803x_driver[] = {
- {
-       /* Qualcomm Atheros AR8035 */
-@@ -1329,8 +1386,8 @@ static struct phy_driver at803x_driver[]
-       .get_sset_count         = at803x_get_sset_count,
-       .get_strings            = at803x_get_strings,
-       .get_stats              = at803x_get_stats,
--      .suspend                = genphy_suspend,
--      .resume                 = genphy_resume,
-+      .suspend                = qca83xx_suspend,
-+      .resume                 = qca83xx_resume,
- }, {
-       /* QCA8327-A from switch QCA8327-AL1A */
-       .phy_id                 = QCA8327_A_PHY_ID,
-@@ -1344,8 +1401,8 @@ static struct phy_driver at803x_driver[]
-       .get_sset_count         = at803x_get_sset_count,
-       .get_strings            = at803x_get_strings,
-       .get_stats              = at803x_get_stats,
--      .suspend                = genphy_suspend,
--      .resume                 = genphy_resume,
-+      .suspend                = qca83xx_suspend,
-+      .resume                 = qca83xx_resume,
- }, {
-       /* QCA8327-B from switch QCA8327-BL1A */
-       .phy_id                 = QCA8327_B_PHY_ID,
-@@ -1359,8 +1416,8 @@ static struct phy_driver at803x_driver[]
-       .get_sset_count         = at803x_get_sset_count,
-       .get_strings            = at803x_get_strings,
-       .get_stats              = at803x_get_stats,
--      .suspend                = genphy_suspend,
--      .resume                 = genphy_resume,
-+      .suspend                = qca83xx_suspend,
-+      .resume                 = qca83xx_resume,
- }, };
- module_phy_driver(at803x_driver);
diff --git a/target/linux/generic/backport-5.10/796-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch b/target/linux/generic/backport-5.10/796-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch
deleted file mode 100644 (file)
index aeb43e2..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-From 1ca8311949aec5c9447645731ef1c6bc5bd71350 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 10 Oct 2021 00:46:16 +0200
-Subject: net: phy: at803x: add DAC amplitude fix for 8327 phy
-
-QCA8327 internal phy require DAC amplitude adjustement set to +6% with
-100m speed. Also add additional define to report a change of the same
-reg in QCA8337. (different scope it does set 1000m voltage)
-Add link_change_notify function to set the proper amplitude adjustement
-on PHY_RUNNING state and disable on any other state.
-
-Fixes: b4df02b562f4 ("net: phy: at803x: add support for qca 8327 A variant internal phy")
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 33 +++++++++++++++++++++++++++++++++
- 1 file changed, 33 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -87,6 +87,8 @@
- #define AT803X_PSSR_MR_AN_COMPLETE    0x0200
- #define AT803X_DEBUG_REG_0                    0x00
-+#define QCA8327_DEBUG_MANU_CTRL_EN            BIT(2)
-+#define QCA8337_DEBUG_MANU_CTRL_EN            GENMASK(3, 2)
- #define AT803X_DEBUG_RX_CLK_DLY_EN            BIT(15)
- #define AT803X_DEBUG_REG_5                    0x05
-@@ -1222,9 +1224,37 @@ static int qca83xx_config_init(struct ph
-               break;
-       }
-+      /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
-+       * Disable on init and enable only with 100m speed following
-+       * qca original source code.
-+       */
-+      if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
-+          phydev->drv->phy_id == QCA8327_B_PHY_ID)
-+              at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+                                    QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+
-       return 0;
- }
-+static void qca83xx_link_change_notify(struct phy_device *phydev)
-+{
-+      /* QCA8337 doesn't require DAC Amplitude adjustement */
-+      if (phydev->drv->phy_id == QCA8337_PHY_ID)
-+              return;
-+
-+      /* Set DAC Amplitude adjustment to +6% for 100m on link running */
-+      if (phydev->state == PHY_RUNNING) {
-+              if (phydev->speed == SPEED_100)
-+                      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+                                            QCA8327_DEBUG_MANU_CTRL_EN,
-+                                            QCA8327_DEBUG_MANU_CTRL_EN);
-+      } else {
-+              /* Reset DAC Amplitude adjustment */
-+              at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+                                    QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+      }
-+}
-+
- static int qca83xx_resume(struct phy_device *phydev)
- {
-       int ret, val;
-@@ -1379,6 +1409,7 @@ static struct phy_driver at803x_driver[]
-       .phy_id_mask            = QCA8K_PHY_ID_MASK,
-       .name                   = "Qualcomm Atheros 8337 internal PHY",
-       /* PHY_GBIT_FEATURES */
-+      .link_change_notify     = qca83xx_link_change_notify,
-       .probe                  = at803x_probe,
-       .flags                  = PHY_IS_INTERNAL,
-       .config_init            = qca83xx_config_init,
-@@ -1394,6 +1425,7 @@ static struct phy_driver at803x_driver[]
-       .phy_id_mask            = QCA8K_PHY_ID_MASK,
-       .name                   = "Qualcomm Atheros 8327-A internal PHY",
-       /* PHY_GBIT_FEATURES */
-+      .link_change_notify     = qca83xx_link_change_notify,
-       .probe                  = at803x_probe,
-       .flags                  = PHY_IS_INTERNAL,
-       .config_init            = qca83xx_config_init,
-@@ -1409,6 +1441,7 @@ static struct phy_driver at803x_driver[]
-       .phy_id_mask            = QCA8K_PHY_ID_MASK,
-       .name                   = "Qualcomm Atheros 8327-B internal PHY",
-       /* PHY_GBIT_FEATURES */
-+      .link_change_notify     = qca83xx_link_change_notify,
-       .probe                  = at803x_probe,
-       .flags                  = PHY_IS_INTERNAL,
-       .config_init            = qca83xx_config_init,
diff --git a/target/linux/generic/backport-5.10/796-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch b/target/linux/generic/backport-5.10/796-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch
deleted file mode 100644 (file)
index 2352fa0..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From 9d1c29b4028557a496be9c5eb2b4b86063700636 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 10 Oct 2021 00:46:17 +0200
-Subject: net: phy: at803x: enable prefer master for 83xx internal phy
-
-From original QCA source code the port was set to prefer master as port
-type in 1000BASE-T mode. Apply the same settings also here.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -1233,6 +1233,9 @@ static int qca83xx_config_init(struct ph
-               at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-                                     QCA8327_DEBUG_MANU_CTRL_EN, 0);
-+      /* Following original QCA sourcecode set port to prefer master */
-+      phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
-+
-       return 0;
- }
diff --git a/target/linux/generic/backport-5.10/796-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch b/target/linux/generic/backport-5.10/796-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch
deleted file mode 100644 (file)
index 9c28a89..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-From 67999555ff42e91de7654488d9a7735bd9e84555 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 10 Oct 2021 00:46:18 +0200
-Subject: net: phy: at803x: better describe debug regs
-
-Give a name to known debug regs from Documentation instead of using
-unknown hex values.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/phy/at803x.c | 30 +++++++++++++++---------------
- 1 file changed, 15 insertions(+), 15 deletions(-)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -86,12 +86,12 @@
- #define AT803X_PSSR                   0x11    /*PHY-Specific Status Register*/
- #define AT803X_PSSR_MR_AN_COMPLETE    0x0200
--#define AT803X_DEBUG_REG_0                    0x00
-+#define AT803X_DEBUG_ANALOG_TEST_CTRL         0x00
- #define QCA8327_DEBUG_MANU_CTRL_EN            BIT(2)
- #define QCA8337_DEBUG_MANU_CTRL_EN            GENMASK(3, 2)
- #define AT803X_DEBUG_RX_CLK_DLY_EN            BIT(15)
--#define AT803X_DEBUG_REG_5                    0x05
-+#define AT803X_DEBUG_SYSTEM_CTRL_MODE         0x05
- #define AT803X_DEBUG_TX_CLK_DLY_EN            BIT(8)
- #define AT803X_DEBUG_REG_HIB_CTRL             0x0b
-@@ -100,7 +100,7 @@
- #define AT803X_DEBUG_REG_3C                   0x3C
--#define AT803X_DEBUG_REG_3D                   0x3D
-+#define AT803X_DEBUG_REG_GREEN                        0x3D
- #define   AT803X_DEBUG_GATE_CLK_IN1000                BIT(6)
- #define AT803X_DEBUG_REG_1F                   0x1F
-@@ -274,25 +274,25 @@ static int at803x_read_page(struct phy_d
- static int at803x_enable_rx_delay(struct phy_device *phydev)
- {
--      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
-+      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0,
-                                    AT803X_DEBUG_RX_CLK_DLY_EN);
- }
- static int at803x_enable_tx_delay(struct phy_device *phydev)
- {
--      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
-+      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0,
-                                    AT803X_DEBUG_TX_CLK_DLY_EN);
- }
- static int at803x_disable_rx_delay(struct phy_device *phydev)
- {
--      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-                                    AT803X_DEBUG_RX_CLK_DLY_EN, 0);
- }
- static int at803x_disable_tx_delay(struct phy_device *phydev)
- {
--      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
-+      return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE,
-                                    AT803X_DEBUG_TX_CLK_DLY_EN, 0);
- }
-@@ -1208,9 +1208,9 @@ static int qca83xx_config_init(struct ph
-       switch (switch_revision) {
-       case 1:
-               /* For 100M waveform */
--              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_0, 0x02ea);
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea);
-               /* Turn on Gigabit clock */
--              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x68a0);
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0);
-               break;
-       case 2:
-@@ -1218,8 +1218,8 @@ static int qca83xx_config_init(struct ph
-               fallthrough;
-       case 4:
-               phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
--              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x6860);
--              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_5, 0x2c46);
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860);
-+              at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46);
-               at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
-               break;
-       }
-@@ -1230,7 +1230,7 @@ static int qca83xx_config_init(struct ph
-        */
-       if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
-           phydev->drv->phy_id == QCA8327_B_PHY_ID)
--              at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+              at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-                                     QCA8327_DEBUG_MANU_CTRL_EN, 0);
-       /* Following original QCA sourcecode set port to prefer master */
-@@ -1248,12 +1248,12 @@ static void qca83xx_link_change_notify(s
-       /* Set DAC Amplitude adjustment to +6% for 100m on link running */
-       if (phydev->state == PHY_RUNNING) {
-               if (phydev->speed == SPEED_100)
--                      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+                      at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-                                             QCA8327_DEBUG_MANU_CTRL_EN,
-                                             QCA8327_DEBUG_MANU_CTRL_EN);
-       } else {
-               /* Reset DAC Amplitude adjustment */
--              at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
-+              at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
-                                     QCA8327_DEBUG_MANU_CTRL_EN, 0);
-       }
- }
-@@ -1300,7 +1300,7 @@ static int qca83xx_suspend(struct phy_de
-               phy_modify(phydev, MII_BMCR, mask, 0);
-       }
--      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D,
-+      at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
-                             AT803X_DEBUG_GATE_CLK_IN1000, 0);
-       at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
diff --git a/target/linux/generic/backport-5.10/797-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch b/target/linux/generic/backport-5.10/797-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch
deleted file mode 100644 (file)
index c8d424d..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-From d8b6f5bae6d3b648a67b6958cb98e4e97256d652 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:06 +0200
-Subject: dsa: qca8k: add mac_power_sel support
-
-Add missing mac power sel support needed for ipq8064/5 SoC that require
-1.8v for the internal regulator port instead of the default 1.5v.
-If other device needs this, consider adding a dedicated binding to
-support this.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 31 +++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h |  5 +++++
- 2 files changed, 36 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -951,6 +951,33 @@ qca8k_setup_of_rgmii_delay(struct qca8k_
- }
- static int
-+qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
-+{
-+      u32 mask = 0;
-+      int ret = 0;
-+
-+      /* SoC specific settings for ipq8064.
-+       * If more device require this consider adding
-+       * a dedicated binding.
-+       */
-+      if (of_machine_is_compatible("qcom,ipq8064"))
-+              mask |= QCA8K_MAC_PWR_RGMII0_1_8V;
-+
-+      /* SoC specific settings for ipq8065 */
-+      if (of_machine_is_compatible("qcom,ipq8065"))
-+              mask |= QCA8K_MAC_PWR_RGMII1_1_8V;
-+
-+      if (mask) {
-+              ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,
-+                              QCA8K_MAC_PWR_RGMII0_1_8V |
-+                              QCA8K_MAC_PWR_RGMII1_1_8V,
-+                              mask);
-+      }
-+
-+      return ret;
-+}
-+
-+static int
- qca8k_setup(struct dsa_switch *ds)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-@@ -979,6 +1006,10 @@ qca8k_setup(struct dsa_switch *ds)
-       if (ret)
-               return ret;
-+      ret = qca8k_setup_mac_pwr_sel(priv);
-+      if (ret)
-+              return ret;
-+
-       /* Enable CPU Port */
-       ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
-                           QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -100,6 +100,11 @@
- #define   QCA8K_SGMII_MODE_CTRL_PHY                   (1 << 22)
- #define   QCA8K_SGMII_MODE_CTRL_MAC                   (2 << 22)
-+/* MAC_PWR_SEL registers */
-+#define QCA8K_REG_MAC_PWR_SEL                         0x0e4
-+#define   QCA8K_MAC_PWR_RGMII1_1_8V                   BIT(18)
-+#define   QCA8K_MAC_PWR_RGMII0_1_8V                   BIT(19)
-+
- /* EEE control registers */
- #define QCA8K_REG_EEE_CTRL                            0x100
- #define  QCA8K_REG_EEE_CTRL_LPI_EN(_i)                        ((_i + 1) * 2)
diff --git a/target/linux/generic/backport-5.10/797-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch b/target/linux/generic/backport-5.10/797-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch
deleted file mode 100644 (file)
index bd768ec..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From fdbf35df9c091db9c46e57e9938e3f7a4f603a7c Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:07 +0200
-Subject: dt-bindings: net: dsa: qca8k: Add SGMII clock phase properties
-
-Add names and descriptions of additional PORT0_PAD_CTRL properties.
-qca,sgmii-(rx|tx)clk-falling-edge are for setting the respective clock
-phase to failling edge.
-
-Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -37,6 +37,10 @@ A CPU port node has the following option
-                           managed entity. See
-                           Documentation/devicetree/bindings/net/fixed-link.txt
-                           for details.
-+- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
-+                                Mostly used in qca8327 with CPU port 0 set to
-+                                sgmii.
-+- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
- For QCA8K the 'fixed-link' sub-node supports only the following properties:
diff --git a/target/linux/generic/backport-5.10/797-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch b/target/linux/generic/backport-5.10/797-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch
deleted file mode 100644 (file)
index e464452..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-From 6c43809bf1bee76c434e365a26546a92a5fbec14 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:08 +0200
-Subject: net: dsa: qca8k: add support for sgmii falling edge
-
-Add support for this in the qca8k driver. Also add support for SGMII
-rx/tx clock falling edge. This is only present for pad0, pad5 and
-pad6 have these bit reserved from Documentation. Add a comment that this
-is hardcoded to PAD0 as qca8327/28/34/37 have an unique sgmii line and
-setting falling in port0 applies to both configuration with sgmii used
-for port0 or port6.
-
-Co-developed-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h |  4 ++++
- 2 files changed, 67 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -978,6 +978,42 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
- }
- static int
-+qca8k_parse_port_config(struct qca8k_priv *priv)
-+{
-+      struct device_node *port_dn;
-+      phy_interface_t mode;
-+      struct dsa_port *dp;
-+      int port, ret;
-+
-+      /* We have 2 CPU port. Check them */
-+      for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+              /* Skip every other port */
-+              if (port != 0 && port != 6)
-+                      continue;
-+
-+              dp = dsa_to_port(priv->ds, port);
-+              port_dn = dp->dn;
-+
-+              if (!of_device_is_available(port_dn))
-+                      continue;
-+
-+              ret = of_get_phy_mode(port_dn, &mode);
-+              if (ret)
-+                      continue;
-+
-+              if (mode == PHY_INTERFACE_MODE_SGMII) {
-+                      if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-+                              priv->sgmii_tx_clk_falling_edge = true;
-+
-+                      if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-+                              priv->sgmii_rx_clk_falling_edge = true;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int
- qca8k_setup(struct dsa_switch *ds)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-@@ -990,6 +1026,11 @@ qca8k_setup(struct dsa_switch *ds)
-               return -EINVAL;
-       }
-+      /* Parse CPU port config to be later used in phy_link mac_config */
-+      ret = qca8k_parse_port_config(priv);
-+      if (ret)
-+              return ret;
-+
-       mutex_init(&priv->reg_mutex);
-       /* Start by setting up the register mapping */
-@@ -1274,6 +1315,28 @@ qca8k_phylink_mac_config(struct dsa_swit
-               }
-               qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
-+
-+              /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and
-+               * falling edge is set writing in the PORT0 PAD reg
-+               */
-+              if (priv->switch_id == QCA8K_ID_QCA8327 ||
-+                  priv->switch_id == QCA8K_ID_QCA8337)
-+                      reg = QCA8K_REG_PORT0_PAD_CTRL;
-+
-+              val = 0;
-+
-+              /* SGMII Clock phase configuration */
-+              if (priv->sgmii_rx_clk_falling_edge)
-+                      val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
-+
-+              if (priv->sgmii_tx_clk_falling_edge)
-+                      val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
-+
-+              if (val)
-+                      ret = qca8k_rmw(priv, reg,
-+                                      QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
-+                                      QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
-+                                      val);
-               break;
-       default:
-               dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -35,6 +35,8 @@
- #define   QCA8K_MASK_CTRL_DEVICE_ID_MASK              GENMASK(15, 8)
- #define   QCA8K_MASK_CTRL_DEVICE_ID(x)                        ((x) >> 8)
- #define QCA8K_REG_PORT0_PAD_CTRL                      0x004
-+#define   QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE    BIT(19)
-+#define   QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE    BIT(18)
- #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
- #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
- #define   QCA8K_PORT_PAD_RGMII_EN                     BIT(26)
-@@ -260,6 +262,8 @@ struct qca8k_priv {
-       u8 switch_revision;
-       u8 rgmii_tx_delay;
-       u8 rgmii_rx_delay;
-+      bool sgmii_rx_clk_falling_edge;
-+      bool sgmii_tx_clk_falling_edge;
-       bool legacy_phy_port_mapping;
-       struct regmap *regmap;
-       struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.10/797-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch b/target/linux/generic/backport-5.10/797-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch
deleted file mode 100644 (file)
index 606ac0a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From 731d613338ec6de482053ffa3f71be2325b0f8eb Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:09 +0200
-Subject: dt-bindings: net: dsa: qca8k: Document support for CPU port 6
-
-The switch now support CPU port to be set 6 instead of be hardcoded to
-0. Document support for it and describe logic selection.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -29,7 +29,11 @@ the mdio MASTER is used as communication
- Don't use mixed external and internal mdio-bus configurations, as this is
- not supported by the hardware.
--The CPU port of this switch is always port 0.
-+This switch support 2 CPU port. Normally and advised configuration is with
-+CPU port set to port 0. It is also possible to set the CPU port to port 6
-+if the device requires it. The driver will configure the switch to the defined
-+port. With both CPU port declared the first CPU port is selected as primary
-+and the secondary CPU ignored.
- A CPU port node has the following optional node:
diff --git a/target/linux/generic/backport-5.10/797-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch b/target/linux/generic/backport-5.10/797-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch
deleted file mode 100644 (file)
index 320db8f..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-From 3fcf734aa482487df83cf8f18608438fcf59127f Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:10 +0200
-Subject: net: dsa: qca8k: add support for cpu port 6
-
-Currently CPU port is always hardcoded to port 0. This switch have 2 CPU
-ports. The original intention of this driver seems to be use the
-mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration
-where device have connected only the CPU port 6. To skip the
-introduction of a new binding, rework the driver to address the
-secondary CPU port as primary and drop any reference of hardcoded port.
-With configuration of mac06 exchange, just skip the definition of port0
-and define the CPU port as a secondary. The driver will autoconfigure
-the switch to use that as the primary CPU port.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 51 ++++++++++++++++++++++++++++++++++---------------
- drivers/net/dsa/qca8k.h |  2 --
- 2 files changed, 36 insertions(+), 17 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
-       return ret;
- }
-+static int qca8k_find_cpu_port(struct dsa_switch *ds)
-+{
-+      struct qca8k_priv *priv = ds->priv;
-+
-+      /* Find the connected cpu port. Valid port are 0 or 6 */
-+      if (dsa_is_cpu_port(ds, 0))
-+              return 0;
-+
-+      dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
-+
-+      if (dsa_is_cpu_port(ds, 6))
-+              return 6;
-+
-+      return -EINVAL;
-+}
-+
- static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
-@@ -1017,13 +1033,13 @@ static int
- qca8k_setup(struct dsa_switch *ds)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--      int ret, i;
-+      int cpu_port, ret, i;
-       u32 mask;
--      /* Make sure that port 0 is the cpu port */
--      if (!dsa_is_cpu_port(ds, 0)) {
--              dev_err(priv->dev, "port 0 is not the CPU port");
--              return -EINVAL;
-+      cpu_port = qca8k_find_cpu_port(ds);
-+      if (cpu_port < 0) {
-+              dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
-+              return cpu_port;
-       }
-       /* Parse CPU port config to be later used in phy_link mac_config */
-@@ -1065,7 +1081,7 @@ qca8k_setup(struct dsa_switch *ds)
-               dev_warn(priv->dev, "mib init failed");
-       /* Enable QCA header mode on the cpu port */
--      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
-+      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
-                         QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
-                         QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
-       if (ret) {
-@@ -1087,10 +1103,10 @@ qca8k_setup(struct dsa_switch *ds)
-       /* Forward all unknown frames to CPU port for Linux processing */
-       ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
--                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
--                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
--                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
--                        BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
-+                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
-+                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
-+                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
-+                        BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
-       if (ret)
-               return ret;
-@@ -1098,7 +1114,7 @@ qca8k_setup(struct dsa_switch *ds)
-       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-               /* CPU port gets connected to all user ports of the switch */
-               if (dsa_is_cpu_port(ds, i)) {
--                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
-+                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
-                                       QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-                       if (ret)
-                               return ret;
-@@ -1110,7 +1126,7 @@ qca8k_setup(struct dsa_switch *ds)
-                       ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-                                       QCA8K_PORT_LOOKUP_MEMBER,
--                                      BIT(QCA8K_CPU_PORT));
-+                                      BIT(cpu_port));
-                       if (ret)
-                               return ret;
-@@ -1616,9 +1632,12 @@ static int
- qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--      int port_mask = BIT(QCA8K_CPU_PORT);
-+      int port_mask, cpu_port;
-       int i, ret;
-+      cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-+      port_mask = BIT(cpu_port);
-+
-       for (i = 1; i < QCA8K_NUM_PORTS; i++) {
-               if (dsa_to_port(ds, i)->bridge_dev != br)
-                       continue;
-@@ -1645,7 +1664,9 @@ static void
- qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
- {
-       struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
--      int i;
-+      int cpu_port, i;
-+
-+      cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-       for (i = 1; i < QCA8K_NUM_PORTS; i++) {
-               if (dsa_to_port(ds, i)->bridge_dev != br)
-@@ -1662,7 +1683,7 @@ qca8k_port_bridge_leave(struct dsa_switc
-        * this port
-        */
-       qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
--                QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT));
-+                QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
- }
- static int
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -24,8 +24,6 @@
- #define QCA8K_NUM_FDB_RECORDS                         2048
--#define QCA8K_CPU_PORT                                        0
--
- #define QCA8K_PORT_VID_DEF                            1
- /* Global control registers */
diff --git a/target/linux/generic/backport-5.10/797-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch b/target/linux/generic/backport-5.10/797-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch
deleted file mode 100644 (file)
index de20176..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-From 5654ec78dd7e64b1e04777b24007344329e6a63b Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:11 +0200
-Subject: net: dsa: qca8k: rework rgmii delay logic and scan for cpu port 6
-
-Future proof commit. This switch have 2 CPU ports and one valid
-configuration is first CPU port set to sgmii and second CPU port set to
-rgmii-id. The current implementation detects delay only for CPU port
-zero set to rgmii and doesn't count any delay set in a secondary CPU
-port. Drop the current delay scan function and move it to the sgmii
-parser function to generalize and implicitly add support for secondary
-CPU port set to rgmii-id. Introduce new logic where delay is enabled
-also with internal delay binding declared and rgmii set as PHY mode.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 165 ++++++++++++++++++++++++------------------------
- drivers/net/dsa/qca8k.h |  10 ++-
- 2 files changed, 89 insertions(+), 86 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -889,68 +889,6 @@ qca8k_setup_mdio_bus(struct qca8k_priv *
- }
- static int
--qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv)
--{
--      struct device_node *port_dn;
--      phy_interface_t mode;
--      struct dsa_port *dp;
--      u32 val;
--
--      /* CPU port is already checked */
--      dp = dsa_to_port(priv->ds, 0);
--
--      port_dn = dp->dn;
--
--      /* Check if port 0 is set to the correct type */
--      of_get_phy_mode(port_dn, &mode);
--      if (mode != PHY_INTERFACE_MODE_RGMII_ID &&
--          mode != PHY_INTERFACE_MODE_RGMII_RXID &&
--          mode != PHY_INTERFACE_MODE_RGMII_TXID) {
--              return 0;
--      }
--
--      switch (mode) {
--      case PHY_INTERFACE_MODE_RGMII_ID:
--      case PHY_INTERFACE_MODE_RGMII_RXID:
--              if (of_property_read_u32(port_dn, "rx-internal-delay-ps", &val))
--                      val = 2;
--              else
--                      /* Switch regs accept value in ns, convert ps to ns */
--                      val = val / 1000;
--
--              if (val > QCA8K_MAX_DELAY) {
--                      dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
--                      val = 3;
--              }
--
--              priv->rgmii_rx_delay = val;
--              /* Stop here if we need to check only for rx delay */
--              if (mode != PHY_INTERFACE_MODE_RGMII_ID)
--                      break;
--
--              fallthrough;
--      case PHY_INTERFACE_MODE_RGMII_TXID:
--              if (of_property_read_u32(port_dn, "tx-internal-delay-ps", &val))
--                      val = 1;
--              else
--                      /* Switch regs accept value in ns, convert ps to ns */
--                      val = val / 1000;
--
--              if (val > QCA8K_MAX_DELAY) {
--                      dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
--                      val = 3;
--              }
--
--              priv->rgmii_tx_delay = val;
--              break;
--      default:
--              return 0;
--      }
--
--      return 0;
--}
--
--static int
- qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
- {
-       u32 mask = 0;
-@@ -996,19 +934,21 @@ static int qca8k_find_cpu_port(struct ds
- static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
-+      int port, cpu_port_index = 0, ret;
-       struct device_node *port_dn;
-       phy_interface_t mode;
-       struct dsa_port *dp;
--      int port, ret;
-+      u32 delay;
-       /* We have 2 CPU port. Check them */
--      for (port = 0; port < QCA8K_NUM_PORTS; port++) {
-+      for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) {
-               /* Skip every other port */
-               if (port != 0 && port != 6)
-                       continue;
-               dp = dsa_to_port(priv->ds, port);
-               port_dn = dp->dn;
-+              cpu_port_index++;
-               if (!of_device_is_available(port_dn))
-                       continue;
-@@ -1017,12 +957,54 @@ qca8k_parse_port_config(struct qca8k_pri
-               if (ret)
-                       continue;
--              if (mode == PHY_INTERFACE_MODE_SGMII) {
-+              switch (mode) {
-+              case PHY_INTERFACE_MODE_RGMII:
-+              case PHY_INTERFACE_MODE_RGMII_ID:
-+              case PHY_INTERFACE_MODE_RGMII_TXID:
-+              case PHY_INTERFACE_MODE_RGMII_RXID:
-+                      delay = 0;
-+
-+                      if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
-+                              /* Switch regs accept value in ns, convert ps to ns */
-+                              delay = delay / 1000;
-+                      else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+                               mode == PHY_INTERFACE_MODE_RGMII_TXID)
-+                              delay = 1;
-+
-+                      if (delay > QCA8K_MAX_DELAY) {
-+                              dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value");
-+                              delay = 3;
-+                      }
-+
-+                      priv->rgmii_tx_delay[cpu_port_index] = delay;
-+
-+                      delay = 0;
-+
-+                      if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay))
-+                              /* Switch regs accept value in ns, convert ps to ns */
-+                              delay = delay / 1000;
-+                      else if (mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+                               mode == PHY_INTERFACE_MODE_RGMII_RXID)
-+                              delay = 2;
-+
-+                      if (delay > QCA8K_MAX_DELAY) {
-+                              dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value");
-+                              delay = 3;
-+                      }
-+
-+                      priv->rgmii_rx_delay[cpu_port_index] = delay;
-+
-+                      break;
-+              case PHY_INTERFACE_MODE_SGMII:
-                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-                               priv->sgmii_tx_clk_falling_edge = true;
-                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-                               priv->sgmii_rx_clk_falling_edge = true;
-+
-+                      break;
-+              default:
-+                      continue;
-               }
-       }
-@@ -1059,10 +1041,6 @@ qca8k_setup(struct dsa_switch *ds)
-       if (ret)
-               return ret;
--      ret = qca8k_setup_of_rgmii_delay(priv);
--      if (ret)
--              return ret;
--
-       ret = qca8k_setup_mac_pwr_sel(priv);
-       if (ret)
-               return ret;
-@@ -1229,8 +1207,8 @@ qca8k_phylink_mac_config(struct dsa_swit
-                        const struct phylink_link_state *state)
- {
-       struct qca8k_priv *priv = ds->priv;
--      u32 reg, val;
--      int ret;
-+      int cpu_port_index, ret;
-+      u32 reg, val, delay;
-       switch (port) {
-       case 0: /* 1st CPU port */
-@@ -1242,6 +1220,7 @@ qca8k_phylink_mac_config(struct dsa_swit
-                       return;
-               reg = QCA8K_REG_PORT0_PAD_CTRL;
-+              cpu_port_index = QCA8K_CPU_PORT0;
-               break;
-       case 1:
-       case 2:
-@@ -1260,6 +1239,7 @@ qca8k_phylink_mac_config(struct dsa_swit
-                       return;
-               reg = QCA8K_REG_PORT6_PAD_CTRL;
-+              cpu_port_index = QCA8K_CPU_PORT6;
-               break;
-       default:
-               dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
-@@ -1274,23 +1254,40 @@ qca8k_phylink_mac_config(struct dsa_swit
-       switch (state->interface) {
-       case PHY_INTERFACE_MODE_RGMII:
--              /* RGMII mode means no delay so don't enable the delay */
--              qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
--              break;
-       case PHY_INTERFACE_MODE_RGMII_ID:
-       case PHY_INTERFACE_MODE_RGMII_TXID:
-       case PHY_INTERFACE_MODE_RGMII_RXID:
--              /* RGMII_ID needs internal delay. This is enabled through
--               * PORT5_PAD_CTRL for all ports, rather than individual port
--               * registers
-+              val = QCA8K_PORT_PAD_RGMII_EN;
-+
-+              /* Delay can be declared in 3 different way.
-+               * Mode to rgmii and internal-delay standard binding defined
-+               * rgmii-id or rgmii-tx/rx phy mode set.
-+               * The parse logic set a delay different than 0 only when one
-+               * of the 3 different way is used. In all other case delay is
-+               * not enabled. With ID or TX/RXID delay is enabled and set
-+               * to the default and recommended value.
-+               */
-+              if (priv->rgmii_tx_delay[cpu_port_index]) {
-+                      delay = priv->rgmii_tx_delay[cpu_port_index];
-+
-+                      val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-+                             QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-+              }
-+
-+              if (priv->rgmii_rx_delay[cpu_port_index]) {
-+                      delay = priv->rgmii_rx_delay[cpu_port_index];
-+
-+                      val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-+                             QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-+              }
-+
-+              /* Set RGMII delay based on the selected values */
-+              qca8k_write(priv, reg, val);
-+
-+              /* QCA8337 requires to set rgmii rx delay for all ports.
-+               * This is enabled through PORT5_PAD_CTRL for all ports,
-+               * rather than individual port registers.
-                */
--              qca8k_write(priv, reg,
--                          QCA8K_PORT_PAD_RGMII_EN |
--                          QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay) |
--                          QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay) |
--                          QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
--                          QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
--              /* QCA8337 requires to set rgmii rx delay */
-               if (priv->switch_id == QCA8K_ID_QCA8337)
-                       qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-                                   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -13,6 +13,7 @@
- #include <linux/gpio.h>
- #define QCA8K_NUM_PORTS                                       7
-+#define QCA8K_NUM_CPU_PORTS                           2
- #define QCA8K_MAX_MTU                                 9000
- #define PHY_ID_QCA8327                                        0x004dd034
-@@ -255,13 +256,18 @@ struct qca8k_match_data {
-       u8 id;
- };
-+enum {
-+      QCA8K_CPU_PORT0,
-+      QCA8K_CPU_PORT6,
-+};
-+
- struct qca8k_priv {
-       u8 switch_id;
-       u8 switch_revision;
--      u8 rgmii_tx_delay;
--      u8 rgmii_rx_delay;
-       bool sgmii_rx_clk_falling_edge;
-       bool sgmii_tx_clk_falling_edge;
-+      u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-+      u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-       bool legacy_phy_port_mapping;
-       struct regmap *regmap;
-       struct mii_bus *bus;
diff --git a/target/linux/generic/backport-5.10/797-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch b/target/linux/generic/backport-5.10/797-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch
deleted file mode 100644 (file)
index 8abd264..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From 13ad5ccc093ff448b99ac7e138e91e78796adb48 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:12 +0200
-Subject: dt-bindings: net: dsa: qca8k: Document qca,sgmii-enable-pll
-
-Document qca,sgmii-enable-pll binding used in the CPU nodes to
-enable SGMII PLL on MAC config.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -45,6 +45,16 @@ A CPU port node has the following option
-                                 Mostly used in qca8327 with CPU port 0 set to
-                                 sgmii.
- - qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
-+- qca,sgmii-enable-pll  : For SGMII CPU port, explicitly enable PLL, TX and RX
-+                          chain along with Signal Detection.
-+                          This should NOT be enabled for qca8327. If enabled with
-+                          qca8327 the sgmii port won't correctly init and an err
-+                          is printed.
-+                          This can be required for qca8337 switch with revision 2.
-+                          A warning is displayed when used with revision greater
-+                          2.
-+                          With CPU port set to sgmii and qca8337 it is advised
-+                          to set this unless a communication problem is observed.
- For QCA8K the 'fixed-link' sub-node supports only the following properties:
diff --git a/target/linux/generic/backport-5.10/797-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch b/target/linux/generic/backport-5.10/797-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch
deleted file mode 100644 (file)
index 2b5a84a..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-From bbc4799e8bb6c397e3b3fec13de68e179f5db9ff Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:13 +0200
-Subject: net: dsa: qca8k: add explicit SGMII PLL enable
-
-Support enabling PLL on the SGMII CPU port. Some device require this
-special configuration or no traffic is transmitted and the switch
-doesn't work at all. A dedicated binding is added to the CPU node
-port to apply the correct reg on mac config.
-Fail to correctly configure sgmii with qca8327 switch and warn if pll is
-used on qca8337 with a revision greater than 1.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 19 +++++++++++++++++--
- drivers/net/dsa/qca8k.h |  1 +
- 2 files changed, 18 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1002,6 +1002,18 @@ qca8k_parse_port_config(struct qca8k_pri
-                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
-                               priv->sgmii_rx_clk_falling_edge = true;
-+                      if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
-+                              priv->sgmii_enable_pll = true;
-+
-+                              if (priv->switch_id == QCA8K_ID_QCA8327) {
-+                                      dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
-+                                      priv->sgmii_enable_pll = false;
-+                              }
-+
-+                              if (priv->switch_revision < 2)
-+                                      dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");
-+                      }
-+
-                       break;
-               default:
-                       continue;
-@@ -1312,8 +1324,11 @@ qca8k_phylink_mac_config(struct dsa_swit
-               if (ret)
-                       return;
--              val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
--                      QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
-+              val |= QCA8K_SGMII_EN_SD;
-+
-+              if (priv->sgmii_enable_pll)
-+                      val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-+                             QCA8K_SGMII_EN_TX;
-               if (dsa_is_cpu_port(ds, port)) {
-                       /* CPU port, we're talking to the CPU MAC, be a PHY */
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -266,6 +266,7 @@ struct qca8k_priv {
-       u8 switch_revision;
-       bool sgmii_rx_clk_falling_edge;
-       bool sgmii_tx_clk_falling_edge;
-+      bool sgmii_enable_pll;
-       u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-       u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-       bool legacy_phy_port_mapping;
diff --git a/target/linux/generic/backport-5.10/797-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch b/target/linux/generic/backport-5.10/797-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch
deleted file mode 100644 (file)
index 38dc954..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From 924087c5c3d41553700b0eb83ca2a53b91643dca Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:14 +0200
-Subject: dt-bindings: net: dsa: qca8k: Document qca,led-open-drain binding
-
-Document new binding qca,ignore-power-on-sel used to ignore
-power on strapping and use sw regs instead.
-Document qca,led-open.drain to set led to open drain mode, the
-qca,ignore-power-on-sel is mandatory with this enabled or an error will
-be reported.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -13,6 +13,17 @@ Required properties:
- Optional properties:
- - reset-gpios: GPIO to be used to reset the whole device
-+- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
-+                           drain or eeprom presence. This is needed for broken
-+                           devices that have wrong configuration or when the oem
-+                           decided to not use pin strapping and fallback to sw
-+                           regs.
-+- qca,led-open-drain: Set leds to open-drain mode. This requires the
-+                      qca,ignore-power-on-sel to be set or the driver will fail
-+                      to probe. This is needed if the oem doesn't use pin
-+                      strapping to set this mode and prefers to set it using sw
-+                      regs. The pin strapping related to led open drain mode is
-+                      the pin B68 for QCA832x and B49 for QCA833x
- Subnodes:
diff --git a/target/linux/generic/backport-5.10/797-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch b/target/linux/generic/backport-5.10/797-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch
deleted file mode 100644 (file)
index aa5d92a..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-From 362bb238d8bf1470424214a8a5968d9c6cce68fa Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:15 +0200
-Subject: net: dsa: qca8k: add support for pws config reg
-
-Some qca8327 switch require to force the ignore of power on sel
-strapping. Some switch require to set the led open drain mode in regs
-instead of using strapping. While most of the device implements this
-using the correct way using pin strapping, there are still some broken
-device that require to be set using sw regs.
-Introduce a new binding and support these special configuration.
-As led open drain require to ignore pin strapping to work, the probe
-fails with EINVAL error with incorrect configuration.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 39 +++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/qca8k.h |  6 ++++++
- 2 files changed, 45 insertions(+)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -932,6 +932,41 @@ static int qca8k_find_cpu_port(struct ds
- }
- static int
-+qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
-+{
-+      struct device_node *node = priv->dev->of_node;
-+      u32 val = 0;
-+      int ret;
-+
-+      /* QCA8327 require to set to the correct mode.
-+       * His bigger brother QCA8328 have the 172 pin layout.
-+       * Should be applied by default but we set this just to make sure.
-+       */
-+      if (priv->switch_id == QCA8K_ID_QCA8327) {
-+              ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
-+                              QCA8327_PWS_PACKAGE148_EN);
-+              if (ret)
-+                      return ret;
-+      }
-+
-+      if (of_property_read_bool(node, "qca,ignore-power-on-sel"))
-+              val |= QCA8K_PWS_POWER_ON_SEL;
-+
-+      if (of_property_read_bool(node, "qca,led-open-drain")) {
-+              if (!(val & QCA8K_PWS_POWER_ON_SEL)) {
-+                      dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set.");
-+                      return -EINVAL;
-+              }
-+
-+              val |= QCA8K_PWS_LED_OPEN_EN_CSR;
-+      }
-+
-+      return qca8k_rmw(priv, QCA8K_REG_PWS,
-+                      QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,
-+                      val);
-+}
-+
-+static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
-       int port, cpu_port_index = 0, ret;
-@@ -1053,6 +1088,10 @@ qca8k_setup(struct dsa_switch *ds)
-       if (ret)
-               return ret;
-+      ret = qca8k_setup_of_pws_reg(priv);
-+      if (ret)
-+              return ret;
-+
-       ret = qca8k_setup_mac_pwr_sel(priv);
-       if (ret)
-               return ret;
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -46,6 +46,12 @@
- #define   QCA8K_MAX_DELAY                             3
- #define   QCA8K_PORT_PAD_SGMII_EN                     BIT(7)
- #define QCA8K_REG_PWS                                 0x010
-+#define   QCA8K_PWS_POWER_ON_SEL                      BIT(31)
-+/* This reg is only valid for QCA832x and toggle the package
-+ * type from 176 pin (by default) to 148 pin used on QCA8327
-+ */
-+#define   QCA8327_PWS_PACKAGE148_EN                   BIT(30)
-+#define   QCA8K_PWS_LED_OPEN_EN_CSR                   BIT(24)
- #define   QCA8K_PWS_SERDES_AEN_DIS                    BIT(7)
- #define QCA8K_REG_MODULE_EN                           0x030
- #define   QCA8K_MODULE_EN_MIB                         BIT(0)
diff --git a/target/linux/generic/backport-5.10/797-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch b/target/linux/generic/backport-5.10/797-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch
deleted file mode 100644 (file)
index 1bfb00c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From ed7988d77fbfb79366b68f9e7fa60a6080da23d4 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:16 +0200
-Subject: dt-bindings: net: dsa: qca8k: document support for qca8328
-
-QCA8328 is the bigger brother of qca8327. Document the new compatible
-binding and add some information to understand the various switch
-compatible.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/dsa/qca8k.txt | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-@@ -3,9 +3,10 @@
- Required properties:
- - compatible: should be one of:
--    "qca,qca8327"
--    "qca,qca8334"
--    "qca,qca8337"
-+    "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
-+    "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
-+    "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
-+    "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
- - #size-cells: must be 0
- - #address-cells: must be 1
diff --git a/target/linux/generic/backport-5.10/797-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch b/target/linux/generic/backport-5.10/797-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch
deleted file mode 100644 (file)
index 6e118f5..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-From f477d1c8bdbef4f400718238e350f16f521d2a3e Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:17 +0200
-Subject: net: dsa: qca8k: add support for QCA8328
-
-QCA8328 switch is the bigger brother of the qca8327. Same regs different
-chip. Change the function to set the correct pin layout and introduce a
-new match_data to differentiate the 2 switch as they have the same ID
-and their internal PHY have the same ID.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 19 ++++++++++++++++---
- drivers/net/dsa/qca8k.h |  1 +
- 2 files changed, 17 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -935,6 +935,7 @@ static int
- qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
- {
-       struct device_node *node = priv->dev->of_node;
-+      const struct qca8k_match_data *data;
-       u32 val = 0;
-       int ret;
-@@ -943,8 +944,14 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
-        * Should be applied by default but we set this just to make sure.
-        */
-       if (priv->switch_id == QCA8K_ID_QCA8327) {
-+              data = of_device_get_match_data(priv->dev);
-+
-+              /* Set the correct package of 148 pin for QCA8327 */
-+              if (data->reduced_package)
-+                      val |= QCA8327_PWS_PACKAGE148_EN;
-+
-               ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,
--                              QCA8327_PWS_PACKAGE148_EN);
-+                              val);
-               if (ret)
-                       return ret;
-       }
-@@ -2098,7 +2105,12 @@ static int qca8k_resume(struct device *d
- static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
-                        qca8k_suspend, qca8k_resume);
--static const struct qca8k_match_data qca832x = {
-+static const struct qca8k_match_data qca8327 = {
-+      .id = QCA8K_ID_QCA8327,
-+      .reduced_package = true,
-+};
-+
-+static const struct qca8k_match_data qca8328 = {
-       .id = QCA8K_ID_QCA8327,
- };
-@@ -2107,7 +2119,8 @@ static const struct qca8k_match_data qca
- };
- static const struct of_device_id qca8k_of_match[] = {
--      { .compatible = "qca,qca8327", .data = &qca832x },
-+      { .compatible = "qca,qca8327", .data = &qca8327 },
-+      { .compatible = "qca,qca8328", .data = &qca8328 },
-       { .compatible = "qca,qca8334", .data = &qca833x },
-       { .compatible = "qca,qca8337", .data = &qca833x },
-       { /* sentinel */ },
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -260,6 +260,7 @@ struct ar8xxx_port_status {
- struct qca8k_match_data {
-       u8 id;
-+      bool reduced_package;
- };
- enum {
diff --git a/target/linux/generic/backport-5.10/797-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch b/target/linux/generic/backport-5.10/797-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch
deleted file mode 100644 (file)
index 27f94dc..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-From cef08115846e581f80ff99abf7bf218da1840616 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:18 +0200
-Subject: net: dsa: qca8k: set internal delay also for sgmii
-
-QCA original code report port instability and sa that SGMII also require
-to set internal delay. Generalize the rgmii delay function and apply the
-advised value if they are not defined in DT.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 88 +++++++++++++++++++++++++++++++++----------------
- drivers/net/dsa/qca8k.h |  2 ++
- 2 files changed, 62 insertions(+), 28 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1004,6 +1004,7 @@ qca8k_parse_port_config(struct qca8k_pri
-               case PHY_INTERFACE_MODE_RGMII_ID:
-               case PHY_INTERFACE_MODE_RGMII_TXID:
-               case PHY_INTERFACE_MODE_RGMII_RXID:
-+              case PHY_INTERFACE_MODE_SGMII:
-                       delay = 0;
-                       if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay))
-@@ -1036,8 +1037,13 @@ qca8k_parse_port_config(struct qca8k_pri
-                       priv->rgmii_rx_delay[cpu_port_index] = delay;
--                      break;
--              case PHY_INTERFACE_MODE_SGMII:
-+                      /* Skip sgmii parsing for rgmii* mode */
-+                      if (mode == PHY_INTERFACE_MODE_RGMII ||
-+                          mode == PHY_INTERFACE_MODE_RGMII_ID ||
-+                          mode == PHY_INTERFACE_MODE_RGMII_TXID ||
-+                          mode == PHY_INTERFACE_MODE_RGMII_RXID)
-+                              break;
-+
-                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
-                               priv->sgmii_tx_clk_falling_edge = true;
-@@ -1261,12 +1267,53 @@ qca8k_setup(struct dsa_switch *ds)
- }
- static void
-+qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,
-+                                    u32 reg)
-+{
-+      u32 delay, val = 0;
-+      int ret;
-+
-+      /* Delay can be declared in 3 different way.
-+       * Mode to rgmii and internal-delay standard binding defined
-+       * rgmii-id or rgmii-tx/rx phy mode set.
-+       * The parse logic set a delay different than 0 only when one
-+       * of the 3 different way is used. In all other case delay is
-+       * not enabled. With ID or TX/RXID delay is enabled and set
-+       * to the default and recommended value.
-+       */
-+      if (priv->rgmii_tx_delay[cpu_port_index]) {
-+              delay = priv->rgmii_tx_delay[cpu_port_index];
-+
-+              val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-+                      QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-+      }
-+
-+      if (priv->rgmii_rx_delay[cpu_port_index]) {
-+              delay = priv->rgmii_rx_delay[cpu_port_index];
-+
-+              val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-+                      QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-+      }
-+
-+      /* Set RGMII delay based on the selected values */
-+      ret = qca8k_rmw(priv, reg,
-+                      QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |
-+                      QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK |
-+                      QCA8K_PORT_PAD_RGMII_TX_DELAY_EN |
-+                      QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,
-+                      val);
-+      if (ret)
-+              dev_err(priv->dev, "Failed to set internal delay for CPU port%d",
-+                      cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6);
-+}
-+
-+static void
- qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-                        const struct phylink_link_state *state)
- {
-       struct qca8k_priv *priv = ds->priv;
-       int cpu_port_index, ret;
--      u32 reg, val, delay;
-+      u32 reg, val;
-       switch (port) {
-       case 0: /* 1st CPU port */
-@@ -1315,32 +1362,10 @@ qca8k_phylink_mac_config(struct dsa_swit
-       case PHY_INTERFACE_MODE_RGMII_ID:
-       case PHY_INTERFACE_MODE_RGMII_TXID:
-       case PHY_INTERFACE_MODE_RGMII_RXID:
--              val = QCA8K_PORT_PAD_RGMII_EN;
--
--              /* Delay can be declared in 3 different way.
--               * Mode to rgmii and internal-delay standard binding defined
--               * rgmii-id or rgmii-tx/rx phy mode set.
--               * The parse logic set a delay different than 0 only when one
--               * of the 3 different way is used. In all other case delay is
--               * not enabled. With ID or TX/RXID delay is enabled and set
--               * to the default and recommended value.
--               */
--              if (priv->rgmii_tx_delay[cpu_port_index]) {
--                      delay = priv->rgmii_tx_delay[cpu_port_index];
--
--                      val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
--                             QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
--              }
--
--              if (priv->rgmii_rx_delay[cpu_port_index]) {
--                      delay = priv->rgmii_rx_delay[cpu_port_index];
--
--                      val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
--                             QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
--              }
-+              qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
--              /* Set RGMII delay based on the selected values */
--              qca8k_write(priv, reg, val);
-+              /* Configure rgmii delay */
-+              qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-               /* QCA8337 requires to set rgmii rx delay for all ports.
-                * This is enabled through PORT5_PAD_CTRL for all ports,
-@@ -1411,6 +1436,13 @@ qca8k_phylink_mac_config(struct dsa_swit
-                                       QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |
-                                       QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,
-                                       val);
-+
-+              /* From original code is reported port instability as SGMII also
-+               * require delay set. Apply advised values here or take them from DT.
-+               */
-+              if (state->interface == PHY_INTERFACE_MODE_SGMII)
-+                      qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);
-+
-               break;
-       default:
-               dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -39,7 +39,9 @@
- #define QCA8K_REG_PORT5_PAD_CTRL                      0x008
- #define QCA8K_REG_PORT6_PAD_CTRL                      0x00c
- #define   QCA8K_PORT_PAD_RGMII_EN                     BIT(26)
-+#define   QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK          GENMASK(23, 22)
- #define   QCA8K_PORT_PAD_RGMII_TX_DELAY(x)            ((x) << 22)
-+#define   QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK          GENMASK(21, 20)
- #define   QCA8K_PORT_PAD_RGMII_RX_DELAY(x)            ((x) << 20)
- #define         QCA8K_PORT_PAD_RGMII_TX_DELAY_EN              BIT(25)
- #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN            BIT(24)
diff --git a/target/linux/generic/backport-5.10/797-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch b/target/linux/generic/backport-5.10/797-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch
deleted file mode 100644 (file)
index b991798..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-From fd0bb28c547f7c8affb1691128cece38f5b626a1 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:19 +0200
-Subject: net: dsa: qca8k: move port config to dedicated struct
-
-Move ports related config to dedicated struct to keep things organized.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 26 +++++++++++++-------------
- drivers/net/dsa/qca8k.h | 10 +++++++---
- 2 files changed, 20 insertions(+), 16 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1019,7 +1019,7 @@ qca8k_parse_port_config(struct qca8k_pri
-                               delay = 3;
-                       }
--                      priv->rgmii_tx_delay[cpu_port_index] = delay;
-+                      priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay;
-                       delay = 0;
-@@ -1035,7 +1035,7 @@ qca8k_parse_port_config(struct qca8k_pri
-                               delay = 3;
-                       }
--                      priv->rgmii_rx_delay[cpu_port_index] = delay;
-+                      priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay;
-                       /* Skip sgmii parsing for rgmii* mode */
-                       if (mode == PHY_INTERFACE_MODE_RGMII ||
-@@ -1045,17 +1045,17 @@ qca8k_parse_port_config(struct qca8k_pri
-                               break;
-                       if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
--                              priv->sgmii_tx_clk_falling_edge = true;
-+                              priv->ports_config.sgmii_tx_clk_falling_edge = true;
-                       if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
--                              priv->sgmii_rx_clk_falling_edge = true;
-+                              priv->ports_config.sgmii_rx_clk_falling_edge = true;
-                       if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) {
--                              priv->sgmii_enable_pll = true;
-+                              priv->ports_config.sgmii_enable_pll = true;
-                               if (priv->switch_id == QCA8K_ID_QCA8327) {
-                                       dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling");
--                                      priv->sgmii_enable_pll = false;
-+                                      priv->ports_config.sgmii_enable_pll = false;
-                               }
-                               if (priv->switch_revision < 2)
-@@ -1281,15 +1281,15 @@ qca8k_mac_config_setup_internal_delay(st
-        * not enabled. With ID or TX/RXID delay is enabled and set
-        * to the default and recommended value.
-        */
--      if (priv->rgmii_tx_delay[cpu_port_index]) {
--              delay = priv->rgmii_tx_delay[cpu_port_index];
-+      if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) {
-+              delay = priv->ports_config.rgmii_tx_delay[cpu_port_index];
-               val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) |
-                       QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;
-       }
--      if (priv->rgmii_rx_delay[cpu_port_index]) {
--              delay = priv->rgmii_rx_delay[cpu_port_index];
-+      if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) {
-+              delay = priv->ports_config.rgmii_rx_delay[cpu_port_index];
-               val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) |
-                       QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
-@@ -1397,7 +1397,7 @@ qca8k_phylink_mac_config(struct dsa_swit
-               val |= QCA8K_SGMII_EN_SD;
--              if (priv->sgmii_enable_pll)
-+              if (priv->ports_config.sgmii_enable_pll)
-                       val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
-                              QCA8K_SGMII_EN_TX;
-@@ -1425,10 +1425,10 @@ qca8k_phylink_mac_config(struct dsa_swit
-               val = 0;
-               /* SGMII Clock phase configuration */
--              if (priv->sgmii_rx_clk_falling_edge)
-+              if (priv->ports_config.sgmii_rx_clk_falling_edge)
-                       val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;
--              if (priv->sgmii_tx_clk_falling_edge)
-+              if (priv->ports_config.sgmii_tx_clk_falling_edge)
-                       val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;
-               if (val)
---- a/drivers/net/dsa/qca8k.h
-+++ b/drivers/net/dsa/qca8k.h
-@@ -270,15 +270,19 @@ enum {
-       QCA8K_CPU_PORT6,
- };
--struct qca8k_priv {
--      u8 switch_id;
--      u8 switch_revision;
-+struct qca8k_ports_config {
-       bool sgmii_rx_clk_falling_edge;
-       bool sgmii_tx_clk_falling_edge;
-       bool sgmii_enable_pll;
-       u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-       u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */
-+};
-+
-+struct qca8k_priv {
-+      u8 switch_id;
-+      u8 switch_revision;
-       bool legacy_phy_port_mapping;
-+      struct qca8k_ports_config ports_config;
-       struct regmap *regmap;
-       struct mii_bus *bus;
-       struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS];
diff --git a/target/linux/generic/backport-5.10/797-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch b/target/linux/generic/backport-5.10/797-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch
deleted file mode 100644 (file)
index f7cb514..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-From e52073a8e3086046a098b8a7cbeb282ff0cdb424 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:20 +0200
-Subject: dt-bindings: net: ipq8064-mdio: fix warning with new qca8k switch
-
-Fix warning now that we have qca8k switch Documentation using yaml.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
-+++ b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
-@@ -51,6 +51,9 @@ examples:
-         switch@10 {
-             compatible = "qca,qca8337";
-             reg = <0x10>;
--            /* ... */
-+
-+            ports {
-+              /* ... */
-+            };
-         };
-     };
diff --git a/target/linux/generic/backport-5.10/797-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch b/target/linux/generic/backport-5.10/797-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch
deleted file mode 100644 (file)
index b9bce97..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-From d291fbb8245d5ba04979fed85575860a5cea7196 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Thu, 14 Oct 2021 00:39:21 +0200
-Subject: dt-bindings: net: dsa: qca8k: convert to YAML schema
-
-Convert the qca8k bindings to YAML format.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Co-developed-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- .../devicetree/bindings/net/dsa/qca8k.txt          | 245 --------------
- .../devicetree/bindings/net/dsa/qca8k.yaml         | 362 +++++++++++++++++++++
- 2 files changed, 362 insertions(+), 245 deletions(-)
- delete mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.txt
- create mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.yaml
-
---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
-+++ /dev/null
-@@ -1,245 +0,0 @@
--* Qualcomm Atheros QCA8xxx switch family
--
--Required properties:
--
--- compatible: should be one of:
--    "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
--    "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package
--    "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package
--    "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
--
--- #size-cells: must be 0
--- #address-cells: must be 1
--
--Optional properties:
--
--- reset-gpios: GPIO to be used to reset the whole device
--- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open
--                           drain or eeprom presence. This is needed for broken
--                           devices that have wrong configuration or when the oem
--                           decided to not use pin strapping and fallback to sw
--                           regs.
--- qca,led-open-drain: Set leds to open-drain mode. This requires the
--                      qca,ignore-power-on-sel to be set or the driver will fail
--                      to probe. This is needed if the oem doesn't use pin
--                      strapping to set this mode and prefers to set it using sw
--                      regs. The pin strapping related to led open drain mode is
--                      the pin B68 for QCA832x and B49 for QCA833x
--
--Subnodes:
--
--The integrated switch subnode should be specified according to the binding
--described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external
--mdio-bus each subnode describing a port needs to have a valid phandle
--referencing the internal PHY it is connected to. This is because there's no
--N:N mapping of port and PHY id.
--To declare the internal mdio-bus configuration, declare a mdio node in the
--switch node and declare the phandle for the port referencing the internal
--PHY is connected to. In this config a internal mdio-bus is registered and
--the mdio MASTER is used as communication.
--
--Don't use mixed external and internal mdio-bus configurations, as this is
--not supported by the hardware.
--
--This switch support 2 CPU port. Normally and advised configuration is with
--CPU port set to port 0. It is also possible to set the CPU port to port 6
--if the device requires it. The driver will configure the switch to the defined
--port. With both CPU port declared the first CPU port is selected as primary
--and the secondary CPU ignored.
--
--A CPU port node has the following optional node:
--
--- fixed-link            : Fixed-link subnode describing a link to a non-MDIO
--                          managed entity. See
--                          Documentation/devicetree/bindings/net/fixed-link.txt
--                          for details.
--- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.
--                                Mostly used in qca8327 with CPU port 0 set to
--                                sgmii.
--- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.
--- qca,sgmii-enable-pll  : For SGMII CPU port, explicitly enable PLL, TX and RX
--                          chain along with Signal Detection.
--                          This should NOT be enabled for qca8327. If enabled with
--                          qca8327 the sgmii port won't correctly init and an err
--                          is printed.
--                          This can be required for qca8337 switch with revision 2.
--                          A warning is displayed when used with revision greater
--                          2.
--                          With CPU port set to sgmii and qca8337 it is advised
--                          to set this unless a communication problem is observed.
--
--For QCA8K the 'fixed-link' sub-node supports only the following properties:
--
--- 'speed' (integer, mandatory), to indicate the link speed. Accepted
--  values are 10, 100 and 1000
--- 'full-duplex' (boolean, optional), to indicate that full duplex is
--  used. When absent, half duplex is assumed.
--
--Examples:
--
--for the external mdio-bus configuration:
--
--      &mdio0 {
--              phy_port1: phy@0 {
--                      reg = <0>;
--              };
--
--              phy_port2: phy@1 {
--                      reg = <1>;
--              };
--
--              phy_port3: phy@2 {
--                      reg = <2>;
--              };
--
--              phy_port4: phy@3 {
--                      reg = <3>;
--              };
--
--              phy_port5: phy@4 {
--                      reg = <4>;
--              };
--
--              switch@10 {
--                      compatible = "qca,qca8337";
--                      #address-cells = <1>;
--                      #size-cells = <0>;
--
--                      reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
--                      reg = <0x10>;
--
--                      ports {
--                              #address-cells = <1>;
--                              #size-cells = <0>;
--                              port@0 {
--                                      reg = <0>;
--                                      label = "cpu";
--                                      ethernet = <&gmac1>;
--                                      phy-mode = "rgmii";
--                                      fixed-link {
--                                              speed = 1000;
--                                              full-duplex;
--                                      };
--                              };
--
--                              port@1 {
--                                      reg = <1>;
--                                      label = "lan1";
--                                      phy-handle = <&phy_port1>;
--                              };
--
--                              port@2 {
--                                      reg = <2>;
--                                      label = "lan2";
--                                      phy-handle = <&phy_port2>;
--                              };
--
--                              port@3 {
--                                      reg = <3>;
--                                      label = "lan3";
--                                      phy-handle = <&phy_port3>;
--                              };
--
--                              port@4 {
--                                      reg = <4>;
--                                      label = "lan4";
--                                      phy-handle = <&phy_port4>;
--                              };
--
--                              port@5 {
--                                      reg = <5>;
--                                      label = "wan";
--                                      phy-handle = <&phy_port5>;
--                              };
--                      };
--              };
--      };
--
--for the internal master mdio-bus configuration:
--
--      &mdio0 {
--              switch@10 {
--                      compatible = "qca,qca8337";
--                      #address-cells = <1>;
--                      #size-cells = <0>;
--
--                      reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
--                      reg = <0x10>;
--
--                      ports {
--                              #address-cells = <1>;
--                              #size-cells = <0>;
--
--                              port@0 {
--                                      reg = <0>;
--                                      label = "cpu";
--                                      ethernet = <&gmac1>;
--                                      phy-mode = "rgmii";
--                                      fixed-link {
--                                              speed = 1000;
--                                              full-duplex;
--                                      };
--                              };
--
--                              port@1 {
--                                      reg = <1>;
--                                      label = "lan1";
--                                      phy-mode = "internal";
--                                      phy-handle = <&phy_port1>;
--                              };
--
--                              port@2 {
--                                      reg = <2>;
--                                      label = "lan2";
--                                      phy-mode = "internal";
--                                      phy-handle = <&phy_port2>;
--                              };
--
--                              port@3 {
--                                      reg = <3>;
--                                      label = "lan3";
--                                      phy-mode = "internal";
--                                      phy-handle = <&phy_port3>;
--                              };
--
--                              port@4 {
--                                      reg = <4>;
--                                      label = "lan4";
--                                      phy-mode = "internal";
--                                      phy-handle = <&phy_port4>;
--                              };
--
--                              port@5 {
--                                      reg = <5>;
--                                      label = "wan";
--                                      phy-mode = "internal";
--                                      phy-handle = <&phy_port5>;
--                              };
--                      };
--
--                      mdio {
--                              #address-cells = <1>;
--                              #size-cells = <0>;
--
--                              phy_port1: phy@0 {
--                                      reg = <0>;
--                              };
--
--                              phy_port2: phy@1 {
--                                      reg = <1>;
--                              };
--
--                              phy_port3: phy@2 {
--                                      reg = <2>;
--                              };
--
--                              phy_port4: phy@3 {
--                                      reg = <3>;
--                              };
--
--                              phy_port5: phy@4 {
--                                      reg = <4>;
--                              };
--                      };
--              };
--      };
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml
-@@ -0,0 +1,362 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/dsa/qca8k.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Qualcomm Atheros QCA83xx switch family
-+
-+maintainers:
-+  - John Crispin <john@phrozen.org>
-+
-+description:
-+  If the QCA8K switch is connect to an SoC's external mdio-bus, each subnode
-+  describing a port needs to have a valid phandle referencing the internal PHY
-+  it is connected to. This is because there is no N:N mapping of port and PHY
-+  ID. To declare the internal mdio-bus configuration, declare an MDIO node in
-+  the switch node and declare the phandle for the port, referencing the internal
-+  PHY it is connected to. In this config, an internal mdio-bus is registered and
-+  the MDIO master is used for communication. Mixed external and internal
-+  mdio-bus configurations are not supported by the hardware.
-+
-+properties:
-+  compatible:
-+    oneOf:
-+      - enum:
-+          - qca,qca8327
-+          - qca,qca8328
-+          - qca,qca8334
-+          - qca,qca8337
-+    description: |
-+      qca,qca8328: referenced as AR8328(N)-AK1(A/B) QFN 176 pin package
-+      qca,qca8327: referenced as AR8327(N)-AL1A DR-QFN 148 pin package
-+      qca,qca8334: referenced as QCA8334-AL3C QFN 88 pin package
-+      qca,qca8337: referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package
-+
-+  reg:
-+    maxItems: 1
-+
-+  reset-gpios:
-+    description:
-+      GPIO to be used to reset the whole device
-+    maxItems: 1
-+
-+  qca,ignore-power-on-sel:
-+    $ref: /schemas/types.yaml#/definitions/flag
-+    description:
-+      Ignore power-on pin strapping to configure LED open-drain or EEPROM
-+      presence. This is needed for devices with incorrect configuration or when
-+      the OEM has decided not to use pin strapping and falls back to SW regs.
-+
-+  qca,led-open-drain:
-+    $ref: /schemas/types.yaml#/definitions/flag
-+    description:
-+      Set LEDs to open-drain mode. This requires the qca,ignore-power-on-sel to
-+      be set, otherwise the driver will fail at probe. This is required if the
-+      OEM does not use pin strapping to set this mode and prefers to set it
-+      using SW regs. The pin strappings related to LED open-drain mode are
-+      B68 on the QCA832x and B49 on the QCA833x.
-+
-+  mdio:
-+    type: object
-+    description: Qca8k switch have an internal mdio to access switch port.
-+                 If this is not present, the legacy mapping is used and the
-+                 internal mdio access is used.
-+                 With the legacy mapping the reg corresponding to the internal
-+                 mdio is the switch reg with an offset of -1.
-+
-+    properties:
-+      '#address-cells':
-+        const: 1
-+      '#size-cells':
-+        const: 0
-+
-+    patternProperties:
-+      "^(ethernet-)?phy@[0-4]$":
-+        type: object
-+
-+        allOf:
-+          - $ref: "http://devicetree.org/schemas/net/mdio.yaml#"
-+
-+        properties:
-+          reg:
-+            maxItems: 1
-+
-+        required:
-+          - reg
-+
-+patternProperties:
-+  "^(ethernet-)?ports$":
-+    type: object
-+    properties:
-+      '#address-cells':
-+        const: 1
-+      '#size-cells':
-+        const: 0
-+
-+    patternProperties:
-+      "^(ethernet-)?port@[0-6]$":
-+        type: object
-+        description: Ethernet switch ports
-+
-+        properties:
-+          reg:
-+            description: Port number
-+
-+          label:
-+            description:
-+              Describes the label associated with this port, which will become
-+              the netdev name
-+            $ref: /schemas/types.yaml#/definitions/string
-+
-+          link:
-+            description:
-+              Should be a list of phandles to other switch's DSA port. This
-+              port is used as the outgoing port towards the phandle ports. The
-+              full routing information must be given, not just the one hop
-+              routes to neighbouring switches
-+            $ref: /schemas/types.yaml#/definitions/phandle-array
-+
-+          ethernet:
-+            description:
-+              Should be a phandle to a valid Ethernet device node.  This host
-+              device is what the switch port is connected to
-+            $ref: /schemas/types.yaml#/definitions/phandle
-+
-+          phy-handle: true
-+
-+          phy-mode: true
-+
-+          fixed-link: true
-+
-+          mac-address: true
-+
-+          sfp: true
-+
-+          qca,sgmii-rxclk-falling-edge:
-+            $ref: /schemas/types.yaml#/definitions/flag
-+            description:
-+              Set the receive clock phase to falling edge. Mostly commonly used on
-+              the QCA8327 with CPU port 0 set to SGMII.
-+
-+          qca,sgmii-txclk-falling-edge:
-+            $ref: /schemas/types.yaml#/definitions/flag
-+            description:
-+              Set the transmit clock phase to falling edge.
-+
-+          qca,sgmii-enable-pll:
-+            $ref: /schemas/types.yaml#/definitions/flag
-+            description:
-+              For SGMII CPU port, explicitly enable PLL, TX and RX chain along with
-+              Signal Detection. On the QCA8327 this should not be enabled, otherwise
-+              the SGMII port will not initialize. When used on the QCA8337, revision 3
-+              or greater, a warning will be displayed. When the CPU port is set to
-+              SGMII on the QCA8337, it is advised to set this unless a communication
-+              issue is observed.
-+
-+        required:
-+          - reg
-+
-+        additionalProperties: false
-+
-+oneOf:
-+  - required:
-+      - ports
-+  - required:
-+      - ethernet-ports
-+
-+required:
-+  - compatible
-+  - reg
-+
-+additionalProperties: true
-+
-+examples:
-+  - |
-+    #include <dt-bindings/gpio/gpio.h>
-+
-+    mdio {
-+        #address-cells = <1>;
-+        #size-cells = <0>;
-+
-+        external_phy_port1: ethernet-phy@0 {
-+            reg = <0>;
-+        };
-+
-+        external_phy_port2: ethernet-phy@1 {
-+            reg = <1>;
-+        };
-+
-+        external_phy_port3: ethernet-phy@2 {
-+            reg = <2>;
-+        };
-+
-+        external_phy_port4: ethernet-phy@3 {
-+            reg = <3>;
-+        };
-+
-+        external_phy_port5: ethernet-phy@4 {
-+            reg = <4>;
-+        };
-+
-+        switch@10 {
-+            compatible = "qca,qca8337";
-+            #address-cells = <1>;
-+            #size-cells = <0>;
-+            reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
-+            reg = <0x10>;
-+
-+            ports {
-+                #address-cells = <1>;
-+                #size-cells = <0>;
-+
-+                port@0 {
-+                    reg = <0>;
-+                    label = "cpu";
-+                    ethernet = <&gmac1>;
-+                    phy-mode = "rgmii";
-+
-+                    fixed-link {
-+                        speed = <1000>;
-+                        full-duplex;
-+                    };
-+                };
-+
-+                port@1 {
-+                    reg = <1>;
-+                    label = "lan1";
-+                    phy-handle = <&external_phy_port1>;
-+                };
-+
-+                port@2 {
-+                    reg = <2>;
-+                    label = "lan2";
-+                    phy-handle = <&external_phy_port2>;
-+                };
-+
-+                port@3 {
-+                    reg = <3>;
-+                    label = "lan3";
-+                    phy-handle = <&external_phy_port3>;
-+                };
-+
-+                port@4 {
-+                    reg = <4>;
-+                    label = "lan4";
-+                    phy-handle = <&external_phy_port4>;
-+                };
-+
-+                port@5 {
-+                    reg = <5>;
-+                    label = "wan";
-+                    phy-handle = <&external_phy_port5>;
-+                };
-+            };
-+        };
-+    };
-+  - |
-+    #include <dt-bindings/gpio/gpio.h>
-+
-+    mdio {
-+        #address-cells = <1>;
-+        #size-cells = <0>;
-+
-+        switch@10 {
-+            compatible = "qca,qca8337";
-+            #address-cells = <1>;
-+            #size-cells = <0>;
-+            reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
-+            reg = <0x10>;
-+
-+            ports {
-+                #address-cells = <1>;
-+                #size-cells = <0>;
-+
-+                port@0 {
-+                    reg = <0>;
-+                    label = "cpu";
-+                    ethernet = <&gmac1>;
-+                    phy-mode = "rgmii";
-+
-+                    fixed-link {
-+                        speed = <1000>;
-+                        full-duplex;
-+                    };
-+                };
-+
-+                port@1 {
-+                    reg = <1>;
-+                    label = "lan1";
-+                    phy-mode = "internal";
-+                    phy-handle = <&internal_phy_port1>;
-+                };
-+
-+                port@2 {
-+                    reg = <2>;
-+                    label = "lan2";
-+                    phy-mode = "internal";
-+                    phy-handle = <&internal_phy_port2>;
-+                };
-+
-+                port@3 {
-+                    reg = <3>;
-+                    label = "lan3";
-+                    phy-mode = "internal";
-+                    phy-handle = <&internal_phy_port3>;
-+                };
-+
-+                port@4 {
-+                    reg = <4>;
-+                    label = "lan4";
-+                    phy-mode = "internal";
-+                    phy-handle = <&internal_phy_port4>;
-+                };
-+
-+                port@5 {
-+                    reg = <5>;
-+                    label = "wan";
-+                    phy-mode = "internal";
-+                    phy-handle = <&internal_phy_port5>;
-+                };
-+
-+                port@6 {
-+                    reg = <0>;
-+                    label = "cpu";
-+                    ethernet = <&gmac1>;
-+                    phy-mode = "sgmii";
-+
-+                    qca,sgmii-rxclk-falling-edge;
-+
-+                    fixed-link {
-+                        speed = <1000>;
-+                        full-duplex;
-+                    };
-+                };
-+            };
-+
-+            mdio {
-+                #address-cells = <1>;
-+                #size-cells = <0>;
-+
-+                internal_phy_port1: ethernet-phy@0 {
-+                    reg = <0>;
-+                };
-+
-+                internal_phy_port2: ethernet-phy@1 {
-+                    reg = <1>;
-+                };
-+
-+                internal_phy_port3: ethernet-phy@2 {
-+                    reg = <2>;
-+                };
-+
-+                internal_phy_port4: ethernet-phy@3 {
-+                    reg = <3>;
-+                };
-+
-+                internal_phy_port5: ethernet-phy@4 {
-+                    reg = <4>;
-+                };
-+            };
-+        };
-+    };
diff --git a/target/linux/generic/backport-5.10/798-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch b/target/linux/generic/backport-5.10/798-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch
deleted file mode 100644 (file)
index a510cfd..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From 06dd34a628ae5b6a839b757e746de165d6789ca8 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 17 Oct 2021 16:56:46 +0200
-Subject: net: dsa: qca8k: fix delay applied to wrong cpu in parse_port_config
-
-Fix delay settings applied to wrong cpu in parse_port_config. The delay
-values is set to the wrong index as the cpu_port_index is incremented
-too early. Start the cpu_port_index to -1 so the correct value is
-applied to address also the case with invalid phy mode and not available
-port.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -976,7 +976,7 @@ qca8k_setup_of_pws_reg(struct qca8k_priv
- static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
--      int port, cpu_port_index = 0, ret;
-+      int port, cpu_port_index = -1, ret;
-       struct device_node *port_dn;
-       phy_interface_t mode;
-       struct dsa_port *dp;
diff --git a/target/linux/generic/backport-5.10/799-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch b/target/linux/generic/backport-5.10/799-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch
deleted file mode 100644 (file)
index 71fa302..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-From 040e926f5813a5f4cc18dbff7c942d1e52f368f2 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Tue, 19 Oct 2021 02:08:50 +0200
-Subject: net: dsa: qca8k: tidy for loop in setup and add cpu port check
-
-Tidy and organize qca8k setup function from multiple for loop.
-Change for loop in bridge leave/join to scan all port and skip cpu port.
-No functional change intended.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/qca8k.c | 74 +++++++++++++++++++++++++++++--------------------
- 1 file changed, 44 insertions(+), 30 deletions(-)
-
---- a/drivers/net/dsa/qca8k.c
-+++ b/drivers/net/dsa/qca8k.c
-@@ -1122,28 +1122,34 @@ qca8k_setup(struct dsa_switch *ds)
-       if (ret)
-               dev_warn(priv->dev, "mib init failed");
--      /* Enable QCA header mode on the cpu port */
--      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
--                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
--                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
--      if (ret) {
--              dev_err(priv->dev, "failed enabling QCA header mode");
--              return ret;
--      }
--
--      /* Disable forwarding by default on all ports */
-+      /* Initial setup of all ports */
-       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+              /* Disable forwarding by default on all ports */
-               ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-                               QCA8K_PORT_LOOKUP_MEMBER, 0);
-               if (ret)
-                       return ret;
--      }
--      /* Disable MAC by default on all ports */
--      for (i = 1; i < QCA8K_NUM_PORTS; i++)
--              qca8k_port_set_status(priv, i, 0);
-+              /* Enable QCA header mode on all cpu ports */
-+              if (dsa_is_cpu_port(ds, i)) {
-+                      ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i),
-+                                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
-+                                        QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
-+                      if (ret) {
-+                              dev_err(priv->dev, "failed enabling QCA header mode");
-+                              return ret;
-+                      }
-+              }
-+
-+              /* Disable MAC by default on all user ports */
-+              if (dsa_is_user_port(ds, i))
-+                      qca8k_port_set_status(priv, i, 0);
-+      }
--      /* Forward all unknown frames to CPU port for Linux processing */
-+      /* Forward all unknown frames to CPU port for Linux processing
-+       * Notice that in multi-cpu config only one port should be set
-+       * for igmp, unknown, multicast and broadcast packet
-+       */
-       ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
-                         BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
-                         BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
-@@ -1152,11 +1158,13 @@ qca8k_setup(struct dsa_switch *ds)
-       if (ret)
-               return ret;
--      /* Setup connection between CPU port & user ports */
-+      /* Setup connection between CPU port & user ports
-+       * Configure specific switch configuration for ports
-+       */
-       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-               /* CPU port gets connected to all user ports of the switch */
-               if (dsa_is_cpu_port(ds, i)) {
--                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
-+                      ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
-                                       QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
-                       if (ret)
-                               return ret;
-@@ -1193,16 +1201,14 @@ qca8k_setup(struct dsa_switch *ds)
-                       if (ret)
-                               return ret;
-               }
--      }
--      /* The port 5 of the qca8337 have some problem in flood condition. The
--       * original legacy driver had some specific buffer and priority settings
--       * for the different port suggested by the QCA switch team. Add this
--       * missing settings to improve switch stability under load condition.
--       * This problem is limited to qca8337 and other qca8k switch are not affected.
--       */
--      if (priv->switch_id == QCA8K_ID_QCA8337) {
--              for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+              /* The port 5 of the qca8337 have some problem in flood condition. The
-+               * original legacy driver had some specific buffer and priority settings
-+               * for the different port suggested by the QCA switch team. Add this
-+               * missing settings to improve switch stability under load condition.
-+               * This problem is limited to qca8337 and other qca8k switch are not affected.
-+               */
-+              if (priv->switch_id == QCA8K_ID_QCA8337) {
-                       switch (i) {
-                       /* The 2 CPU port and port 5 requires some different
-                        * priority than any other ports.
-@@ -1238,6 +1244,12 @@ qca8k_setup(struct dsa_switch *ds)
-                                 QCA8K_PORT_HOL_CTRL1_WRED_EN,
-                                 mask);
-               }
-+
-+              /* Set initial MTU for every port.
-+               * We have only have a general MTU setting. So track
-+               * every port and set the max across all port.
-+               */
-+              priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
-       }
-       /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */
-@@ -1251,8 +1263,6 @@ qca8k_setup(struct dsa_switch *ds)
-       }
-       /* Setup our port MTUs to match power on defaults */
--      for (i = 0; i < QCA8K_NUM_PORTS; i++)
--              priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
-       ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
-       if (ret)
-               dev_warn(priv->dev, "failed setting MTU settings");
-@@ -1728,7 +1738,9 @@ qca8k_port_bridge_join(struct dsa_switch
-       cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-       port_mask = BIT(cpu_port);
--      for (i = 1; i < QCA8K_NUM_PORTS; i++) {
-+      for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+              if (dsa_is_cpu_port(ds, i))
-+                      continue;
-               if (dsa_to_port(ds, i)->bridge_dev != br)
-                       continue;
-               /* Add this port to the portvlan mask of the other ports
-@@ -1758,7 +1770,9 @@ qca8k_port_bridge_leave(struct dsa_switc
-       cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
--      for (i = 1; i < QCA8K_NUM_PORTS; i++) {
-+      for (i = 0; i < QCA8K_NUM_PORTS; i++) {
-+              if (dsa_is_cpu_port(ds, i))
-+                      continue;
-               if (dsa_to_port(ds, i)->bridge_dev != br)
-                       continue;
-               /* Remove this port to the portvlan mask of the other ports